Python:PIL 替换单个 RGBA 颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3752476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:33:32  来源:igfitidea点击:

Python: PIL replace a single RGBA color

pythoncolorspython-imaging-library

提问by sberry

I have already taken a look at this question: SO questionand seem to have implemented a very similar technique for replacing a single color including the alpha values:

我已经看过这个问题:SO question并且似乎已经实现了一种非常相似的技术来替换包括 alpha 值的单一颜色:

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                                                                                                   

However, this is very slow. I found this recipeout on the interwebs, but have not had success using it thus far.

然而,这是非常缓慢的。我在网上找到了这个食谱,但到目前为止还没有成功使用它。

What I am trying to do is take various PNG images that consist of a single color, white. Each pixel is 100% white with various alpha values, including alpha = 0. What I want to do is basically colorize the image with a new set color, for instance #ff0000<00-ff>. SO my starting and resulting images would look like this where the left side is my starting image and the right is my ending image (NOTE: background has been changed to a light gray so you can see it since it is actually transparent and you wouldn't be able to see the dots on the left.)

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

alt text

替代文字

Any better way to do this?

有没有更好的方法来做到这一点?

采纳答案by Joe Kington

If you have numpy, it provides a much, much faster way to operate on PIL images.

如果你有 numpy,它提供了一种对 PIL 图像进行操作的更快的方法。

E.g.:

例如:

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

Edit: It's a slow Monday, so I figured I'd add a couple of examples:

编辑:这是一个缓慢的星期一,所以我想我会添加几个例子:

Just to show that it's leaving the alpha values alone, here's the results for a version of your example image with a radial gradient applied to the alpha channel:

只是为了表明它不考虑 alpha 值,下面是示例图像版本的结果,其中径向渐变应用于 alpha 通道:

Original: alt text

原来的: 替代文字

Result: alt text

结果: 替代文字

回答by T.P.

The Pythonware PIL online book chapter for the Image modulestipulates that putpixel() is slow and suggests that it can be sped up by inlining. Or depending on PIL version, using load() instead.

图像模块的 Pythonware PIL 在线书籍章节规定 putpixel() 很慢,并建议它可以通过内联来加速。或者根据 PIL 版本,使用 load() 代替。

回答by Yuda Prawira

Try this , in this sample we set the color to black if color is not white .

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

#!/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)

you can use color picker in gimp to absorb the color and see that's rgba color

你可以在 gimp 中使用颜色选择器来吸收颜色并看到那是 rgba 颜色