2009-04-19 89 views
38

我想使所有的白色像素透明使用Python图像库。 (我是一个C黑客试图学习Python,所以要温柔) 我已经得到了转化工作(至少像素值看起来是正确的),但我无法弄清楚如何将列表转换成一个缓冲重新创建图像。下面的代码使用PIL使所有白色像素透明?

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

回答

49

你需要做以下修改:

  • 追加一个元组(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") 
+4

只是潜在的安全你一些时间:如果您正在使用Python3工作,你必须去枕(HTTP: //python-pillow.org/)而不是PIL。 – davedadizzel 2016-10-10 13:39:11

36

您还可以使用像素的接入方式来修改图像就地:

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

是不是一个可变类型的元组? – DataGreed 2009-12-02 13:56:17

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]);