Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用PIL将PNG32转换为PNG8,同时保持透明度_Python_Png_Python Imaging Library - Fatal编程技术网

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

Python 使用PIL将PNG32转换为PNG8,同时保持透明度,python,png,python-imaging-library,Python,Png,Python Imaging Library,我想用Python图像库将PNG32图像(具有透明度)转换为PNG8。 到目前为止,我已经成功地转换到PNG8与坚实的背景 以下是我正在做的事情: 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) 正如MarkRansom所提

我想用Python图像库将PNG32图像(具有透明度)转换为PNG8。 到目前为止,我已经成功地转换到PNG8与坚实的背景

以下是我正在做的事情:

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)

正如MarkRansom所提到的,您的苍白图像将只有一个透明度级别

保存调色板化图像时,必须指定要作为透明颜色的颜色索引,如下所示:

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

要将图像保存为调色板颜色,并使用第一种颜色作为透明颜色。

在网上进行了大量搜索后,下面是实现我要求的代码:

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)
从PIL导入图像
im=Image.open(“logo_256.png”)
#如果没有显式加载,PIL会抱怨
im.load()
#得到阿尔法波段
alpha=im.split()[-1]
im=im.convert('RGB')。convert('P',调色板=Image.ADAPTIVE,颜色=255)
#将所有像素值设置为128到255以下,
#剩下的是0

mask=Image.eval(alpha,lambda a:255,如果a不使用PIL生成调色板,因为它不能正确处理RGBA,并且量化算法非常有限


改为使用。

这是一个老问题,所以可能旧答案被调整为旧版本的PIL

但是,对于任何一个使用
枕头>=6.0.0
的人来说,下面的答案要快得多,也要简单得多

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

PNG32有8位透明度,PNG8只有1位,所以不可能忠实地转换。你能接受吗?是的,因为它只是一个透明的背景。请将你的解决方案作为答案发布;这更适合网站的格式。如果你这样做,我很高兴给它一个升级投票。@MarkRansom PNG8每页有256个透明度级别alette entry,你自己试试看:或者。@porneL,你当然是对的,但是在实践中你会发现透明度级别的数量是有限的,因为颜色和透明度的每一个组合在调色板中都有一个条目。GIF有我提到的限制,而我多年前使用的软件对它们的处理方式都是一样的,所以有时甚至在今天我也会这样做感到困惑。我相信PIL也是这样工作的。Internet Explorer错误地显示PNG8的透明度级别也有问题,但我认为它已经被修复了一段时间。我刚刚尝试过这个,但在新创建的图像中没有出现透明颜色。我想我必须找到一种方法来找出什么是颜色,可以复制在这一步中使用透明背景:im.convert('RGB')@montonero:可能有一种以上的颜色被映射到透明颜色,因为您正在尽可能减少颜色的数量。@martineau我在网上找到的代码在应用convert()命令之前提取alpha,因此在我的情况下,一切都很完美(只有透明的背景,尽管我认为这也应该满足其他情况。)@montonero:哦,好吧,我明白——如果是这样的话,你最好接受你自己的答案(我认为这在这里是可以接受的)。几年后,最后回到这个问题,这是我承诺的投票结果。这是一个好的解决方案。