简体   繁体   English

使用 PIL 将 PNG32 转换为 PNG8,同时保持透明度

[英]Converting PNG32 to PNG8 with PIL while preserving transparency

I would like to convert a PNG32 image (with transparency) to PNG8 with Python Image Library.我想使用 Python 图像库将 PNG32 图像(具有透明度)转换为 PNG8。 So far I have succeeded converting to PNG8 with a solid background.到目前为止,我已成功转换为具有纯色背景的 PNG8。

Below is what I am doing:以下是我正在做的事情:

from PIL import Image
im = Image.open("logo_256.png")
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
im.save("logo_py.png", colors=255)

After much searching on the net, here is the code to accomplish what I asked for:在网上大量搜索后,这里是完成我要求的代码:

from PIL import Image

im = Image.open("logo_256.png")

# PIL complains if you don't load explicitly
im.load()

# Get the alpha band
alpha = im.split()[-1]

im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)

# Set all pixel values below 128 to 255,
# and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)

# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)

# The transparency index is 255
im.save("logo_py.png", transparency=255)

Source: http://nadiana.com/pil-tips-converting-png-gif Although the code there does not call im.load(), and thus crashes on my version of os/python/pil.来源: http://nadiana.com/pil-tips-converting-png-gif虽然那里的代码没有调用 im.load(),因此在我的 os/python/pil 版本上崩溃。 (It looks like that is the bug in PIL). (看起来这是 PIL 中的错误)。

Don't use PIL to generate the palette, as it can't handle RGBA properly and has quite limited quantization algorithm.不要使用 PIL 生成调色板,因为它无法正确处理 RGBA 并且量化算法非常有限。

Use pngquant instead.请改用pngquant

This is an old question so perhaps older answers are tuned to older version of PIL?这是一个老问题,所以也许老的答案是针对老版本的 PIL?

But for anyone coming to this with Pillow>=6.0.0 then the following answer is many magnitudes faster and simpler.但是对于任何使用Pillow>=6.0.0来解决这个问题的人,那么下面的答案会更快、更简单。

im = Image.open('png32_or_png64_with_alpha.png')
im = im.quantize()
im.save('png8_with_alpha_channel_preserved.png')

As mentioned by Mark Ransom, your paletized image will only have one transparency level.正如 Mark Ransom 所提到的,您的调色图像将只有一个透明度级别。

When saving your paletized image, you'll have to specify which color index you want to be the transparent color like this:保存调色板图像时,您必须指定要成为透明颜色的颜色索引,如下所示:

im.save("logo_py.png", transparency=0) 

to save the image as a paletized colors and using the first color as a transparent color.将图像保存为调色板 colors 并使用第一种颜色作为透明颜色。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM