最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實現(xiàn)批量圖片轉(zhuǎn)GIF動圖(附源代碼)

 更新時間:2026年04月15日 08:51:18   作者:躬行見萬象  
本文介紹了一個Python實現(xiàn)的批量圖片轉(zhuǎn)GIF工具,提供簡潔版和專業(yè)版兩種實現(xiàn)方案,該工具支持從指定目錄讀取PNG/JPG/BMP等格式圖片,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

本文分享如何實現(xiàn) 批量圖片轉(zhuǎn) GIF 動圖:

關(guān)鍵內(nèi)容

  1. 支持 PNG/JPG/BMP 等主流圖片格式,自動過濾非圖片文件;
  2. 參數(shù)靈活配置輸入目錄、輸出路徑、GIF 幀率(FPS)、圖像名稱順序循環(huán)次數(shù);
  3. 自動處理圖片格式兼容問題,并包含完善的異常提示。
  4. 多維度輕量化壓縮,支持 0.1-1.0 縮放因子調(diào)整圖片大小。

運行效果:

簡潔版

首先分享的是簡潔版,一個批量圖片轉(zhuǎn)GIF動圖的Python腳本,基于PIL庫實現(xiàn)。

代碼的參數(shù)配置:

階段關(guān)鍵操作說明
參數(shù)解析argparse支持輸入目錄、輸出路徑、FPS、循環(huán)次數(shù)、排序方式
文件篩選os.listdir + 后綴過濾僅保留支持的5種圖片格式
智能排序re.search(r'\d+')提取文件名中的數(shù)字進(jìn)行排序,處理如 frame_001.png
圖像處理Image.open → convert('RGB')統(tǒng)一轉(zhuǎn)RGB,解決透明通道兼容問題
GIF生成images[0].save(save_all=True)首幀保存,其余幀append
目錄處理os.makedirs(exist_ok=True)自動創(chuàng)建不存在的輸出目錄

思路流程:

源代碼:

import os
import argparse
import re
from PIL import Image

def create_gif(image_folder, output_path, fps=10, loop=0, sort_order='asc'):
    """
    從指定目錄的圖片創(chuàng)建GIF動圖
    參數(shù):
    image_folder (str): 圖片目錄路徑
    output_path (str): GIF輸出路徑
    fps (int/float): 每秒幀數(shù),默認(rèn)0.5
    loop (int): 循環(huán)次數(shù)(0=無限),默認(rèn)0
    sort_order (str): 排序方式(asc=升序/desc=降序),默認(rèn)asc
    """
    # 支持的圖片格式
    IMAGE_EXTS = ('.png', '.jpg', '.jpeg', '.bmp', '.webp')
    
    # 篩選目錄內(nèi)的圖片文件
    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}' 未找到圖片文件")
    
    # 提取文件名中的數(shù)字作為排序依據(jù)
    def sort_key(filename):
        basename = os.path.basename(filename)
        match = re.search(r'\d+', basename)
        return int(match.group()) if match else basename
    
    # 根據(jù)參數(shù)切換升/降序排序
    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)}")
    
    # 打開并處理圖片(轉(zhuǎn)RGB兼容透明通道)
    images = []
    for img_path in image_files:
        try:
            img = Image.open(img_path)
            img = img.convert('RGB')  # 統(tǒng)一轉(zhuǎn)為RGB模式
            images.append(img)
        except Exception as e:
            print(f"警告: 無法打開圖片 {img_path} - {e}")
    
    if not images:
        raise ValueError("無可用圖片文件")
    
    # 計算每幀持續(xù)時間(毫秒)
    duration = 1000 / fps
    
    # 保存GIF
    images[0].save(
        output_path,
        save_all=True,
        append_images=images[1:],
        duration=duration,
        loop=loop
    )
    
    # 打印生成結(jié)果
    print(f"\nGIF已保存至: {output_path}")
    print(f"幀率: {fps} FPS | 圖片數(shù)量: {len(images)} | 循環(huán)次數(shù): {'無限' if loop == 0 else loop}")

def main():
    # 命令行參數(shù)解析
    parser = argparse.ArgumentParser(description='批量圖片轉(zhuǎn)GIF動圖工具')
    parser.add_argument('--input_dir', default='./coco_test/', help='輸入圖片目錄(默認(rèn): ./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='每秒幀數(shù)(默認(rèn): 0.5)')
    parser.add_argument('-l', '--loop', type=int, default=0, help='循環(huán)次數(shù)(0=無限,默認(rèn): 0)')
    parser.add_argument('-s', '--sort_order', choices=['asc', 'desc'], default='asc', help='排序方式(asc=升序/desc=降序,默認(rèn): 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'
    
    # 自動創(chuàng)建輸出目錄(如果不存在)
    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"提示: 自動創(chuàng)建輸出目錄 '{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 | 圖片數(shù)量: 5 | 循環(huán)次數(shù): 無限

運行效果:

專業(yè)版

這是一個增強版批量圖片轉(zhuǎn)GIF工具,相比之前的基礎(chǔ)版本,新增了壓縮優(yōu)化、尺寸縮放、顏色量化等專業(yè)功能。

核心功能對比:

特性基礎(chǔ)版增強版(本代碼)
圖片轉(zhuǎn)GIF??
智能數(shù)字排序??
透明通道處理?(直接轉(zhuǎn)RGB)?(白色背景填充)
尺寸縮放??(LANCZOS重采樣)
顏色量化??(MedianCut算法,1-256色)
幀差異優(yōu)化??(optimize參數(shù))
壓縮級別控制??(0-9級)
調(diào)色板質(zhì)量??(1-100)
尺寸一致性校驗??(打印警告)

這是一款功能全面、高度可定制的批量圖片轉(zhuǎn) GIF 工具,覆蓋從圖片預(yù)處理到 GIF 優(yōu)化的全流程,核心能力如下:

  1. 核心生成:靈活可控的 GIF 創(chuàng)建

    • 讀取指定目錄下 PNG/JPG/BMP/WebP 等主流格式圖片,支持通過-s/--sort_order參數(shù)一鍵切換文件名升序 / 降序排序;
    • 自定義幀率(FPS)、循環(huán)次數(shù)(0 = 無限循環(huán)),滿足不同播放節(jié)奏需求。
  2. 預(yù)處理:智能兼容 & 規(guī)整圖片

    • 自動處理 RGBA 透明圖片:將透明背景轉(zhuǎn)為白色,避免 GIF 背景異常;
    • 校驗所有圖片尺寸一致性,尺寸不符時給出明確警告,保障動圖顯示效果;
    • 支持 0.1-1.0 縮放因子調(diào)整圖片大小,平衡 GIF 清晰度與文件體積。
  3. 優(yōu)化:多維度輕量化壓縮

    • 可選顏色數(shù)精簡:通過中值切割算法限制最大顏色數(shù)(1-256),大幅降低 GIF 體積;
    • 幀優(yōu)化 + 多級壓縮:啟用幀差異編碼、自定義壓縮級別(0-9)、調(diào)色板質(zhì)量(1-100),兼顧畫質(zhì)與壓縮率;
    • 內(nèi)置 Floyd-Steinberg 抖動算法,減少顏色精簡后的畫面失真。

源代碼:

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'):
    """
    從指定目錄圖片創(chuàng)建GIF動圖(支持壓縮/縮放/調(diào)色)
    參數(shù):
    image_folder (str): 圖片目錄路徑
    output_path (str): GIF輸出路徑
    fps (int/float): 每秒幀數(shù),默認(rèn)10
    loop (int): 循環(huán)次數(shù)(0=無限),默認(rèn)0
    reduce_colors (bool): 是否減少顏色數(shù),默認(rèn)True
    max_colors (int): 最大顏色數(shù)(1-256),默認(rèn)256
    optimize_frames (bool): 是否優(yōu)化幀(差異編碼),默認(rèn)True
    resize_factor (float): 縮放因子(0.1-1.0),默認(rèn)1.0(不縮放)
    compress_level (int): 壓縮級別(0-9),默認(rèn)6
    quality (int): 調(diào)色板質(zhì)量(1-100),默認(rèn)85
    sort_order (str): 排序方式(asc=升序/desc=降序),默認(rèn)asc
    """
    # 支持的圖片格式
    IMAGE_EXTS = ('.png', '.jpg', '.jpeg', '.bmp', '.webp')
    
    # 篩選目錄內(nèi)的圖片文件
    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}' 未找到圖片文件")
    
    # 提取文件名中的數(shù)字作為排序依據(jù)
    def sort_key(filename):
        basename = os.path.basename(filename)
        match = re.search(r'\d+', basename)
        return int(match.group()) if match else basename
    
    # 根據(jù)參數(shù)切換升/降序排序
    reverse = True if sort_order == 'desc' else False
    image_files.sort(key=sort_key, reverse=reverse)
    
    # 打印排序結(jié)果
    print(f"找到 {len(image_files)} 張圖片,排序方式: {sort_order}")
    for i, f in enumerate(image_files):
        print(f"  {i+1}. {os.path.basename(f)}")
    
    # 加載并統(tǒng)一圖片格式/尺寸
    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基準(zhǔn)尺寸: {first_size[0]}x{first_size[1]}")
            elif img.size != first_size:
                print(f"警告: 圖片 {os.path.basename(img_path)} 尺寸 {img.size} 與基準(zhǔn)不一致")
            
            # 處理透明通道(轉(zhuǎn)為白色背景)
            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)
    
    # 減少顏色數(shù)(按需)
    if reduce_colors and max_colors < 256:
        print(f"減少顏色數(shù)至 {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
    
    # 自動創(chuàng)建輸出目錄(不存在時)
    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(帶優(yōu)化參數(shù))
    print("正在生成GIF文件...")
    images[0].save(
        output_path,
        save_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
    )
    
    # 輸出生成結(jié)果
    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"??? 圖片數(shù)量: {len(images)} | ?? 循環(huán)次數(shù): {'無限' if loop == 0 else loop}")
    if resize_factor != 1.0:
        print(f"?? 縮放因子: {resize_factor}")
    if reduce_colors:
        print(f"?? 顏色數(shù)限制: {max_colors}")
    print(f"??? 壓縮級別: {compress_level} | ?? 質(zhì)量設(shè)置: {quality}")

