代码之家  ›  专栏  ›  技术社区  ›  haseman

使用PIL使所有白色像素透明?

  •  44
  • haseman  · 技术社区  · 17 年前

    我试图使用Python图像库使所有白色像素透明。(我是一名试图学习python的C黑客,所以请温柔一点)

    img = Image.open('img.png')
    imga = img.convert("RGBA")
    datas = imga.getdata()
    
    newData = list()
    for item in datas:
        if item[0] == 255 and item[1] == 255 and item[2] == 255:
            newData.append([255, 255, 255, 0])
        else:
            newData.append(item)
    
    imgb = Image.frombuffer("RGBA", imga.size, newData, "raw", "RGBA", 0, 1)
    imgb.save("img2.png", "PNG")
    
    5 回复  |  直到 6 年前
        1
  •  111
  •   Community Mohan Dere    13 年前

    您需要进行以下更改:

    • (255, 255, 255, 0) 而不是列表 [255, 255, 255, 0]
    • 使用 img.putdata(newData)

    这是工作代码:

    from PIL import Image
    
    img = Image.open('img.png')
    img = img.convert("RGBA")
    datas = img.getdata()
    
    newData = []
    for item in datas:
        if item[0] == 255 and item[1] == 255 and item[2] == 255:
            newData.append((255, 255, 255, 0))
        else:
            newData.append(item)
    
    img.putdata(newData)
    img.save("img2.png", "PNG")
    
        2
  •  48
  •   Cosmos Zhu keithb    6 年前

    您还可以使用像素访问模式就地修改图像:

    from PIL import Image
    
    img = Image.open('img.png')
    img = img.convert("RGBA")
    
    pixdata = img.load()
    
    width, height = img.size
    for y in range(height):
        for x in range(width):
            if pixdata[x, y] == (255, 255, 255, 255):
                pixdata[x, y] = (255, 255, 255, 0)
    
    img.save("img2.png", "PNG")
    

    如果你经常使用,你也可以把上面的内容包装成一个脚本。

        3
  •  8
  •   Dardo    13 年前

    import numpy as np
    
    def white_to_transparency(img):
        x = np.asarray(img.convert('RGBA')).copy()
    
        x[:, :, 3] = (255 * (x[:, :, :3] != 255).any(axis=2)).astype(np.uint8)
    
        return Image.fromarray(x)
    

    def white_to_transparency_gradient(img):
        x = np.asarray(img.convert('RGBA')).copy()
    
        x[:, :, 3] = (255 - x[:, :, :3].mean(axis=2)).astype(np.uint8)
    
        return Image.fromarray(x)
    

    备注: .copy()

        4
  •  5
  •   Marco Spinaci    7 年前
    import Image
    import ImageMath
    
    def distance2(a, b):
        return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) + (a[2] - b[2]) * (a[2] - b[2])
    
    def makeColorTransparent(image, color, thresh2=0):
        image = image.convert("RGBA")
        red, green, blue, alpha = image.split()
        image.putalpha(ImageMath.eval("""convert(((((t - d(c, (r, g, b))) >> 31) + 1) ^ 1) * a, 'L')""",
            t=thresh2, d=distance2, c=color, r=red, g=green, b=blue, a=alpha))
        return image
    
    if __name__ == '__main__':
        import sys
        makeColorTransparent(Image.open(sys.argv[1]), (255, 255, 255)).save(sys.argv[2]);
    
        5
  •  4
  •   kdebugging    6 年前

    一种更Python化的方式,因为循环一个大图像需要很长时间

    from PIL import Image
    
    img = Image.open('img.png')
    img = img.convert("RGBA")
    
    imgnp = np.array(img)
    
    white = np.sum(imgnp[:,:,:3], axis=2)
    white_mask = np.where(white == 255*3, 1, 0)
    
    alpha = np.where(white_mask, 0, imgnp[:,:,-1])
    
    imgnp[:,:,-1] = alpha 
    
    img = Image.fromarray(np.uint8(imgnp))
    img.save("img2.png", "PNG")
    
        6
  •  3
  •   PythonProgrammi    7 年前

    此函数结合了前面解决方案的所有优点:它允许任何背景并使用numpy(比经典列表更快)。

    import numpy as np
    from PIL import Image
    
    def convert_png_transparent(src_file, dst_file, bg_color=(255,255,255)):
        image = Image.open(src_file).convert("RGBA")
        array = np.array(image, dtype=np.ubyte)
        mask = (array[:,:,:3] == bg_color).all(axis=2)
        alpha = np.where(mask, 0, 255)
        array[:,:,-1] = alpha
        Image.fromarray(np.ubyte(array)).save(dst_file, "PNG")
    
        7
  •  1
  •   egeres    5 年前

    Python 3版本,所有文件都在一个目录中

    import glob
    from PIL import Image
    
    def transparent(myimage):
        img = Image.open(myimage)
        img = img.convert("RGBA")
    
        pixdata = img.load()
    
        width, height = img.size
        for y in range(height):
            for x in range(width):
                if pixdata[x, y] == (255, 255, 255, 255):
                    pixdata[x, y] = (255, 255, 255, 0)
    
        img.save(myimage, "PNG")
    
    for image in glob.glob("*.png"):
        transparent(image)
    
        8
  •  -3
  •   YFBY    5 年前

    https://stackoverflow.com/a/62334218/5189462

    from PIL import Image
    
    target_color = (255, 255, 255)
    
    img   = Image.open('img.png')
    imga  = img.convert("RGBA")
    datas = imga.getdata()
    
    newData = list()
    for item in datas:
        newData.append((
            item[0], item[1], item[2],
            max( 
                abs(item[0] - target_color[0]), 
                abs(item[1] - target_color[1]), 
                abs(item[2] - target_color[2]), 
            )  
        ))
    
    imgb = Image.frombuffer("RGBA", imga.size, newData, "raw", "RGBA", 0, 1)
    imgb.save("img2.png", "PNG")