在Pillow中保存动画GIF

19 投票
4 回答
59297 浏览
提问于 2025-04-18 12:53

(Python 3.4, PIL 1.1.7, Pillow 2.5.1)

我本来以为这样可以复制原来的GIF动图。

from PIL import Image
im = Image.open(filename)
im.save('temp.gif')

结果,它只保存了第一帧作为静态图。

我哪里做错了呢?

4 个回答

3

我刚遇到同样的问题。我通过设置 save_all=True 来解决了这个问题。所以你就不需要再使用 gifmaker 这个库了。

14

我们可以看到,新的gifmaker脚本版本简单地使用了保存方法,并且为GIF设置了一些特别的参数。

根据文档的说明(https://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html#saving-sequences):

当调用保存方法时,如果使用的是多帧图像,默认情况下只会保存第一帧。如果想保存所有帧,就必须添加一个叫做save_all的参数,并把它设置为True。

如果这个参数存在,还可以使用loop参数来设置GIF循环的次数,duration参数则可以设置每帧之间的时间间隔,单位是毫秒。

27

这个版本只需要用到 pillow 就能正常工作:

from PIL import Image

width = 300
height = 300
im1 = Image.new("RGBA", (width, height), (255, 0, 0))
im2 = Image.new("RGBA", (width, height), (255, 255, 0))
im3 = Image.new("RGBA", (width, height), (255, 255, 255))
im1.save("out.gif", save_all=True, append_images=[im2, im3], duration=100, loop=0)

使用已有的图片:

from PIL import Image

im1 = Image.open('a.png')
im2 = Image.open('b.png')
im3 = Image.open('c.png')
im1.save("out.gif", save_all=True, append_images=[im2, im3], duration=100, loop=0)

另外,由于较低版本的 pillow 可能会悄悄出错,这里还有一个附加版本,带有库版本检查:

from packaging import version
from PIL import Image

im1 = Image.open('a.png')
im2 = Image.open('b.png')
im3 = Image.open('c.png')
if version.parse(Image.PILLOW_VERSION) < version.parse("3.4"):
    print("Pillow in version not supporting making animated gifs")
    print("you need to upgrade library version")
    print("see release notes in")
    print("https://pillow.readthedocs.io/en/latest/releasenotes/3.4.0.html#append-images-to-gif")
else:
    im1.save("out.gif", save_all=True, append_images=[
             im2, im3], duration=100, loop=0)
6

使用在Pillow的GitHub上找到的脚本,点击这里

 from PIL import ImageSequence
 from PIL import Image
 import gifmaker
 sequence = []

 im = Image.open(....)

 # im is your original image
 frames = [frame.copy() for frame in ImageSequence.Iterator(im)]
 
 # write GIF animation
 fp = open("out.gif", "wb")
 gifmaker.makedelta(fp, frames)
 fp.close()

撰写回答