TexturePacker 拆解工具

直接使用pip install untp安装该工具即可。
plist 文件其实就是 xml 文件, 可以用 xml.etree.ElementTree 来解析, 恰好之前做过一个 ccb2lua 的项目, 搞起来也是轻车熟路.
lsit 中关键的一个结构是:
12345678910111213 oooo_001.png frame {{978,582},{38,40}} offset{15,42} rotated sourceColorRect {{76,18},{38,40}}sourceSize {160,160}
oooo_001.png
frame
{{978,582},{38,40}}
offset
{15,42}
rotated
sourceColorRect
{{76,18},{38,40}}
sourceSize
{160,160}
字段 含义
frame 在大图上的坐标和尺寸信息
offset trim 过的图片和原图之间的偏移
rotated 是否进行了旋转
ourceColorRect 原始图上的坐标和尺寸信息
ourceSize 原始图片尺寸
我做了一张图来解释这些参数:
这里要注意:
图像 python 的还是选用了 PIL 来搞, 用到的接口也不多:
Image.open(file) ⇒ image
打开图像
Image.new(mode, size) ⇒ image
创建一张图像
im.crop(box) ⇒ image
截图图像一个区域
im.paste(image, box)
将一张图像粘贴到一个区域
这里我大概讲一下实现, 具体大家可以去看源码.
cocos2d-x 的这个 plist 的格式是比较奇怪的 xml, 每一个 key 的 value 都是在下一行:
123456 format2realTextureFileNameoooo.pngsize{1024,1024}
format
2
realTextureFileName
oooo.png
size
{1024,1024}
所以比较方便的实现是一次获取两行, 如下:
123456789 data = {}iterator = iter(_element)while True: try: key = iterator.next() value = iterator.next() data[key.text] = parseElement(value.tag, value) except StopIteration: break
data = {}
iterator = iter(_element)
while True:
try:
key = iterator.next()
value = iterator.next()
data[key.text] = parseElement(value.tag, value)
except StopIteration:
reak
这个着实令人蛋疼, 因为旋转之后, frame 标签记录的宽高值并没有改变, 所以还得自己去判断下有没有旋转. trim+rotate 之后更是令人发指, 因为这样 sourceColorRect 的宽高,xy偏移都会互换. 这里若是思路不清晰, 极有可能被绕晕.
因为开始参考了texture_unpacker_scirpt的实现, 所以思路一直按照它的路线走, 代码中多次判断了是否旋转. 后来发现代码过于晦涩, 于是完全抛弃了它的实现.
最终核心代码如下:
12345678910111213141516171819 rc_image = Image.open(_imagefile)for (name,config) in data["frames"].items(): # parse config frame = parse.parse("{{{{{x:d},{y:d}}},{{{w:d},{h:d}}}}}",config["frame"]) sourceColorRect = parse.parse("{{{{{x:d},{y:d}}},{{{w:d},{h:d}}}}}",config["sourceColorRect"]) sourceSize = parse.parse("{{{w:d},{h:d}}",config["sourceSize"]) rotated = config["rotated"] # create temp image src_rect = (frame["x"],frame["y"],frame["x"]+(frame["h"] if rotated else frame["w"]),frame["y"]+(frame["w"] if rotated else frame["h"])) temp_image = src_image.crop(src_rect) if rotated: temp_image = temp_image.rotate(90) # create dst image dst_image = Image.new('RGBA', (sourceSize["w"], sourceSize["h"]), (0,0,0,0)) dst_image.paste(temp_image, (sourceColorRect["x"],sourceColorRect["y"]), mask=0) dst_image.save(outpath + "/" + name)
rc_image = Image.open(_imagefile)
for (name,config) in data["frames"].items():
# parse config
frame = parse.parse("{{{{{x:d},{y:d}}},{{{w:d},{h:d}}}}}",config["frame"])
ourceColorRect = parse.parse("{{{{{x:d},{y:d}}},{{{w:d},{h:d}}}}}",config["sourceColorRect"])
ourceSize = parse.parse("{{{w:d},{h:d}}",config["sourceSize"])
rotated = config["rotated"]
# create temp image
rc_rect = (frame["x"],frame["y"],frame["x"]+(frame["h"] if rotated else frame["w"]),frame["y"]+(frame["w"] if rotated else frame["h"]))
temp_image = src_image.crop(src_rect)
if rotated:
temp_image = temp_image.rotate(90)
# create dst image
dst_image = Image.new('RGBA', (sourceSize["w"], sourceSize["h"]), (0,0,0,0))
dst_image.paste(temp_image, (sourceColorRect["x"],sourceColorRect["y"]), mask=0)
dst_image.save(outpath + "/" + name)
可以看到只有两处判断了旋转. 大家点这里可以看下texture_unpacker_scirpt的实现, 就会发现它的逻辑确实略显晦涩.
用法已经更新, 大家到这里查看.
项目现已开源至github, 地址https://github.com/justbilt/untp, 并提供了 windows 和 mac 的可执行文件, 位于 Release Page, 有问题欢迎评论或 issue 告知!

你可能感兴趣的:(cocos2dx)