在Python中如何获取gif的帧率?

6
在Python中,我使用PIL加载了一个gif文件。我提取了第一帧,进行了修改,并重新放回。我使用以下代码保存了修改后的gif文件。
imgs[0].save('C:\\etc\\test.gif',
           save_all=True,
           append_images=imgs[1:],
           duration=10,
           loop=0)

其中imgs是由多张图片组成的数组,duration是每帧之间的延迟时间(以毫秒为单位)。我想让duration值与原始gif相同,但我不确定如何提取gif的总持续时间或每秒显示的帧数。

据我所知,gif的头文件没有提供任何fps信息。

有人知道我怎样才能得到正确的duration值吗?

提前感谢您的帮助。

编辑:请求的gif示例:

enter image description here

这里检索。


如果您在此答案 https://dev59.com/DIzda4cB1Zd3GeqPoptW#31194595 中找不到更好的方法,可以使用 ImageMagick 获取以厘秒为单位的帧延迟。 - Mark Setchell
一个GIF不会指示fps,因为每个单独的图像都可以有自己的时间。这是一个潜在的问题吗?如果不是,将它们全部加起来,然后除以帧数。 - Jongware
@usr2564301 这不是问题,因为帧的持续时间始终相等,因此我可以从中计算出帧速率,但我不知道如何获取每个帧的持续时间,你知道吗? - Thomas B.
我不知道,但是GIF格式在其他地方有广泛的描述。甚至可能有一些现成的代码可用。同时,你能否在你的问题中添加这样一个GIF呢? - Jongware
上面我链接的答案中有一个动画GIF,其中列出了每帧的延迟时间。 - Mark Setchell
当您使用PIL的Image.open()函数时,可以获取一个ImageObj.info()字典,其中包含duration作为键。请参见:Pillow文档 - agtoever
1个回答

12
在GIF文件中,每个帧都有自己的持续时间。因此,GIF文件没有通用的fps。PIL支持这一点的方法是提供一个info字典,其中包含当前帧的duration。您可以使用seektell来遍历帧并计算总持续时间。
下面是一个计算GIF文件平均帧速率的示例程序。
import os
from PIL import Image

FILENAME = os.path.join(os.path.dirname(__file__),
                        'Rotating_earth_(large).gif')

def get_avg_fps(PIL_Image_object):
    """ Returns the average framerate of a PIL Image object """
    PIL_Image_object.seek(0)
    frames = duration = 0
    while True:
        try:
            frames += 1
            duration += PIL_Image_object.info['duration']
            PIL_Image_object.seek(PIL_Image_object.tell() + 1)
        except EOFError:
            return frames / duration * 1000
    return None

def main():
    img_obj = Image.open(FILENAME)
    print(f"Average fps: {get_avg_fps(img_obj)}")

if __name__ == '__main__':
    main()

如果你假设所有帧的{{duration}}相等,那么你只需要这样做:
print(1000 / Image.open(FILENAME).info['duration'])

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