Python 如何将部分alpha透明图像转换为PIL中的单一(不透明)颜色?

Python 如何将部分alpha透明图像转换为PIL中的单一(不透明)颜色?,python,python-imaging-library,image-manipulation,Python,Python Imaging Library,Image Manipulation,我有一个标志,我需要成为一个单色版本,例如全红。例如,将其转换为: 为此: 我在PIL(主要是Image.paste)中尝试了各种技术,但结果并不支持边缘周围的部分alpha透明像素。使用matplotlib使用遮罩搜索所有不完全透明的像素.imread将其作为RGBA加载,其中a是alpha通道,使遮罩变得简单。从那里,只需使用遮罩将像素更改为所需的颜色。在这种情况下,红色是[1,0,0,1] import matplotlib.pyplot as plt import matplotli

我有一个标志,我需要成为一个单色版本,例如全红。例如,将其转换为:

为此:


我在PIL(主要是Image.paste)中尝试了各种技术,但结果并不支持边缘周围的部分alpha透明像素。

使用matplotlib使用遮罩搜索所有不完全透明的像素
.imread
将其作为RGBA加载,其中a是alpha通道,使遮罩变得简单。从那里,只需使用遮罩将像素更改为所需的颜色。在这种情况下,红色是
[1,0,0,1]

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img = mpimg.imread('1EQ07.png')
opaque_idx = img[:,:,3]>0
img[opaque_idx] = [1,0,0,1]
plt.axis('off')
plt.imshow(img)
plt.show()

编辑:如果希望保持alpha通道不变,可以创建自定义过滤器并将其应用于匹配的像素

def custom_filter((r,g,b,a)): 
    return (1,0,0,a)

img[opaque_idx] = np.apply_along_axis(custom_filter,1,img[opaque_idx])

经过一番搜索,我发现逐像素改变图像数据可以得到结果,例如

from PIL import Image

image = Image.open('logo.png')
assert image.mode == 'RGBA', 'This will only work with RGBA images!'

width = image.size[0]
for index, (r, g, b, a) in enumerate(image.getdata()):
    if a > 0:
        y, x = divmod(index, width)
        image.putpixel((x, y), (255, 0, 0, a))

image.save('logo-red.png')

对于小示例图像,这非常快,但我不确定它如何处理较大的文件,因此欢迎使用任何替代方案

我不希望引入任何其他依赖项,也不希望使用本机PIL代码。此外,这张图像在世界各地都是非常像素化的edge@Euan它是像素化的,因为输入图像是像素化的,如果您想要平滑的抗锯齿版本,则始终可以在alpha剥离后应用过滤器。在原始大小下,图像看起来是平滑的(通过徽标边缘的半透明像素)。在您上面发布的版本中,半透明像素似乎丢失了(尽管这可能只是放大图像的一个假象)@Euan关于像素化版本你是对的,我误解了你最初的意图。我发布了一个更新版本来解决这个问题。使用PIL很好,但是过滤图像的想法可以应用于一般环境,所以我将保留这个答案。使用
加载
函数来加快速度。谢谢@mark ransom。这就是一个比迭代所有像素更好的解决方案我已经将代码集成到我正在处理的项目中,它似乎可以很好地处理image.load()省略-你能解释一下这是否会导致任何问题吗?@Euan当我测试它时,出现了一个错误:
文件“C:\Python27\lib\site packages\PIL\image.py”,第1497行,在split if self.im.bands==1:AttributeError:“非类型”对象没有属性“bands”
。我想这是因为PIL使用延迟加载,而
load
强制加载。这很有趣,@mark ransom。在Ubuntu 13.04和Debian Wheezy上,这在不调用
load()的情况下工作正常
!我想在windows上,底层的PNG库可能会有很大的不同。在Pillow中使用webp实现后,源代码非常可怕!
from PIL import Image

image = Image.open('logo.png')
assert im.mode.endswith('A'), 'This will only work with images having alpha!'

image.load()
alpha = image.split()[-1]
image2 = Image.new(image.mode, image.size, (255, 0, 0, 0))
image2.putalpha(alpha)

image2.save('logo-red.png')