TexturePacker 拆解工具

直接使用pip install untp安装该工具即可。
plist 文件其实就是 xml 文件, 可以用 xml.etree.ElementTree 来解析, 恰好之前做过一个 ccb2lua 的项目, 搞起来也是轻车熟路.
lsit 中关键的一个结构是:
12345678910111213oooo_001.png frame {{978,582},{38,40}} offset{15,42} rotated sourceColorRect {{76,18},{38,40}}sourceSize {160,160}
<key>oooo_001.png</key>
<dict>
<key>frame</key>
<string>{{978,582},{38,40}}</string>
<key>offset</key>
<string>{15,42}</string>
<key>rotated</key>
<true/>
<key>sourceColorRect</key>
<string>{{76,18},{38,40}}</string>
<key>sourceSize</key>
<string>{160,160}</string>
</dict>
字段 含义
frame在大图上的坐标和尺寸信息
offsettrim 过的图片和原图之间的偏移
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 都是在下一行:
123456format2realTextureFileNameoooo.pngsize{1024,1024}
<key>format</key>
<integer>2</integer>
<key>realTextureFileName</key>
<string>oooo.png</string>
<key>size</key>
<string>{1024,1024}</string>
所以比较方便的实现是一次获取两行, 如下:
123456789data = {}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的实现, 所以思路一直按照它的路线走, 代码中多次判断了是否旋转. 后来发现代码过于晦涩, 于是完全抛弃了它的实现.
最终核心代码如下:
12345678910111213141516171819rc_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 告知!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值