为什么 PIL convert('RGB') 将一些透明变成黑色,而一些变成白色?

sng*_*juk 3 python photoshop png image-processing python-imaging-library

我有两个具有透明背景的类似蒙版图像。我想获得图像差异并期望它的值与图像相似一样低。

lenna1.png lenna2.png

但是结果显示在看起来相同的透明区域上存在巨大差异。
(白色表示差异)

diff_res = ImageChops.difference(lenna1, lenna2).convert('RGB')
Run Code Online (Sandbox Code Playgroud)

diff_res

我在某个网站上检查了 lenna1 和 lenna2 图像差异,它说除了边界上的小差异外,图像完全相同。

然后我怀疑 alpha 通道值并将 lenna1、lenna2 转换为 'RGB'。它显示一个人的背景为黑色,而另一个人的背景为白色。

lenna1 = Image.open('lenna1.png')
lenna2 = Image.open('lenna2.png')

converted_lenna1 = lenna1.convert('RGB')
converted_lenna2 = lenna2.convert('RGB')
Run Code Online (Sandbox Code Playgroud)

Converted_lenna1   Converted_lenna2

现在我知道 convert() 默认将透明区域变为黑色。但我还是不明白。

  1. 为什么透明区域之间存在图像差异?
  2. 为什么一些透明图像变成白色,如何制作自己的“将是白色”透明图像?

*我还使用 .putalpha() 测试了相同的 alpha 级别

感谢您阅读这个问题。

Mar*_*ell 5

两个图像都有透明度,只是一个白色像素透明,另一个黑色像素透明。另一种说法是透明像素的底层颜色在一个图像中是黑色,在另一个图像中是白色。你看不出区别,因为它们是透明的!

这是lenna1在左侧移除了 alpha 层,然后在右侧移除了 alpha 层:

在此处输入图片说明

这是lenna2在左侧移除 alpha 层,然后在右侧移除 alpha 层:

在此处输入图片说明

你可以通过找到所有透明像素来使它们相同,并将它们变成白色,如下所示:

# Load the image and make into Numpy array
rgba = np.array(Image.open('lena2.png'))

# Make image transparent white anywhere it is transparent
rgba[rgba[...,-1]==0] = [255,255,255,0]

# Make back into PIL Image and save
Image.fromarray(rgba).save('result.png')
Run Code Online (Sandbox Code Playgroud)

如果您想让透明像素显示为蓝色,以便您可以看到它们进行测试,请使用:

rgba[rgba[...,-1]==0] = [0,0,255,255]
Run Code Online (Sandbox Code Playgroud)

如果你安装了ImageMagick,你可以在终端中强制所有透明像素变成你选择的颜色,比如洋红色:

magick lenna1.png -background magenta -alpha background result.png
Run Code Online (Sandbox Code Playgroud)

这通常意味着您可以通过将所有透明像素设为黑色来改进 PNG 压缩并减小 PNG 文件大小,因此,与透明像素都是完全不同的颜色相比,图像的压缩效果可能要好得多:

magick image.png -background black -alpha background result.png
Run Code Online (Sandbox Code Playgroud)