简体   繁体   English

如何将PNG图像转换为透明的GIF?

[英]How to convert PNG images to a transparent GIF?

I'm trying to convert a list of PNG images with a transparent background to a GIF, while keeping the background transparency.我正在尝试将具有透明背景的 PNG 图像列表转换为 GIF,同时保持背景透明度。 I took this bit of code I found, and adapted it:我采用了我找到的这段代码,并对其进行了修改:

import os
from PIL import Image

# Create the frames
frames = []

path = "directory/to/my/png/images"
for frame in os.listdir(path):
    new_frame = Image.open(path + "/" + frame)
    frames.append(new_frame)

# Save into a GIF file
frames[0].save(path + "/../output/animation.gif", format='GIF',
               append_images=frames[1:],
               save_all=True,
               duration=41, loop=1, transparency=0)

It is opening all the PNG images I have in a folder, and export them to a GIF, but the background is black.它正在打开我在一个文件夹中的所有 PNG 图像,并将它们导出为 GIF,但背景是黑色的。 I have looked at the PIL documentation , but I don't seem to understand how the transparency parameter works, or I think I am using it wrong.我查看了PIL 文档,但我似乎不明白transparency参数是如何工作的,或者我认为我用错了。

First of all, the GIF format does not support alpha-channel transparency like PNG does.首先, GIF 格式不像 PNG 那样支持 alpha 通道透明度。 You can only select one out of the 256 possible colors in a GIF to be transparent .您只能在 GIF 中的 256 个可能的 colors 中的一个 select 是透明的 So, you also don't get any smooth transparencies, pixels are either fully transparent or opaque.因此,您也不会得到任何平滑的透明度,像素要么是完全透明的,要么是不透明的。

When dealing with Image objects having mode RGBA , try to convert all your images to mode PA before saving.在处理具有RGBA 模式Image对象时,请尝试在保存之前将所有图像转换为PA模式。 Maybe, that helps automagically .也许,这会自动帮助。

Let's assume we have the following three images:假设我们有以下三个图像:

红色的

绿色的

蓝色的

Your minimized code would look like this:您的最小化代码如下所示:

from PIL import Image

frames = [Image.open('red.png'), Image.open('green.png'), Image.open('blue.png')]

frames[0].save('test.gif', format='GIF',
               append_images=frames[1:],
               save_all=True,
               duration=200, loop=0, transparency=0)

The resulting GIF in fact doesn't reflect the transparency from the single PNGs, the GIF is totally corrupted:生成的 GIF 实际上并不反映单个 PNG 的透明度,GIF 已完全损坏:

损坏的输出

Adding the conversion to mode PA , the code might look like this:将转换添加到模式PA ,代码可能如下所示:

from PIL import Image

frames = [Image.open('red.png'), Image.open('green.png'), Image.open('blue.png')]

frames = [frame.convert('PA') for frame in frames]

frames[0].save('test.gif', format='GIF',
               append_images=frames[1:],
               save_all=True,
               duration=200, loop=0, transparency=0)

And, the result is fine, transparency is maintained:而且,结果很好,保持了透明度:

适当的输出

I don't know, if that route works for arbitrary PNGs, but it's worth testing with your images, isn't it?我不知道,该路线是否适用于任意 PNG,但值得用您的图像进行测试,不是吗? If that doesn't work, you need to provide some of your input images for further testing.如果这不起作用,您需要提供一些输入图像以进行进一步测试。

The final approach could be to replace all transparent pixels in your PNGs with a certain color, let's say solid yellow.最后一种方法可能是用某种颜色替换 PNG 中的所有透明像素,比如说纯黄色。 When saving the GIF later, you'd need to make sure, that all images' palettes store that solid yellow at the same index, and then finally set transparency to that index.稍后保存 GIF 时,您需要确保所有图像的调色板都将纯黄色存储在同一索引处,然后最后为该索引设置transparency

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
Pillow:        8.1.0
----------------------------------------

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

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