使用 Python 从 GIF 中提取关键帧

Posted

技术标签:

【中文标题】使用 Python 从 GIF 中提取关键帧【英文标题】:Extract key frames from GIF using Python 【发布时间】:2019-01-02 13:46:17 【问题描述】:

我想通过从 GIF 中提取最好应该是不同的 15 帧来压缩 GIF 图像。

我正在使用 Python 和 Pillow 库,但我没有找到任何方法来获取 GIF 在Pillow docs 中的帧数。我也没有找到如何从 GIF 中提取特定帧,因为Pillow restricts that。

有没有什么方法可以在不遍历每一帧的情况下提取帧? 是否有更高级的用于 GIF 处理的 Python 库?

【问题讨论】:

@Bram 我不确定另一个问题是否与此处完全相关。这个问题是关于如何跳转到任意帧。 【参考方案1】:

对于帧数,您正在寻找 n_frames - https://pillow.readthedocs.io/en/5.2.x/reference/plugins.html#PIL.GifImagePlugin.GifImageFile.n_frames。

from PIL import Image
im = Image.open('test.gif')
print("Number of frames: "+str(im.n_frames))

用于提取单帧 -

im.seek(20)
im.save('frame20.gif')

【讨论】:

【参考方案2】:

这是@radarhere 答案的扩展,它将.gif 分成num_key_frames 不同的部分,并将每个部分保存到一个新图像中。

from PIL import Image

num_key_frames = 8

with Image.open('somegif.gif') as im:
    for i in range(num_key_frames):
        im.seek(im.n_frames // num_key_frames * i)
        im.save('.png'.format(i))

结果是somegif.gif被分成8块保存为0..7.png

【讨论】:

这 8 帧大概编号为 0..7 ;-) @MarkSetchell,是的 :--) 他们肯定是。 那么添加到原帖的价值是如何使用for循环? @mins 该值是因为问题要求“提取 15 帧”,而我正在扩展的答案几乎达到了该目标,我的答案一路走来。 OP 不知道如何对特定帧执行随机访问,对于任何帧,他都必须从第 0 帧重新开始。答案由@radarhere 给出:使用PIL.Image.seek(i)【参考方案3】:

提取任何 GIF 文件的正确帧的真正有效解决方案:

BigglesZX/gifextract.py

【讨论】:

以上是关于使用 Python 从 GIF 中提取关键帧的主要内容,如果未能解决你的问题,请参考以下文章

Python:使用PyAV提取视频关键帧

如何从保留帧尺寸的 GIF 文件中提取帧

如何用python实现视频关键帧提取并保存为图片

使用 Python 从 MP3 音乐中提取节拍

制作简单的GIF动图

在python中获取gif的每秒帧数?