def main():
    # 命令行參數(shù)解析
    parser = argparse.ArgumentParser(description='GIF生成工具(支持壓縮/縮放/調(diào)色/排序)')
    parser.add_argument('--input_dir', default='./THUD_Robot_data/', help='輸入圖片目錄(默認(rèn): ./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='每秒幀數(shù)(默認(rèn): 0.5)')
    parser.add_argument('-l', '--loop', type=int, default=0, help='循環(huán)次數(shù)(0=無限,默認(rèn): 0)')
    parser.add_argument('-s', '--sort_order', choices=['asc', 'desc'], default='asc',help='排序方式(asc=升序/desc=降序,默認(rèn): asc)')
    
    # 壓縮/優(yōu)化相關(guān)參數(shù)
    parser.add_argument('--no-reduce-colors', action='store_false', default=True, dest='reduce_colors',help='不減少顏色數(shù)')
    parser.add_argument('--max-colors', type=int, default=256,help='最大顏色數(shù)(1-256),默認(rèn)256')
    parser.add_argument('--resize', type=float, default=0.6,help='縮放因子(0.1-1.0),默認(rèn)0.6')
    parser.add_argument('--compress', type=int, default=3, choices=range(0, 10),help='壓縮級別(0-9),默認(rèn)3')
    parser.add_argument('--quality', type=int, default=95,help='調(diào)色板質(zhì)量(1-100),默認(rèn)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'
    
    # 執(zhí)行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()
  • 配置:零代碼便捷適配

    • 全參數(shù)通過命令行配置(輸入 / 輸出路徑、縮放、壓縮、排序等),無需修改代碼;
    • 自動補全.gif擴展名,避免格式錯誤;
    • 輸出生成后詳細(xì)信息(文件大小、幀率、顏色數(shù)等),直觀掌握結(jié)果。
  • 魯棒性:防錯 & 易調(diào)試

    • 自動創(chuàng)建不存在的輸出目錄,無需手動建文件夾;
    • 校驗輸入目錄有效性,捕獲異常并打印錯誤堆棧,快速定位問題;
    • 跳過無法打開的異常圖片,不中斷整體生成流程。

可視化結(jié)果:

運行信息:

找到 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

基準(zhǔn)尺寸: 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)
??? 圖片數(shù)量: 7 | ?? 循環(huán)次數(shù): 無限
?? 縮放因子: 0.8
?? 顏色數(shù)限制: 256
??? 壓縮級別: 3 | ?? 質(zhì)量設(shè)置: 95

分析完成~

到此這篇關(guān)于Python實現(xiàn)批量圖片轉(zhuǎn)GIF動圖(附源代碼)的文章就介紹到這了,更多相關(guān)Python圖片轉(zhuǎn)GIF動圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

佳木斯市| 黄山市| 双辽市| 庆城县| 南陵县| 弥渡县| 开平市| 枣阳市| 巢湖市| 峨边| 同仁县| 尼玛县| 宝应县| 昭苏县| 平和县| 习水县| 苏尼特左旗| 蓬溪县| 青冈县| 余干县| 谢通门县| 济南市| 鄱阳县| 惠来县| 广西| 固始县| 康马县| 察哈| 三河市| 泊头市| 宁夏| 仙游县| 黄梅县| 会泽县| 阳江市| 扎囊县| 封开县| 邓州市| 文化| 黄龙县| 马鞍山市|