2010-09-20 86 views
13

我已经采取了看看这个问题:SO question,似乎实现了一个非常类似的技术来取代单一的颜色,包括阿尔法值:的Python:PIL更换单个RGBA颜色

c = Image.open(f) 
c = c.convert("RGBA") 
w, h = c.size 
cnt = 0 
for px in c.getdata(): 
    c.putpixel((int(cnt % w), int(cnt/w)), (255, 0, 0, px[3]))                          cnt += 1 

然而,这非常缓慢。我在互联网上发现了这个配方,但到目前为止还没有成功使用它:recipe

我想要做的是采取由单一颜色,白色组成的各种PNG图像。每个像素都是100%白色,包含alpha = 0的各种alpha值。我想要做的是基本上用新的设置颜色着色图像,例如#ff0000 < 00-ff>。因此,我的起始图像和结果图像看起来像这样,左侧是我的起始图像,右侧是我的结束图像(注意:背景已更改为浅灰色,因此您可以看到它,因为它实际上是透明的, T为能看到左边的点。)

alt text

什么更好的办法来做到这一点?

回答

32

如果你有numpy,它提供了一个更快的方法来操作PIL图像。

如:

import Image 
import numpy as np 

im = Image.open('test.png') 
im = im.convert('RGBA') 

data = np.array(im) # "data" is a height x width x 4 numpy array 
red, green, blue, alpha = data.T # Temporarily unpack the bands for readability 

# Replace white with red... (leaves alpha values alone...) 
white_areas = (red == 255) & (blue == 255) & (green == 255) 
data[..., :-1][white_areas.T] = (255, 0, 0) # Transpose back needed 

im2 = Image.fromarray(data) 
im2.show() 

编辑:这是一个星期一慢,所以我想我会加入一两个例子:

只是为了表示它独自离开alpha值,这里的结果对于具有径向梯度的版本的示例图像的施加到α通道:

原件:alt text

结果:alt text

+1

真棒!真棒!真棒! +1并标记为“已接受”。巨大的时间节省和结果是完美的。 – sberry 2010-09-21 13:48:28

+0

@sberry - 很高兴帮助! – 2010-09-21 14:44:32

+0

应该不是,红绿蓝? white_areas = – Sekai 2014-12-18 19:29:39

2

Image module的Pythonware PIL在线书籍章节规定putpixel()速度较慢,并且暗示它可以通过内联加速。或者取决于PIL版本,使用load()来代替。

2

试试这个,在本示例中,如果颜色不是白色,我们将颜色设置为黑色。

#!/usr/bin/python 
from PIL import Image 
import sys 

img = Image.open(sys.argv[1]) 
img = img.convert("RGBA") 

pixdata = img.load() 

# Clean the background noise, if color != white, then set to black. 

for y in xrange(img.size[1]): 
    for x in xrange(img.size[0]): 
     if pixdata[x, y] == (255, 255, 255, 255): 
      pixdata[x, y] = (0, 0, 0, 255) 

您可以使用颜色选择器在GIMP吸收的颜色和看到的RGBA颜色