python 从动画GIF中提取帧,正确处理调色板和帧更新模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 从动画GIF中提取帧,正确处理调色板和帧更新模式相关的知识,希望对你有一定的参考价值。

'''
A fork of this gist https://gist.github.com/BigglesZX/4016539 .
Ported to Python3 and verify it with Pillow.
'''

import argparse
import os
from PIL import Image

def find_dir(path):
    '''
    Create target directory if it does not exist.
    '''
    if not os.path.exists(path):
        os.makedirs(path)

def analyze_image(path):
    '''
    Pre-process the image to determine the mode (full or additive).
    '''
    image = Image.open(path)
    results = {'size': image.size, 'mode': 'full'}

    try:
        while True:
            if image.tile:
                tile = image.tile[0]
                update_region = tile[1]
                update_region_dimensions = update_region[2:]
                if update_region_dimensions != image.size:
                    results['mode'] = 'partial'
                    break
            image.seek(image.tell()+1)
    except EOFError:
        pass

    return results

def process_image(path):
    '''
    Iterate through the frames in GIF, extracting each frame.
    '''
    mode = analyze_image(path)['mode']

    image = Image.open(path)

    i = 0
    palette = image.getpalette()
    last_frame = image.convert('RGBA')

    new_dir = ''.join(os.path.basename(path).split('.')[:-1])
    find_dir(new_dir)

    try:
        while True:
            print('Saving {:} ({:}) frame {:}, {:} {:}'
                  .format(path, mode, i, image.size, image.tile))
            if not image.getpalette():
                image.putpalette(palette)

            new_frame = Image.new('RGBA', image.size)

            if mode == 'partial':
                new_frame.paste(last_frame)

            new_frame.paste(image, (0, 0), image.convert('RGBA'))
            new_path = '{:}/{:}.png'.format(new_dir, i)
            new_frame.save(new_path, 'PNG')

            i += 1
            last_frame = new_frame
            image.seek(image.tell()+1)
    except EOFError:
        pass

def get_file_path():
    '''
    Get the file path from command line.
    '''
    # Setup the parser.
    parser = argparse.ArgumentParser(description='Extract .gif into frames.')
    parser.add_argument('filePath', help='Path to the file.')

    # Retrieve the filenames.
    args = parser.parse_args()

    return args.filePath

def main():
    '''
    The main function, wrapped to avoid global variable issue.
    '''
    path = get_file_path()
    process_image(path)

if __name__ == '__main__':
    main()

以上是关于python 从动画GIF中提取帧,正确处理调色板和帧更新模式的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 将 MP4视频 转换为GIF动画

在 PHP 中读取动画 GIF

如何从保留帧尺寸的 GIF 文件中提取帧

如何在制作 gif FFMPEG WEBM TO GIF 之前覆盖帧

将 GIF 的所有帧显示为单个图像

在 iPhone(一些 C 库)上创建动画 gif?