使用Python从GIF中提取关键帧

11

我想通过提取15帧GIF图像来压缩它,这些帧最好是不同的。

我正在使用Python和Pillow库,但在Pillow文档中没有找到获取GIF帧数的方法,也没有找到如何从GIF中提取特定帧的方法,因为Pillow限制了这个操作

是否有办法在不连续迭代每一帧的情况下提取帧?是否有更先进的Python库可以处理GIF?


1
@Bram 我不确定其他问题是否完全相关。这个问题是关于如何跳转到任意帧的。 - Mad Physicist
4个回答

12

这是@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


2
这8个帧可能被编号为0..7;-) - Mark Setchell
@MarkSetchell,是的:--)它们确实是。 - Alistair Carscadden
1
那么对原贴的价值是如何使用 for 循环? - mins
@mins 这个值是因为问题要求“提取15帧”,而我所扩展的答案几乎达到了这个目标,所以我的答案将其完全实现了。 - Alistair Carscadden
1
OP不知道如何随机访问特定帧,他必须从第0帧重新开始。答案由@radarhere给出:使用PIL.Image.seek(i) - mins
1
@mins 我认为在SO上扩展答案以更接近问题所寻求的答案是完全可以接受的。迭代帧可能不是最重要的细节,但这是问题中提出的一个目标。一些用户显然发现这个答案很有用,那么你的观点到底是什么? - Alistair Carscadden

9

关于帧数,您需要查找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.jpg')

链接无效。 - Scott
1
@Scott - https://pillow.readthedocs.io/en/stable/reference/plugins.html#PIL.GifImagePlugin.GifImageFile.n_frames@Scott - https://pillow.readthedocs.io/en/stable/reference/plugins.html#PIL.GifImagePlugin.GifImageFile.n_frames - Salil

0
如果您已经导入了tf,您可以执行以下操作:
def load_gif(file_path):
    with tf.io.gfile.GFile(file_path, 'rb') as f:
        video = tf.io.decode_gif(f.read())
    return np.array(video)

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接