如何按数字顺序将编号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
相关产品推荐
相关产品推荐

