Python,如何获取gif帧

13 投票
7 回答
30058 浏览
提问于 2025-04-17 02:46

我想找一种方法来获取GIF的帧数。我在谷歌、StackOverflow和其他网站上搜索,但只找到一些没用的东西!有没有人知道怎么做?我只需要GIF帧的简单数字。

7 个回答

6

我最近也遇到了同样的问题,发现关于GIF的文档特别不够详细。这里是我用 imageio的get_reader 来读取图像字节的解决方案(如果你是通过 HTTP获取图像,这个方法特别有用),它会把帧方便地存储在 numpy矩阵 中:

import imageio
gif = imageio.get_reader(image_bytes, '.gif')

# Here's the number you're looking for
number_of_frames = len(gif)

for frame in gif:
  # each frame is a numpy matrix

如果你只需要打开一个文件,可以使用:

gif = imageio.get_reader('cat.gif')
13

只需要解析这个文件,GIF格式其实很简单:

class GIFError(Exception): pass

def get_gif_num_frames(filename):
    frames = 0
    with open(filename, 'rb') as f:
        if f.read(6) not in ('GIF87a', 'GIF89a'):
            raise GIFError('not a valid GIF file')
        f.seek(4, 1)
        def skip_color_table(flags):
            if flags & 0x80: f.seek(3 << ((flags & 7) + 1), 1)
        flags = ord(f.read(1))
        f.seek(2, 1)
        skip_color_table(flags)
        while True:
            block = f.read(1)
            if block == ';': break
            if block == '!': f.seek(1, 1)
            elif block == ',':
                frames += 1
                f.seek(8, 1)
                skip_color_table(ord(f.read(1)))
                f.seek(1, 1)
            else: raise GIFError('unknown block type')
            while True:
                l = ord(f.read(1))
                if not l: break
                f.seek(l, 1)
    return frames
23

你是用什么方法来加载或处理这个帧的?你在用PIL吗?如果没有,我建议你去看看这个:Python图像库,特别是这个PIL的GIF页面

假设你在用PIL来读取GIF文件,其实判断你正在查看哪个帧是很简单的。seek这个方法可以让你跳到特定的帧,而tell这个方法会告诉你现在正在查看的是哪个帧。

from PIL import Image
im = Image.open("animation.gif")

# To iterate through the entire gif
try:
    while 1:
        im.seek(im.tell()+1)
        # do something to im
except EOFError:
    pass # end of sequence

如果不是这样的话,我想你只能通过不断跳帧,直到出现异常(EOFError)来找到GIF中的帧数。

撰写回答