【问题标题】:Imagemagick & Pillow generate malformed GIF framesImagemagick & Pillow 生成格式错误的 GIF 帧
【发布时间】:2016-06-07 10:12:39
【问题描述】:

我需要提取一个gif动画的中间帧。

Imagemagick:

convert C:\temp\orig.gif -coalesce C:\temp\frame.jpg

正确生成帧:

但是当我提取单个帧时:

convert C:\temp\orig.gif[4] -coalesce C:\temp\frame.jpg

那么框架格式错误,就好像 -coalesce 选项被忽略了:

使用 Pillow 和 ffmpeg 提取单个帧也会导致帧格式错误,在几个 gif 上进行了测试。

下载gif:https://i.imgur.com/Aus8JpT.gif

我需要能够在 PIL、ffmpeg 的 Imagemagick(最好是 PIL)中提取每个 gif 版本的中间帧。

【问题讨论】:

    标签: ffmpeg imagemagick python-imaging-library


    【解决方案1】:

    你可以这样做:

    convert pour.gif -coalesce -delete 0-3,5-8 frame4.png
    

    基本上,它会完整生成所有帧,然后删除除 4 之外的所有帧。

    【讨论】:

    • 它有效,正如我在原始问题中所展示的那样。当您尝试仅提取单个帧 pour.gif[2] 或一系列帧 pour.gif[2-5] 时,它不起作用
    • 我可以在 10 分钟内回答我的问题。感谢您的提醒。
    【解决方案2】:

    好的,此脚本将使用 Pillow 查找并保存动画 GIF 的中间帧。

    它还会通过计算每帧的毫秒数来显示 GIF 的持续时间。

    from PIL import Image
    
    def iter_frames(im):
        try:
            i = 0
            while 1:
                im.seek(i)
                frame = im.copy()
                if i == 0:
                    # Save pallete of the first frame
                    palette = frame.getpalette()
                else:
                    # Copy the pallete to the subsequent frames
                    frame.putpalette(palette)
                yield frame
                i += 1
        except EOFError:  # End of gif
            pass
    
    im = Image.open('animated.gif')
    middle_frame_pos = int(im.n_frames / 2)
    durations = []
    
    for i, frame in enumerate(iter_frames(im)):
        if i == middle_frame_pos:
            middle_frame = frame.copy()
    
        try:
            durations.append(frame.info['duration'])
        except KeyError:
            pass
    
    middle_frame.save('middle_frame.png', **frame.info)
    
    duration = float("{:.2f}".format(sum(durations)))
    print('Total duration: %d ms' % (duration))
    

    有用的代码:

    【讨论】:

      【解决方案3】:

      您正在尝试将单个输入图像合并为单个输出图像。你得到的就是你想要的。

      相反,您应该将 0-4 帧“扁平化”为单个输出图像:

      convert C:\temp\orig.gif[0-4] -flatten C:\temp\frame.jpg
      

      如果您使用“-coalesce”,您将在 frame-0.jpg 到 frame-4.jpg 中获得 5 帧输出,其中最后一个是您想要的图像。

      【讨论】:

      • 不适用于单个帧“orig.gif[4]”,因为它会生成格式错误的帧。需要“-coalesce”,否则后续帧会跳过 GIF 调色板:imagemagick.org/script/command-line-options.php#coalesce。我已经使用 PIL 发布了一个有效的答案。
      • 它适用于单帧,但如果 GIF 被优化,它只会显示与前一帧相比发生变化的部分。您必须使用范围 [0-N]。
      • 没错,这就是单帧出现格式错误的原因。我发布的解决方案会为每一帧复制调色板,因此它会在播放时保存一帧。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 2012-04-04
      • 2015-10-30
      • 2013-12-30
      • 1970-01-01
      • 2021-11-19
      相关资源
      最近更新 更多