86 votes

Comment utiliser PIL pour rendre tous les pixels blancs transparents ?

J'essaie de rendre tous les pixels blancs transparents à l'aide de la bibliothèque d'images Python. (Je suis un hacker C essayant d'apprendre le python alors soyez doux) J'ai la conversion qui fonctionne (au moins les valeurs des pixels semblent correctes) mais je ne peux pas comprendre comment convertir la liste en tampon pour recréer l'image. Voici le code

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")

112voto

cr333 Points 343

Vous devez apporter les modifications suivantes :

  • ajouter un tuple (255, 255, 255, 0) et non une liste [255, 255, 255, 0]
  • utiliser img.putdata(newData)

Voici le code de travail :

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")

51voto

keithb Points 806

Vous pouvez également utiliser le mode d'accès aux pixels pour modifier l'image sur place :

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")

Vous pouvez probablement aussi envelopper ce qui précède dans un script si vous l'utilisez souvent.

8voto

Dardo Points 21
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]);

4voto

kdebugging Points 109

Une façon plus pythonique puisque le looping prend beaucoup de temps pour une grande image

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")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X