仔细研究一下图像调色板,我会说透明度实际上分配给调色板中的黑色。
pngcheck http://www.libpng.org/pub/png/apps/pngcheck.html告诉我事实并非如此:
...
chunk PLTE at offset 0x00025, length 48: 16 palette entries
chunk tRNS at offset 0x00061, length 1: 1 transparency entry
Each actual颜色有一个索引PLTE
,包括黑色,并且还有一个附加条目被指定为“透明”。黑色环境可能是之前转换之一的产物,其中 alpha=0 被转换为 RGBA (0,0,0,0)。
看来 Pillow 立即转换为 Lab(“L”和“LA”)无法处理索引颜色转换。
您可以通过首先将图像转换为 RGBA,然后使用 Lab 转换公式将 RGBA 的每个像素四元组转换为灰度来解决此问题文档 http://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.convert,然后将其转换回调色板:
for i in range(img.size[0]): # for every pixel:
for j in range(img.size[1]):
g = (pixels[i,j][0]*299 + pixels[i,j][1]*587 + pixels[i,j][2]*114)//1000
pixels[i,j] = (g,g,g,pixels[i,j][3])
但后来我意识到,既然你从一张调色板图像开始,并想再次以一个调色板图像结束,仅转换调色板容易多了...
#/usr/bin/env python3
from PIL import Image, ImageFile
img = Image.open('bee.png')
palette = img.getpalette()
for i in range(len(palette)//3):
gray = (palette[3*i]*299 + palette[3*i+1]*587 + palette[3*i+2]*114)//1000
palette[3*i:3*i+3] = [gray,gray,gray]
img.putpalette(palette)
img.save('bee2a.png', optimize=True, format="PNG")
print ('done')
(硬编码假设您的输入图像确实是索引文件。如果您想确定,请添加检查。)
结果,包含在注释块内,以便您可以看到透明度: