当前位置:   article > 正文

游戏素材处理:利用Python把多个序列帧合并为一个大序列图_python 序列帧拼图导出游戏

python 序列帧拼图导出游戏

目录

问题来源

代码解决


游戏素材的整理是一件挺麻烦的事情,但是只要用好了工具,便可以事半功倍。

问题来源

从网上找了一些游戏特效素材,其中包括很多批序列帧图集

一部分特效素材是所有子帧都拼在一张大图上的,

 

而另一部分是若干个单独的序列帧图片

这样使用起来极其不方便,需要把资源的形式统一。最终决定还是把零散的多个序列帧图片拼成一个大图比较方便管理。

 

代码解决

花了点时间用python写了一个转换脚本,

这个脚本会递归遍历给定目录下的所有子目录, 对于每一个末级目录,将其中的所有png图片合成一个大的序列图,保存到给定路径下相同结构的路径中,顺便输出这个序列图的信息到序列图同路径下的文本文件。

 有需要的朋友可以拿去使用。

  1. import os
  2. import math
  3. from PIL import Image
  4. def pngfile2sequence(root_path_to_walk, root_path_to_save):
  5. """
  6. 递归遍历给定目录下的所有子目录,
  7. 对于每一个末级目录,将其中的所有png图片合成一个大的序列图,
  8. 保存到给定路径下相同结构的路径中,顺便输出这个序列图的信息到序列图同路径下的文本文件
  9. Author: Rabbit_Gray
  10. Source: https://blog.csdn.net/Rabbit_Gray
  11. """
  12. # 递归遍历指定目录
  13. for root, dirs, files in os.walk(root_path_to_walk):
  14. if "SequenceMap.png" in files:
  15. files.remove("SequenceMap.png")
  16. if len(dirs) == 0 and len(files) != 0: # 如果某目录下只有文件没有文件夹,那么这是一个动画包
  17. # 打开当前目录下的所有png文件
  18. ani_imgs = [Image.open(os.path.join(root, file)) for file in files if file.endswith(".png")]
  19. if len(ani_imgs) == 0: # 这个动画包中没有png文件
  20. continue
  21. # 获取动画序列信息
  22. ani_w, ani_h = ani_imgs[0].size
  23. ani_frame_num = len(ani_imgs)
  24. mode = ani_imgs[0].mode
  25. # 生成合理排列布局的序列图
  26. for i in range(1, int(ani_frame_num**0.5)+1):
  27. # 将ani_frame_num分解为2个尽可能接近的质因子的乘积
  28. if ani_frame_num%i == 0:
  29. prime_factor_1 = i
  30. prime_factor_2 = int(ani_frame_num / i)
  31. sequence_map_w_num = prime_factor_2
  32. sequence_map_h_num = prime_factor_1
  33. sequence_map_size = (ani_w * sequence_map_w_num, ani_h * sequence_map_h_num)
  34. sequence_map_img = Image.new(mode, sequence_map_size)
  35. # 向空白序列图粘贴子图
  36. for i, img in enumerate(ani_imgs):
  37. position = (i%sequence_map_w_num * ani_w, int(i/sequence_map_w_num) * ani_h)
  38. sequence_map_img.paste(img, position)
  39. # 在指定位置建立相同结构子目录
  40. path_to_save = os.path.join(root_path_to_save, root.replace(root_path_to_walk, ""))
  41. if not os.path.exists(path_to_save):
  42. os.makedirs(path_to_save)
  43. # 保存生成的序列图
  44. sequence_map_img.save(os.path.join(path_to_save, "SequenceMap.png"))
  45. delay_data = ""
  46. if "delay.txt" in files:
  47. with open(os.path.join(root,"delay.txt"), "r") as f:
  48. data = f.read().replace("\n\nCreated By Monogatari.", "")
  49. data = data.split("\n")
  50. data = [d.split(":")[1].strip() for d in data]
  51. delay_data = ",".join(data)
  52. # 导出序列图的信息
  53. with open(os.path.join(path_to_save, "ani_info.txt"), "w") as f:
  54. f.write(f"file=SequenceMap.png\n")
  55. f.write(f"SequenceMap_size_w=%d\n" % sequence_map_size[0])
  56. f.write(f"SequenceMap_size_h=%d\n" % sequence_map_size[1])
  57. f.write(f"ani_frame_cnt=%d\n" % ani_frame_num)
  58. f.write(f"ani_w=%d\n" % ani_w)
  59. f.write(f"ani_h=%d\n" % ani_h)
  60. f.write(f"delay=%s\n" % delay_data)
  61. print(f"保存到 %s" % path_to_save)
  62. if __name__ == "__main__":
  63. # 包含序列帧素材的根文件夹目录
  64. animation_file_path = ".\\冒险岛光效合集\\"
  65. # 生成序列大图的目标文件夹根目录
  66. path_to_save = ".\\new_ani\\"
  67. # 转换
  68. pngfile2sequence(animation_file_path, path_to_save)

转换效果

有的素材会包含delay.txt来说明这个动画特效帧与帧之间的时间间隔,因此程序也试图提取了存在delay.txt文件的动画的帧间隔时长信息。

 

 

 

 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号