Imagemagick & Pillow generate malformed GIF frames

前端 未结 3 1255
[愿得一人]
[愿得一人] 2021-01-23 01:16

I need to extract the middle frame of a gif animation.

Imagemagick:

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

generates

相关标签:
3条回答
  • 2021-01-23 01:23

    Ok, this script will find and save the middle frame of an animated GIF using Pillow.

    It will also display the duration of the GIF by counting the milliseconds of each frame.

    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))
    

    Helpful code:

    • Python: Converting GIF frames to PNG
    • https://github.com/alimony/gifduration
    0 讨论(0)
  • 2021-01-23 01:26

    You can do it like this:

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

    Basically, it generates in full, all the frames and then deletes all frames other than from 4.

    0 讨论(0)
  • 2021-01-23 01:36

    You are attempting to coalesce a single input image into single output image. What you got is what you asked for.

    Instead you should "flatten" frames 0-4 into a single output image:

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

    If you use "-coalesce" you'll get 5 frames of output in frame-0.jpg through frame-4.jpg, the last of them being the image you wanted.

    0 讨论(0)
提交回复
热议问题