Python: PIL替换单一RGBA颜色
我之前看过这个问题:SO问题,似乎已经实现了一种很相似的方法来替换单一颜色,包括透明度的值:
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
不过,这个方法速度很慢。我在网上找到过这个做法,但到现在为止还没有成功使用。
我想做的是处理一些只包含单一颜色(白色)的PNG图片。每个像素都是100%白色,透明度各不相同,包括透明度为0的情况。我想做的就是把这些图片换成一种新的颜色,比如#ff0000<00-ff>。所以我的起始图像和最终图像看起来是这样的,左边是我的起始图像,右边是我的最终图像(注意:背景已经换成浅灰色,这样你能看到,因为实际上它是透明的,左边的点你是看不见的)。
有没有更好的方法来做到这一点?
4 个回答
5
Pythonware的PIL在线书籍中关于图像模块的章节提到,putpixel()这个函数运行得比较慢。为了提高速度,建议可以通过内联的方式来加快它的运行速度。或者根据你使用的PIL版本,可以考虑使用load()函数来替代。
15
试试这个,在这个例子中,如果颜色不是白色,我们就把颜色设置为黑色。
#!/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颜色值。
91
如果你有使用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值)不变的,这里是你示例图像的一个版本,应用了径向渐变到透明度通道的结果:
原图:
结果图: