J'essaie de rendre tous les pixels blancs transparents en utilisant la bibliothèque d'images Python. (Je suis un pirate C essayant d'apprendre python alors soyez doux)) I 'ai réussi la conversion (au moins les valeurs en pixels semblent correctes) mais je ne sais pas 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")
Vous devez apporter les modifications suivantes:
(255, 255, 255, 0)
et non une liste [255, 255, 255, 0]
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")
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 = image.size
for y in xrange(height):
for x in xrange(width):
if pixdata[x, y] == (255, 255, 255, 255):
pixdata[x, y] = (255, 255, 255, 0)
img.save("img2.png", "PNG")
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 __== '__main__':
import sys
makeColorTransparent(Image.open(sys.argv[1]), (255, 255, 255)).save(sys.argv[2]);
Étant donné qu'il s'agit actuellement du premier résultat Google en recherchant "Oreiller blanc à transparent", j'aimerais ajouter que la même chose peut être obtenue avec numpy, et dans mon benchmark (une seule image 8MP avec beaucoup de fond blanc) est d'environ 10 fois plus rapide (environ 300 ms vs 3,28 s pour la solution proposée). Le code est également un peu plus court:
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)
Il est également facilement échangeable vers une version où le "presque blanc" (par exemple un canal est 254 au lieu de 255) est "presque transparent". Bien sûr, cela rendra l'image entière partiellement transparente, à l'exception du noir pur:
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)
Remarque: la .copy()
est nécessaire car par défaut les images Pillow sont converties en tableaux en lecture seule.
Version Python 3 avec tous les fichiers dans un répertoire
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)