游戏开发小技TexturePacker生成的图集逆向切分成精灵小图(json | python | PIL | TextureUnPacker | 逆向 | 切图)
Posted 林新发
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了游戏开发小技TexturePacker生成的图集逆向切分成精灵小图(json | python | PIL | TextureUnPacker | 逆向 | 切图)相关的知识,希望对你有一定的参考价值。
文章目录
一、前言
嗨,大家好,我是林新发。
之前有同事找我问我能不能通过json
逆向切分图集,我之前写过一个python
脚本,但是没有存起来,
直到最近又有同事找我,给我发了json
和png
图集,
我决定写篇文章讲一下,也方便下次又有同事问我的时候直接丢出这篇文章~
二、TexturePacker
1、特别说明
首先,本文的python
代码是针对TexturePacker
工具Phaser 3
框架生成出来的图集进行逆向切分,不过只要你懂了原理,其他格式的配置都可以一通百通。
如何知道图集是使用TexturePacker
工具制作的呢?我们可以打开图集同名的配置文件,如果能看到texturepacker
的字样,就说明是使用TexturePacker
工具生成的,例:
2、TexturePacker下载
TexturePacker
官网地址:https://www.codeandweb.com/texturepacker
下载下来后,我们进入bin
目录,可以看到TexturePackerGUI.exe
,双击即可打开,
如下
为了演示,我先使用搞一些散图,然后使用TexturePacker
打个图集出来。
3、准备精灵散图(小图)
以下是我随便搜的一些精灵小图,
4、使用TexturePacker打图集
首先点击界面右侧的 框架
,根据需求选择一个框架,
它支持非常多的框架,如下
我选择的是通用的Phaser 3
,如下,(因为我那两个同事发给我的图集格式都是用的这个-_-,那我就用这个来做演示吧)
接着,我们把小图的整个文件夹拖到界面左侧中,它自动帮我们执行了图集排版,如下,
接着,我们点击发布精灵表
,
填写保存路径,即可生成图集png
和一个json
配置文件,如下
5、json结构分析
其中test.atlas.json
配置表内容如下:
"textures": [
"image": "test_atlas.png",
"format": "RGBA8888",
"size":
"w": 309,
"h": 118
,
"scale": 1,
"frames": [
"filename": "car.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 128,
"h": 128
,
"spriteSourceSize":
"x": 0,
"y": 6,
"w": 128,
"h": 116
,
"frame":
"x": 1,
"y": 1,
"w": 128,
"h": 116
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "bookcase.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 64,
"h": 64
,
"spriteSourceSize":
"x": 8,
"y": 0,
"w": 55,
"h": 64
,
"frame":
"x": 131,
"y": 1,
"w": 55,
"h": 64
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "table_tennis.png",
"rotated": false,
"trimmed": false,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 0,
"y": 0,
"w": 48,
"h": 48
,
"frame":
"x": 131,
"y": 67,
"w": 48,
"h": 48
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "pencil.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 3,
"y": 3,
"w": 42,
"h": 42
,
"frame":
"x": 188,
"y": 1,
"w": 42,
"h": 42
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "cate.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 5,
"y": 3,
"w": 39,
"h": 41
,
"frame":
"x": 232,
"y": 1,
"w": 39,
"h": 41
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "stone.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 6,
"y": 4,
"w": 35,
"h": 40
,
"frame":
"x": 273,
"y": 1,
"w": 35,
"h": 40
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "brinjaul.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 2,
"y": 6,
"w": 42,
"h": 36
,
"frame":
"x": 188,
"y": 45,
"w": 42,
"h": 36
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "carota.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 5,
"y": 6,
"w": 38,
"h": 36
,
"frame":
"x": 232,
"y": 44,
"w": 38,
"h": 36
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "bulb.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 6,
"y": 4,
"w": 36,
"h": 40
,
"frame":
"x": 272,
"y": 44,
"w": 36,
"h": 40
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "pizza.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 4,
"y": 6,
"w": 41,
"h": 34
,
"frame":
"x": 181,
"y": 83,
"w": 41,
"h": 34
,
"anchor":
"x": 0.5,
"y": 0.5
,
"filename": "coconut.png",
"rotated": false,
"trimmed": true,
"sourceSize":
"w": 48,
"h": 48
,
"spriteSourceSize":
"x": 3,
"y": 10,
"w": 42,
"h": 27
,
"frame":
"x": 224,
"y": 83,
"w": 42,
"h": 27
,
"anchor":
"x": 0.5,
"y": 0.5
]
],
"meta":
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:79dd9a57d14f6938f1ea38d2225ac0ce:6ec25dea8a4c4491ba119c28bbdefaf3:2a084c904c80f72428569743fdf0f51d$"
我们分析一下json
配置的结构,画个图方便一目了然,
(注意:这个json
结构仅针对Phaser 3
这个框架,其他框架的格式需要自行分析)
知道了json
的结构,以及每个字段的含义,我们就可以开始逆向了~
三、图集逆向切分精灵图
1、环境准备
人生苦短,我用python
,不要跟我争辩~
如果你没有python
环境,安装一下,我用的是python 3
。
另外因为要进行图形处理,需要安装Pillow
库(PIL
)。
通过pip
命令进行安装
pip install Pillow
如果在python
中import PIL
没有报错,则说明安装PIL
库成功。
2、python代码:TextureUnpacker.py
这里我先直接上代码,注释我写得比较详细,大家应该能看懂,下文我会讲解核心的步骤,
# TexturePacker图集逆向工具,本代码只针对Phaser 3框架的json配置
# 只要你知道原理,其他配置都可自行分析处理,希望你能有自行修改和优化的能力
# Author: 林新发 https://blog.csdn.net/linxinfa
# Create: 2022-03-24
import os
from PIL import Image
import json
# 封装一个TextureUnpacker类
class TextureUnpacker(object):
@classmethod
def split_with_json(cls, f_json, save_dir=None):
f_json = os.path.abspath(f_json)
if save_dir is None:
save_dir = f_json + '_split'
else:
save_dir = os.path.abspath(save_dir)
# 读取json配置表
f = open(f_json, 'r')
txt = f.read()
dt = json.loads(txt)
f.close()
# 大图集文件名
big_texture_file_name = dt['textures'][0]['image']
# 小图序列
frames = dt['textures'][0]['frames']
# 打开大图
big_img = Image.open(big_texture_file_name)
# 遍历生成小图
for index in range(0, len(frames)):
info = frames[index]
# 解析配置
info = cls.parse_as_json(info)
print(info)
# 小图的保存路径
little_image_save_path = os.path.join(save_dir, info['filename'])
# 生成小图
cls.generate_little_image(big_img, info, little_image_save_path)
@classmethod
def generate_little_image(cls, big_img, info, path):
# 创建小图
little_img = Image.new('RGBA', info['sz'])
# PIL.Image.crop()方法用于裁剪任何图像的矩形部分
# box –定义左,上,右和下像素坐标的4元组
region = big_img.crop(info['box'])
if info['rotated']:
region = region.transpose(Image.ROTATE_90)
# 把裁剪出来的图片粘贴到小图上
little_img.paste(region, info['xy'])
save_dir = os.path.dirname(path)
if not os.path.exists(save_dir):
os.makedirs(save_dir)
# 保存
little_img.save(path)
@classmethod
def parse_as_json(cls, info):
"""
"filename": "player_1.png",
"rotated": false,
"trimmed": false,
"sourceSize": "w": 1, "h": 1 ,
"spriteSourceSize": "x": 0, "y": 0, "w": 1, "h": 1 ,
"frame": "x": 1, "y": 1, "w": 1, "h": 1
"""
# 小图宽高
width = info['sourceSize']['w']
height = info['sourceSize']['h']
# 小图矩形信息
frame = info['frame']
# 是否旋转 (顺时针方向90度)
rotated = info['rotated']
if rotated:
# box 定义左、上、右和下像素坐标的4元组
box = (frame['x'], frame['y'],
frame['x'] + frame['h'],
frame['y'] + frame['w'])
else:
box = (frame['x'], frame['y'],
frame['x'] + frame['w'],
frame['y'] + frame['h'])
# 图形在小图中的偏移
x = int((width - frame['w']) / 2)
y = int((height - frame['h']) / 2)
return
'box': box,
'rotated': rotated,
'sz': [width, height],
'xy': (x, y),
'filename' : info['filename']
if __name__ == '__main__':
unpacker = TextureUnpacker()
unpacker.split_with_json('test_atlas.json')
print(以上是关于游戏开发小技TexturePacker生成的图集逆向切分成精灵小图(json | python | PIL | TextureUnPacker | 逆向 | 切图)的主要内容,如果未能解决你的问题,请参考以下文章
游戏开发小技TexturePacker生成的图集逆向切分成精灵小图(json | python | PIL | TextureUnPacker | 逆向 | 切图)
游戏开发小技TexturePacker生成的图集逆向切分成精灵小图(json | python | PIL | TextureUnPacker | 逆向 | 切图)
LibGDX - TexturePacker2不生成/打包图像