You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按数字顺序将编号PNG帧生成GIF(解决glob排序异常问题)

如何按数字顺序将编号PNG帧生成GIF(解决glob排序异常问题)

嗨,这个问题我之前也踩过坑!glob默认是按字典序排序的,所以才会出现frame10排在frame2前面的情况——字符串比较时只看单个字符的顺序,"10"的第一个字符"1"比"2"小,它可不管数字实际大小哦。

下面给你几个靠谱的解决办法,按需选择就行:

方法一:手动提取文件名中的数字排序(无需额外库)

直接对glob获取的文件列表做自定义排序,提取文件名里的数字作为排序依据,代码修改如下:

import glob
from PIL import Image
import os

def make_gif(frame_folder):
    # 获取所有PNG文件路径
    image_paths = glob.glob(f"{frame_folder}/*.png")
    # 按文件名中的数字排序:提取frame后的数字转成整数作为排序key
    sorted_images = sorted(
        image_paths,
        key=lambda x: int(os.path.splitext(os.path.basename(x))[0].replace('frame', ''))
    )
    # 按顺序打开所有图片
    frames = [Image.open(img) for img in sorted_images]
    
    frame_one = frames[0]
    # 这里优化下:append_images用frames[1:],避免重复添加第一帧
    frame_one.save(
        "gif_name.gif",
        format="GIF",
        append_images=frames[1:],
        save_all=True,
        duration=100,
        loop=0
    )

if __name__ == "__main__":
    make_gif("path_to_directory")

这个方法适合文件名格式完全固定的场景(比如都是frame+数字+.png),不用装额外库,逻辑也清晰。

方法二:用natsort库做自然排序(更省心)

如果文件名格式可能有变化,或者不想自己写排序逻辑,可以用专门做自然排序的natsort库,它能自动识别字符串中的数字并按实际大小排序:

先安装库:

pip install natsort

然后修改代码:

import glob
from PIL import Image
from natsort import natsorted

def make_gif(frame_folder):
    # 直接用natsorted替代默认排序
    image_paths = natsorted(glob.glob(f"{frame_folder}/*.png"))
    frames = [Image.open(img) for img in image_paths]
    
    frame_one = frames[0]
    frame_one.save(
        "gif_name.gif",
        format="GIF",
        append_images=frames[1:],
        save_all=True,
        duration=100,
        loop=0
    )

if __name__ == "__main__":
    make_gif("path_to_directory")

这个方法更鲁棒,哪怕文件名里的数字位数不固定(比如frame1.png和frame0010.png),也能正确排序。

补充小提示

你之前尝试用os包的思路是对的,用os.listdir也能实现,和方法一逻辑类似:

import os
image_paths = [os.path.join(frame_folder, f) for f in os.listdir(frame_folder) if f.endswith('.png')]
sorted_images = sorted(image_paths, key=lambda x: int(os.path.splitext(os.path.basename(x))[0].replace('frame', '')))

不过glob已经帮你过滤了.png文件,用glob会更省事~

备注:内容来源于stack exchange,提问作者requiemman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 10:18:12