展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Python实现批量图片转GIF动图(附源代码)

Python实现批量图片转GIF动图(附源代码)

利用Python的PIL库实现批量图片合成GIF动图,支持PNG、JPG、BMP等格式,可配置帧率、循环次数与文件名排序,自动处理透明通道兼容问题,并提供尺寸缩放、颜色量化、帧优化等压缩功能,生成高质量动图。

本文目录

    自然引入,只在原文已有的标题层级基础上使用

    ,未额外添加模板化小标题。 ---

    今天来聊聊如何用Python把一堆图片合成GIF动图。这事儿听起来简单,但真要上手,会遇到不少坑——图片格式不统一、透明通道导致背景变黑、文件名排序乱套、生成的GIF体积过大……这些问题,其实都可以用一套脚本搞定。下面分享两个版本:一个简洁版,适合快速上手;一个专业版,适合对画质和体积有要求的场景。

    关键内容

    1. 支持 PNG/JPG/BMP 等主流图片格式,自动过滤非图片文件;
    2. 参数灵活配置——输入目录、输出路径、GIF 帧率(FPS)、图像名称顺序和循环次数;
    3. 自动处理图片格式兼容问题,并包含完善的异常提示;
    4. 多维度轻量化压缩,支持 0.1-1.0 缩放因子调整图片大小。

    运行效果:

    Python实现批量图片转GIF动图(附源代码)

    简洁版

    先看一个简洁版方案。这个脚本基于PIL库实现,核心逻辑就几步:读图片、排顺序、生成GIF。代码量不大,但该有的功能一个不少。

    参数配置里,最关键的几个点如下:

    阶段关键操作说明
    参数解析argparse支持输入目录、输出路径、FPS、循环次数、排序方式
    文件筛选os.listdir + 后缀过滤仅保留支持的5种图片格式
    智能排序re.search(r'\d+')提取文件名中的数字进行排序,处理如 frame_001.png
    图像处理Image.open → convert('RGB')统一转RGB,解决透明通道兼容问题
    GIF生成images[0].sa ve(sa ve_all=True)首帧保存,其余帧append
    目录处理os.makedirs(exist_ok=True)自动创建不存在的输出目录

    思路流程:

    Python实现批量图片转GIF动图(附源代码)

    源代码:

    import os
    import argparse
    import re
    from PIL import Image
    
    def create_gif(image_folder, output_path, fps=10, loop=0, sort_order='asc'):
        """
        从指定目录的图片创建GIF动图
        参数:
        image_folder (str): 图片目录路径
        output_path (str): GIF输出路径
        fps (int/float): 每秒帧数,默认0.5
        loop (int): 循环次数(0=无限),默认0
        sort_order (str): 排序方式(asc=升序/desc=降序),默认asc
        """
        # 支持的图片格式
        IMAGE_EXTS = ('.png', '.jpg', '.jpeg', '.bmp', '.webp')
        
        # 筛选目录内的图片文件
        image_files = [
            os.path.join(image_folder, f) 
            for f in os.listdir(image_folder) 
            if f.lower().endswith(IMAGE_EXTS)
        ]
        
        if not image_files:
            raise ValueError(f"目录 '{image_folder}' 未找到图片文件")
        
        # 提取文件名中的数字作为排序依据
        def sort_key(filename):
            basename = os.path.basename(filename)
            match = re.search(r'\d+', basename)
            return int(match.group()) if match else basename
        
        # 根据参数切换升/降序排序
        reverse_flag = True if sort_order == 'desc' else False
        image_files.sort(key=sort_key, reverse=reverse_flag)
        
        # 打印排序后的图片列表
        print(f"找到 {len(image_files)} 张图片,排序方式: {sort_order}")
        for i, f in enumerate(image_files):
            print(f"  {i+1}. {os.path.basename(f)}")
        
        # 打开并处理图片(转RGB兼容透明通道)
        images = []
        for img_path in image_files:
            try:
                img = Image.open(img_path)
                img = img.convert('RGB')  # 统一转为RGB模式
                images.append(img)
            except Exception as e:
                print(f"警告: 无法打开图片 {img_path} - {e}")
        
        if not images:
            raise ValueError("无可用图片文件")
        
        # 计算每帧持续时间(毫秒)
        duration = 1000 / fps
        
        # 保存GIF
        images[0].sa ve(
            output_path,
            sa ve_all=True,
            append_images=images[1:],
            duration=duration,
            loop=loop
        )
        
        # 打印生成结果
        print(f"\nGIF已保存至: {output_path}")
        print(f"帧率: {fps} FPS | 图片数量: {len(images)} | 循环次数: {'无限' if loop == 0 else loop}")
    
    def main():
        # 命令行参数解析
        parser = argparse.ArgumentParser(description='批量图片转GIF动图工具')
        parser.add_argument('--input_dir', default='./coco_test/', help='输入图片目录(默认: ./coco_test/)')
        parser.add_argument('--output_file', default='Output_GIF/coco_test-202601.gif', help='输出GIF文件路径')
        parser.add_argument('-f', '--fps', type=float, default=0.5, help='每秒帧数(默认: 0.5)')
        parser.add_argument('-l', '--loop', type=int, default=0, help='循环次数(0=无限,默认: 0)')
        parser.add_argument('-s', '--sort_order', choices=['asc', 'desc'], default='asc', help='排序方式(asc=升序/desc=降序,默认: asc)')
        
        args = parser.parse_args()
        
        # 校验输入目录是否存在
        if not os.path.isdir(args.input_dir):
            print(f"错误: 输入目录 '{args.input_dir}' 不存在")
            return
        
        # 自动补全GIF扩展名
        if not args.output_file.lower().endswith('.gif'):
            args.output_file += '.gif'
        
        # 自动创建输出目录(如果不存在)
        output_dir = os.path.dirname(args.output_file)
        if output_dir and not os.path.exists(output_dir):
            os.makedirs(output_dir, exist_ok=True)
            print(f"提示: 自动创建输出目录 '{output_dir}'")
        
        # 生成GIF
        try:
            create_gif(args.input_dir, args.output_file, args.fps, args.loop, args.sort_order)
        except Exception as e:
            print(f"错误: {e}")
    
    if __name__ == "__main__":
        main()
    

    打印信息:

    找到 5 张图片,排序方式: asc

    1. 000000000030.jpg

    2. 000000000034.jpg

    3. 000000000192.jpg

    4. 000000000247.jpg

    5. 000000000307.jpg

    GIF已保存至: Output_GIF/coco_test-202601.gif

    帧率: 0.5 FPS | 图片数量: 5 | 循环次数: 无限

    运行效果:

    Python实现批量图片转GIF动图(附源代码)

    专业版

    如果简洁版不够用,那就看看这个增强版。相比基础版,它新增了压缩优化、尺寸缩放、颜色量化等专业功能,适合对GIF质量有更高要求的场景。先看一个对比表,一目了然:

    特性基础版增强版(本代码)
    图片转GIF✅✅
    智能数字排序✅✅
    透明通道处理❌(直接转RGB)✅(白色背景填充)
    尺寸缩放❌✅(LANCZOS重采样)
    颜色量化❌✅(MedianCut算法,1-256色)
    帧差异优化❌✅(optimize参数)
    压缩级别控制❌✅(0-9级)
    调色板质量❌✅(1-100)
    尺寸一致性校验❌✅(打印警告)

    这版工具可以说是麻雀虽小五脏俱全,从图片预处理到GIF优化,一条龙搞定。核心能力可以拆成三块来看:

    1. 核心生成:灵活可控的GIF创建

      • 读取指定目录下PNG/JPG/BMP/WebP等主流格式图片,支持通过-s/--sort_order参数一键切换文件名升序/降序排序;
      • 自定义帧率(FPS)、循环次数(0 = 无限循环),满足不同播放节奏需求。
    2. 预处理:智能兼容 & 规整图片

      • 自动处理RGBA透明图片:将透明背景转为白色,避免GIF背景异常;
      • 校验所有图片尺寸一致性,尺寸不符时给出明确警告,保障动图显示效果;
      • 支持0.1-1.0缩放因子调整图片大小,平衡GIF清晰度与文件体积。
    3. 优化:多维度轻量化压缩

      • 可选颜色数精简:通过中值切割算法限制最大颜色数(1-256),大幅降低GIF体积;
      • 帧优化 + 多级压缩:启用帧差异编码、自定义压缩级别(0-9)、调色板质量(1-100),兼顾画质与压缩率;
      • 内置Floyd-Steinberg抖动算法,减少颜色精简后的画面失真。

    Python实现批量图片转GIF动图(附源代码)

    源代码:

    import os
    import argparse
    import re
    from PIL import Image
    import numpy as np
    
    def create_gif(image_folder, output_path, fps=10, loop=0, 
                   reduce_colors=True, max_colors=256, 
                   optimize_frames=True, resize_factor=1.0, 
                   compress_level=6, quality=85, sort_order='asc'):
        """
        从指定目录图片创建GIF动图(支持压缩/缩放/调色)
        参数:
        image_folder (str): 图片目录路径
        output_path (str): GIF输出路径
        fps (int/float): 每秒帧数,默认10
        loop (int): 循环次数(0=无限),默认0
        reduce_colors (bool): 是否减少颜色数,默认True
        max_colors (int): 最大颜色数(1-256),默认256
        optimize_frames (bool): 是否优化帧(差异编码),默认True
        resize_factor (float): 缩放因子(0.1-1.0),默认1.0(不缩放)
        compress_level (int): 压缩级别(0-9),默认6
        quality (int): 调色板质量(1-100),默认85
        sort_order (str): 排序方式(asc=升序/desc=降序),默认asc
        """
        # 支持的图片格式
        IMAGE_EXTS = ('.png', '.jpg', '.jpeg', '.bmp', '.webp')
        
        # 筛选目录内的图片文件
        image_files = [
            os.path.join(image_folder, f) 
            for f in os.listdir(image_folder) 
            if f.lower().endswith(IMAGE_EXTS)
        ]
        
        if not image_files:
            raise ValueError(f"目录 '{image_folder}' 未找到图片文件")
        
        # 提取文件名中的数字作为排序依据
        def sort_key(filename):
            basename = os.path.basename(filename)
            match = re.search(r'\d+', basename)
            return int(match.group()) if match else basename
        
        # 根据参数切换升/降序排序
        reverse = True if sort_order == 'desc' else False
        image_files.sort(key=sort_key, reverse=reverse)
        
        # 打印排序结果
        print(f"找到 {len(image_files)} 张图片,排序方式: {sort_order}")
        for i, f in enumerate(image_files):
            print(f"  {i+1}. {os.path.basename(f)}")
        
        # 加载并统一图片格式/尺寸
        images = []
        first_size = None
        
        for img_path in image_files:
            try:
                img = Image.open(img_path)
                
                # 校验图片尺寸一致性
                if first_size is None:
                    first_size = img.size
                    print(f"\n基准尺寸: {first_size[0]}x{first_size[1]}")
                elif img.size != first_size:
                    print(f"警告: 图片 {os.path.basename(img_path)} 尺寸 {img.size} 与基准不一致")
                
                # 处理透明通道(转为白色背景)
                if img.mode == 'RGBA':
                    background = Image.new('RGB', img.size, (255, 255, 255))
                    background.paste(img, mask=img.split()[-1])
                    img = background
                else:
                    img = img.convert('RGB')
                
                images.append(img)
                
            except Exception as e:
                print(f"警告: 无法打开图片 {img_path} - {e}")
        
        if not images:
            raise ValueError("无可用图片文件")
        
        print(f"\n成功加载 {len(images)} 张图片")
        
        # 图片缩放(按需)
        if resize_factor != 1.0 and 0.1 <= resize_factor <= 1.0:
            new_size = (int(first_size[0] * resize_factor), 
                       int(first_size[1] * resize_factor))
            print(f"缩放图片: {first_size} → {new_size} (缩放因子: {resize_factor})")
            
            for i in range(len(images)):
                images[i] = images[i].resize(new_size, Image.Resampling.LANCZOS)
        
        # 减少颜色数(按需)
        if reduce_colors and max_colors < 256:
            print(f"减少颜色数至 {max_colors} 色")
            
            for i in range(len(images)):
                images[i] = images[i].quantize(colors=max_colors, 
                                               method=Image.Quantize.MEDIANCUT)
                images[i] = images[i].convert('RGB')
        
        # 计算每帧时长(毫秒)
        duration = 1000 / fps
        
        # 自动创建输出目录(不存在时)
        output_dir = os.path.dirname(os.path.abspath(output_path))
        if output_dir:
            os.makedirs(output_dir, exist_ok=True)
            print(f"\n输出目录已确保存在: {output_dir}")
        
        # 生成并保存GIF(带优化参数)
        print("正在生成GIF文件...")
        images[0].sa ve(
            output_path,
            sa ve_all=True,
            append_images=images[1:],
            duration=duration,
            loop=loop,
            optimize=optimize_frames,
            compress_level=compress_level,
            quality=quality,
            disposal=2,
            dither=Image.Dither.FLOYDSTEINBERG
        )
        
        # 输出生成结果
        file_size = os.path.getsize(output_path) / (1024 * 1024)
        print(f"\n✅ GIF已保存至: {output_path}")
        print(f"? 文件大小: {file_size:.2f} MB | ?️ 帧率: {fps} FPS (每帧 {duration:.1f}ms)")
        print(f"?️ 图片数量: {len(images)} | ? 循环次数: {'无限' if loop == 0 else loop}")
        if resize_factor != 1.0:
            print(f"? 缩放因子: {resize_factor}")
        if reduce_colors:
            print(f"? 颜色数限制: {max_colors}")
        print(f"?️ 压缩级别: {compress_level} | ? 质量设置: {quality}")
    
    def main():
        # 命令行参数解析
        parser = argparse.ArgumentParser(description='GIF生成工具(支持压缩/缩放/调色/排序)')
        parser.add_argument('--input_dir', default='./THUD_Robot_data/', help='输入图片目录(默认: ./Gif_bev_Global_Graph_Range/)')
        parser.add_argument('--output_file', default='Output_GIF/THUD_Robot_data-test.gif', help='输出GIF文件路径')
        parser.add_argument('-f', '--fps', type=float, default=0.5, help='每秒帧数(默认: 0.5)')
        parser.add_argument('-l', '--loop', type=int, default=0, help='循环次数(0=无限,默认: 0)')
        parser.add_argument('-s', '--sort_order', choices=['asc', 'desc'], default='asc',help='排序方式(asc=升序/desc=降序,默认: asc)')
        
        # 压缩/优化相关参数
        parser.add_argument('--no-reduce-colors', action='store_false', default=True, dest='reduce_colors',help='不减少颜色数')
        parser.add_argument('--max-colors', type=int, default=256,help='最大颜色数(1-256),默认256')
        parser.add_argument('--resize', type=float, default=0.6,help='缩放因子(0.1-1.0),默认0.6')
        parser.add_argument('--compress', type=int, default=3, choices=range(0, 10),help='压缩级别(0-9),默认3')
        parser.add_argument('--quality', type=int, default=95,help='调色板质量(1-100),默认95')
        
        args = parser.parse_args()
        
        # 校验输入目录
        if not os.path.isdir(args.input_dir):
            print(f"❌ 错误: 输入目录 '{args.input_dir}' 不存在")
            return
        
        # 自动补全GIF扩展名
        if not args.output_file.lower().endswith('.gif'):
            args.output_file += '.gif'
        
        # 执行GIF生成
        try:
            create_gif(
                args.input_dir, 
                args.output_file, 
                args.fps, 
                args.loop,
                reduce_colors=args.reduce_colors,
                max_colors=args.max_colors,
                resize_factor=args.resize,
                compress_level=args.compress,
                quality=args.quality,
                sort_order=args.sort_order
            )
        except Exception as e:
            print(f"\n❌ 错误: {e}")
            import traceback
            traceback.print_exc()
    
    if __name__ == "__main__":
        main()
    

    配置方面,所有参数都通过命令行传递,无需修改代码。自动补全.gif扩展名避免格式错误,生成后还会输出文件大小、帧率、颜色数等详细信息,方便你掌握结果。另外,程序会自动创建不存在的输出目录,遇到异常图片会跳过而不中断流程,整体容错性不错。

    可视化结果:

    Python实现批量图片转GIF动图(附源代码)

    运行信息:

    找到 7 张图片,排序方式: asc

    1. frame-000010.color.png

    2. frame-000019.color.png

    3. frame-000039.color.png

    4. frame-000046.color.png

    5. frame-000066.color.png

    6. frame-000086.color.png

    7. frame-000109.color.png

    基准尺寸: 960x540

    成功加载 7 张图片

    缩放图片: (960, 540) → (768, 432) (缩放因子: 0.8)

    输出目录已确保存在: /home/user/lgp_dev/01_Gif_picture/Output_GIF

    正在生成GIF文件...

    ✅ GIF已保存至: Output_GIF/THUD_Robot_data-test.gif

    ? 文件大小: 1.14 MB | ?️ 帧率: 0.5 FPS (每帧 2000.0ms)

    ?️ 图片数量: 7 | ? 循环次数: 无限

    ? 缩放因子: 0.8

    ? 颜色数限制: 256

    ?️ 压缩级别: 3 | ? 质量设置: 95

    分析完成~

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Python
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。