Python PIL-不透明的所有PNG区域> 0将其不透明度设置为1 [英] Python PIL - All areas of PNG with opacity > 0 have their opacity set to 1

查看:285
本文介绍了Python PIL-不透明的所有PNG区域> 0将其不透明度设置为1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一个带有黑色阴影的红色圆圈,该阴影在完全透明的背景上逐渐消失.当我用PIL打开并重新保存图像时,背景保持完全透明,但阴影变为全黑.

Imagine a red circle with a black dropshadow that fades away on top of a fully transparent background. When I open and resave the image with PIL the background remains fully transparent but the dropshadow becomes full black.

问题出现了,甚至没有改变图像:

The problem appears without even altering the image:

image = Image.open('input.png')
image = image.convert('RGBA')
image.save('output.png')

我想使图像看起来与原始图像完全一样,以便可以对其进行裁切或调整大小.

I want to keep the image looking exactly as the original so that I can crop or resize it.

这是一个演示效果的PNG.使用PNGNQ将其转换为8位.

Here's a PNG that demonstrates the effect. It was converted to 8bit by using PNGNQ.

使用上述Python代码时,结果如下:

When using the above Python code it comes out as the following:

推荐答案

PIL当前不支持PNG8的完整alpha.

It looks like PIL currently doesn't support full alpha for PNG8.

这里有一个只读支持补丁: http ://mail.python.org/pipermail/image-sig/2010-October/006533.html

There is a patch here for read-only support: http://mail.python.org/pipermail/image-sig/2010-October/006533.html

如果您感到顽皮,可以猴子修补PIL:

If you're feeling naughty, you could monkeypatch 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')

这篇关于Python PIL-不透明的所有PNG区域> 0将其不透明度设置为1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