Python PIL - 所有透明度大于0的PNG区域都被设置为1
想象一下,有一个红色的圆圈,上面有一个黑色的阴影,这个阴影在完全透明的背景上逐渐消失。当我用PIL打开并重新保存这个图片时,背景依然是完全透明的,但阴影却变成了纯黑色。
这个问题出现的时候,我甚至没有对图片进行任何修改:
image = Image.open('input.png')
image = image.convert('RGBA')
image.save('output.png')
我希望图片看起来和原来一模一样,这样我才能裁剪或调整它的大小。
补充说明:这里有一个PNG图片,展示了这个效果。它是通过使用PNGNQ转换成8位的。
使用上面的Python代码处理后,结果变成了这样:
2 个回答
0
我觉得这个问题已经有点解决了,不过你有没有想过可能需要设置一下透明通道的深度呢?
6
看起来PIL目前不支持PNG8格式的完整透明度。
这里有一个补丁,可以实现只读支持:http://mail.python.org/pipermail/image-sig/2010-October/006533.html
如果你想尝试一些不太正规的做法,可以对PIL进行修改:
from PIL import Image, ImageFile, PngImagePlugin
def patched_chunk_tRNS(self, pos, len):
i16 = PngImagePlugin.i16
s = ImageFile._safe_read(self.fp, len)
if self.im_mode == "P":
self.im_info["transparency"] = map(ord, s)
elif self.im_mode == "L":
self.im_info["transparency"] = i16(s)
elif self.im_mode == "RGB":
self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:])
return s
PngImagePlugin.PngStream.chunk_tRNS = patched_chunk_tRNS
def patched_load(self):
if self.im and self.palette and self.palette.dirty:
apply(self.im.putpalette, self.palette.getdata())
self.palette.dirty = 0
self.palette.rawmode = None
try:
trans = self.info["transparency"]
except KeyError:
self.palette.mode = "RGB"
else:
try:
for i, a in enumerate(trans):
self.im.putpalettealpha(i, a)
except TypeError:
self.im.putpalettealpha(trans, 0)
self.palette.mode = "RGBA"
if self.im:
return self.im.pixel_access(self.readonly)
Image.Image.load = patched_load
Image.open('kHrY6.png').convert('RGBA').save('kHrY6-out.png')