裁剪动画GIF的通用方法?

问题描述

我正在研究一种裁剪GIF的解决方案。我可以使用它,但是图像的大小增加了很多。 IE,它是500KB动画GIF,但裁剪后是8MB动画GIF。 我怀疑这是因为我将其转换为RGB,然后在GIF具有部分模式的情况下将帧与上一个合并。

这是我如何执行此操作的示例:

    img = Image.open(file_path)
    last_frame = img.convert('RGBA')
    p = img.getpalette()
    # this method analyzes image and determines if it's in partial mode.
    mode = analyseImage(img)['mode']
    all_frames = []
    frames = ImageSequence.Iterator(img)
    for frame in frames:
        if not frame.getpalette():
            frame.putpalette(p)
        new_frame = Image.new('RGBA',img.size)
        if mode == 'partial':
            new_frame.paste(last_frame)
        new_frame.paste(frame,(0,0),frame.convert('RGBA'))
        last_frame = new_frame.copy()
        new_frame.thumbnail(size,Image.ANTIALIAS)
        all_frames.append(new_frame)
    return all_frames

然后使用方法将其存储为新图像:

new_image_bytes = BytesIO()
om = all_frames[0]
om.info = img.info
om.save(new_image_bytes,format='gif',optimize=True,save_all=True,append_images=all_frames[1:],duration=img.info.get('duration'),loop=img.info.get('loop'))

图片是8MB而不是500KB

我想念任何明显的东西吗?

解决方法

基本上,您在这里所做的就是放弃原始 GIF 可能具有的所有压缩优化。

假设有一个 2 帧 GIF,其中第二帧仅更改裁剪窗口外的像素。裁剪后它可能会变空(因此尺寸很小),但您的过程使其成为第一帧的完整副本,最终导致您描述的膨胀。