Loss of data when extracting frames from GIF to PNG?

▼魔方 西西 提交于 2019-12-05 18:48:35

If you can stick to ImageMagick then it is very simple to solve this:

convert input.gif -coalesce output.png

Otherwise, you will have to consider the different forms of how each GIF frame can be constructed. For this specific type of GIF, and also the other one shown in your other question, the following code works (note that in your earlier question, the accepted answer doesn't actually make all the split parts transparent -- at least with the latest released PIL):

import sys
from PIL import Image, ImageSequence

img = Image.open(sys.argv[1])

pal = img.getpalette()
prev = img.convert('RGBA')
prev_dispose = True
for i, frame in enumerate(ImageSequence.Iterator(img)):
    dispose = frame.dispose

    if frame.tile:
        x0, y0, x1, y1 = frame.tile[0][1]
        if not frame.palette.dirty:
            frame.putpalette(pal)
        frame = frame.crop((x0, y0, x1, y1))
        bbox = (x0, y0, x1, y1)
    else:
        bbox = None

    if dispose is None:
        prev.paste(frame, bbox, frame.convert('RGBA'))
        prev.save('foo%02d.png' % i)
        prev_dispose = False
    else:
        if prev_dispose:
            prev = Image.new('RGBA', img.size, (0, 0, 0, 0))
        out = prev.copy()
        out.paste(frame, bbox, frame.convert('RGBA'))
        out.save('foo%02d.png' % i)

Ultimately you will have to recreate what -coalesce does, since it is likely that the code above may not work with certain GIF images.

You should try keeping the whole history of frames in "background", instead of :

background = Image.new("RGB", size, (255,255,255))
background.paste( lastframe )
background.paste( im2 )

Just create the "background" once before the loop, then only paste() frame on it, it should work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!