2009-04-19 21 views
38

Estoy tratando de hacer que todos los píxeles blancos sean transparentes utilizando la biblioteca de imágenes de Python. (Soy un hacker de C tratando de aprender Python, así que sea gentil) Tengo la conversión funcionando (al menos los valores de píxel parecen correctos) pero no entiendo cómo convertir la lista en un buffer para volver crea la imagen. Aquí está el código¿Usando PIL para hacer transparentes todos los píxeles blancos?

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

Respuesta

49

Necesitas realizar los siguientes cambios:

  • anexar una tupla (255, 255, 255, 0) y no una lista de [255, 255, 255, 0]
  • uso img.putdata(newData)

Este es el código de trabajo:

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

Sólo para potencialmente a salvo algún tiempo: Si está trabajando con python3 usted tiene que ir para Almohada (http: //python-pillow.org/) en lugar de PIL. – davedadizzel

36

También puede utilizar el modo de acceso de píxeles para modificar la imagen en el lugar:

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

no es tupla un tipo mutable? – DataGreed

+0

Como punto de referencia sobre la eficiencia, el ciclo anterior toma aproximadamente 0,05 segundos en una imagen de 256x256 en mi máquina promedio. Eso es más rápido de lo que esperaba. –

5
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]); 
Cuestiones relacionadas