├── .gitignore ├── README.md ├── LICENSE └── tp-png-split.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tp-png-split 2 | TexturePacker 碎图拆分小工具 3 | 4 | 使用方法举例: 5 | ``` 6 | > Python3 tp-png-split.py source export 7 | ``` 8 | - source:图集文件名,需要确保 png、plist 同在,且文件名相同 9 | - export:碎图生成目录,如果目录不存将会创建 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 ShawnZhang2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tp-png-split.py: -------------------------------------------------------------------------------- 1 | import plistlib 2 | import os 3 | import sys 4 | from PIL import Image 5 | 6 | 7 | def export_image(img, pathname, item): 8 | # 去透明后的子图矩形 9 | x, y, w, h = tuple(map(int, item['frame'])) 10 | # 子图原始大小 11 | size = tuple(map(int, item['sourceSize'])) 12 | # 子图在原始图片中的偏移 13 | ox, oy, _, _ = tuple(map(int, item['sourceColorRect'])) 14 | 15 | # 获取子图左上角,右下角 16 | if item['rotated']: 17 | box = (x, y, x + h, y + w) 18 | else: 19 | box = (x, y, x + w, y + h) 20 | 21 | # 使用原始大小创建图像,全透明 22 | image = Image.new('RGBA', size, (0, 0, 0, 0)) 23 | # 从图集中裁剪出子图 24 | sprite = img.crop(box) 25 | 26 | # rotated纹理旋转90度 27 | if item['rotated']: 28 | sprite = sprite.transpose(Image.ROTATE_90) 29 | 30 | # 粘贴子图,设置偏移 31 | image.paste(sprite, (ox, oy)) 32 | 33 | # 保存到文件 34 | print('保存文件:%s' % pathname) 35 | image.save(pathname, 'png') 36 | 37 | # 获取 frame 参数 38 | def get_frame(frame): 39 | result = {} 40 | if frame['frame']: 41 | result['frame'] = frame['frame'].replace('}', '').replace('{', '').split(',') 42 | result['sourceSize'] = frame['sourceSize'].replace('}', '').replace('{', '').split(',') 43 | result['sourceColorRect'] = frame['sourceColorRect'].replace('}', '').replace('{', '').split(',') 44 | result['rotated'] = frame['rotated'] 45 | return result 46 | 47 | # 生成图片 48 | def gen_image(file_name, export_path): 49 | # 检查文件是否存在 50 | plist = file_name + '.plist' 51 | if not os.path.exists(plist): 52 | print('plist文件【%s】不存在!请检查' % plist) 53 | return 54 | 55 | png = file_name + '.png' 56 | if not os.path.exists(png): 57 | print('png文件【%s】不存在!请检查' % plist) 58 | return 59 | 60 | # 检查导出目录 61 | if not os.path.exists(export_path): 62 | try: 63 | os.mkdir(export_path) 64 | except Exception as e: 65 | print(e) 66 | return 67 | 68 | # 使用plistlib库加载 plist 文件 69 | lp = plistlib.load(open(plist, 'rb')) 70 | # 加载 png 图片文件 71 | img = Image.open(file_name + '.png') 72 | 73 | # 读取所有小图数据 74 | frames = lp['frames'] 75 | for key in frames: 76 | item = get_frame(frames[key]) 77 | export_image(img, os.path.join(export_path, key), item) 78 | 79 | 80 | # Press the green button in the gutter to run the script. 81 | if __name__ == '__main__': 82 | if len(sys.argv) == 3: 83 | filename = sys.argv[1] 84 | exportPath = sys.argv[2] 85 | gen_image(filename, exportPath) 86 | --------------------------------------------------------------------------------