Python PIL - 具有不透明度的 PNG 所有区域 > 0 将其不透明度设置为 1

发布于 2024-10-02 19:44:04 字数 464 浏览 2 评论 0原文

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

甚至在不更改图像的情况下也会出现问题:

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

我想让图像看起来与原始图像完全相同,以便我可以裁剪或调整其大小。

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

alt text

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

替代文字

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.

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

alt text

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

alt text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流年里的时光 2024-10-09 19:44:04

看起来 PIL 目前不支持 PNG8 的完整 Alpha。

这里有一个用于只读支持的补丁: 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')

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

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

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')
我也只是我 2024-10-09 19:44:04

我认为问题已经得到了一定程度的解决,但是是否有可能需要设置 alpha 通道的深度?

I think that the problem has been somewhat resolved, but is it possible that you need to set the depth of the alpha channel?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文