赞
踩
目录
游戏素材的整理是一件挺麻烦的事情,但是只要用好了工具,便可以事半功倍。
从网上找了一些游戏特效素材,其中包括很多批序列帧图集
一部分特效素材是所有子帧都拼在一张大图上的,
而另一部分是若干个单独的序列帧图片
这样使用起来极其不方便,需要把资源的形式统一。最终决定还是把零散的多个序列帧图片拼成一个大图比较方便管理。
花了点时间用python写了一个转换脚本,
这个脚本会递归遍历给定目录下的所有子目录, 对于每一个末级目录,将其中的所有png图片合成一个大的序列图,保存到给定路径下相同结构的路径中,顺便输出这个序列图的信息到序列图同路径下的文本文件。
有需要的朋友可以拿去使用。
- import os
- import math
- from PIL import Image
-
-
- def pngfile2sequence(root_path_to_walk, root_path_to_save):
- """
- 递归遍历给定目录下的所有子目录,
- 对于每一个末级目录,将其中的所有png图片合成一个大的序列图,
- 保存到给定路径下相同结构的路径中,顺便输出这个序列图的信息到序列图同路径下的文本文件
- Author: Rabbit_Gray
- Source: https://blog.csdn.net/Rabbit_Gray
- """
-
- # 递归遍历指定目录
- for root, dirs, files in os.walk(root_path_to_walk):
- if "SequenceMap.png" in files:
- files.remove("SequenceMap.png")
-
- if len(dirs) == 0 and len(files) != 0: # 如果某目录下只有文件没有文件夹,那么这是一个动画包
- # 打开当前目录下的所有png文件
- ani_imgs = [Image.open(os.path.join(root, file)) for file in files if file.endswith(".png")]
- if len(ani_imgs) == 0: # 这个动画包中没有png文件
- continue
-
- # 获取动画序列信息
- ani_w, ani_h = ani_imgs[0].size
- ani_frame_num = len(ani_imgs)
- mode = ani_imgs[0].mode
-
- # 生成合理排列布局的序列图
- for i in range(1, int(ani_frame_num**0.5)+1):
- # 将ani_frame_num分解为2个尽可能接近的质因子的乘积
- if ani_frame_num%i == 0:
- prime_factor_1 = i
- prime_factor_2 = int(ani_frame_num / i)
- sequence_map_w_num = prime_factor_2
- sequence_map_h_num = prime_factor_1
- sequence_map_size = (ani_w * sequence_map_w_num, ani_h * sequence_map_h_num)
- sequence_map_img = Image.new(mode, sequence_map_size)
-
- # 向空白序列图粘贴子图
- for i, img in enumerate(ani_imgs):
- position = (i%sequence_map_w_num * ani_w, int(i/sequence_map_w_num) * ani_h)
- sequence_map_img.paste(img, position)
-
- # 在指定位置建立相同结构子目录
- path_to_save = os.path.join(root_path_to_save, root.replace(root_path_to_walk, ""))
- if not os.path.exists(path_to_save):
- os.makedirs(path_to_save)
-
- # 保存生成的序列图
- sequence_map_img.save(os.path.join(path_to_save, "SequenceMap.png"))
-
- delay_data = ""
- if "delay.txt" in files:
- with open(os.path.join(root,"delay.txt"), "r") as f:
- data = f.read().replace("\n\nCreated By Monogatari.", "")
- data = data.split("\n")
- data = [d.split(":")[1].strip() for d in data]
- delay_data = ",".join(data)
-
- # 导出序列图的信息
- with open(os.path.join(path_to_save, "ani_info.txt"), "w") as f:
- f.write(f"file=SequenceMap.png\n")
- f.write(f"SequenceMap_size_w=%d\n" % sequence_map_size[0])
- f.write(f"SequenceMap_size_h=%d\n" % sequence_map_size[1])
- f.write(f"ani_frame_cnt=%d\n" % ani_frame_num)
- f.write(f"ani_w=%d\n" % ani_w)
- f.write(f"ani_h=%d\n" % ani_h)
- f.write(f"delay=%s\n" % delay_data)
-
- print(f"保存到 %s" % path_to_save)
-
-
-
- if __name__ == "__main__":
- # 包含序列帧素材的根文件夹目录
- animation_file_path = ".\\冒险岛光效合集\\"
- # 生成序列大图的目标文件夹根目录
- path_to_save = ".\\new_ani\\"
- # 转换
- pngfile2sequence(animation_file_path, path_to_save)
转换效果
有的素材会包含delay.txt来说明这个动画特效帧与帧之间的时间间隔,因此程序也试图提取了存在delay.txt文件的动画的帧间隔时长信息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。