免费用TexturePack和UnPack的功能

正常免费的使用TexturePack和UnPack的功能

前言:去官网下载个TexturePack下来,可发现要使用需要付费才可,如果不想付费点击使用免费版本,但是呢免费版本打出来的图片带有水印,plist倒是正常的,所以我们要做的就是在plist的基础上使用Python脚本读取plist的信息重新生成图片,这样就可以免费使用TexturePack的功能了!
使用免费版就可以使用pack功能了
可惜免费版打出来的是有带水印的,左边免费版
当然有人可能使用的是破解版,可是破解版基本是拷贝一份TexturePackerGUI去覆盖原exe,涉及到用命令打包的你会发现网上大部分破解版并没有破解TexturePacker.exe也就不能使用了,所以这个时候最简单的方式就是去官网下载正版使用free模式,这样即便是终端命名TexturePacker.exe也能使用了,只是打出来的有红色的水印,不过plist信息确实和付费的一样,我们的操作就在这里

TextureRePk 即基于plist的RePack

# -*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

import os
from xml.etree import ElementTree
from PIL import Image

def tree_to_dict(tree):
    d = {}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index+1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index + 1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index+1]) 

    return d

def gen_png_from_plist(plist_filename, png_dir):
    # 第一步 读取plist的信息 解析
    to_list = lambda x: x.replace('{','').replace('}','').split(',')
    # 解析plist为字典
    root = ElementTree.fromstring(open(plist_filename, 'r').read())
    plist_dict = tree_to_dict(root[0])
    # 根据plist画一张大图作为底图
    get_size = plist_dict["metadata"]["size"]
    sizelist = [ int(x) for x in to_list(get_size) ]
    result_image = Image.new('RGBA', sizelist, (0,0,0,0))
    # 判断plist类型 有的plist的用 frame 有的用 aliases 关键有的frame还不一样  这里我先做我面对的几种不一样的情况
    # food14.png {'frame': '{{107,214},{28,28}}', 'rotated': False, 'sourceColorRect': '{{0,0},{28,28}}', 'sourceSize': '{28,28}', 'offset': '{0,0}'}
    # res/shuihuzhuan/loading/logo.png {'spriteSize': '{280,296}', 'textureRect': '{{2,346},{280,296}}', 'textureRotated': True, 'spriteOffset': '{0,0}', 'spriteSourceSize': '{280,296}'}
    for k, v in plist_dict['frames'].items():
        full_path = os.path.join(png_dir, k)
        if not os.path.exists(full_path):
            print u"图片不存在:" + full_path
            continue
        # 打开子图片
        part_png = Image.open(full_path) 

        spriteSourceSize = v["spriteSourceSize"] if v.has_key("spriteSourceSize") else v["sourceSize"]
        spriteSourceSize = [ int(x) for x in to_list(spriteSourceSize) ]
        # pack后剩下的有效区域
        textureRect = v["textureRect"] if v.has_key("textureRect") else v["frame"]
        textureRect = [ int(x) for x in to_list(textureRect) ]
        # 是否旋转
        isRotate = v["textureRotated"] if v.has_key("textureRotated") else v["rotated"]
        # 小图在大图上的区域
        spriteOffset = v["spriteOffset"] if v.has_key("spriteOffset") else v["offset"]
        spriteOffset = [ int(x) for x in to_list(spriteOffset) ]
        # 获得长宽
        width = int( textureRect[3] if isRotate else textureRect[2] )  
        height = int( textureRect[2] if isRotate else textureRect[3] ) 

        if (part_png.size[0] != spriteSourceSize[0]) or (part_png.size[1] != spriteSourceSize[1]):
            print "图片和所描述尺寸不一致:目标替换尺寸->" + str(spriteSourceSize) + " 图片尺寸->" + str(part_png.size)
            continue

        if isRotate:
            rect_box=(  
                ( spriteSourceSize[0] - height)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] - width)/2 - spriteOffset[1],  
                ( spriteSourceSize[0] + height)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] + width)/2 - spriteOffset[1]   
                )  
        else:
            rect_box=(  
                ( spriteSourceSize[0] - width)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] - height)/2 - spriteOffset[1],  
                ( spriteSourceSize[0] + width)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] + height)/2 - spriteOffset[1] 
                )  
        rect_png = part_png.crop(rect_box)
        # 这里有个 spriteOffset 是干嘛的?先不管了
        result_box = ( textureRect[0], textureRect[1], textureRect[0] + width, textureRect[1] + height )
        if isRotate:
            result_image.paste(part_png.rotate(-90), result_box, mask = 0)
        else:
            result_image.paste(rect_png, result_box, mask = 0)
        print "paste", k
    # 保存图片
    save_name = os.path.join( os.path.dirname(plist_filename), plist_dict["metadata"]["realTextureFileName"] )
    result_image.save(save_name)

def main():
    # plist 所在路径
    plist_filename = r'D:\xampp\htdocs\Aproject\mGit\mSnack\res\game\snakePack2.plist'
    # 图片所在文件夹
    png_dir = r'D:\xampp\htdocs\Aproject\mGit\mSnack\res\game\snakePack2'
    # 根据plist生成图片
    if (os.path.exists(plist_filename) and os.path.exists(png_dir)):
        gen_png_from_plist( plist_filename, png_dir )
    else:
        print "make sure you have both plist and pngDir in directory"


if __name__ == '__main__':
    main()

这个脚本目前是以Python2.7版本所写,只需要拖动到SublimeText,修改好plist所在位置和素材图片文件夹就可以了,按Ctrl+B键即可快速运行

TextureUnPk即解压plist和大图为小图片

有时候我们有了大图和plist想要把它拆分成小图片,但是手上有没有趁手的工具,不妨用Python再写一个脚本用于功能TextureUnPacker

# -*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

import os
from xml.etree import ElementTree
from PIL import Image

def tree_to_dict(tree):
    d = {}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index+1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index+1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index+1]) 

    return d

def gen_png_from_plist(filename):

    plist_filename = filename + '.plist'
    png_filename = filename + '.png'
    # 判断两个文件是否存在
    if (not os.path.exists(plist_filename)) or (not os.path.exists(png_filename)):
        print "make sure you have both plist and png files in the directory"
        return True
    to_list = lambda x: x.replace('{','').replace('}','').split(',')
    # 打开大图
    big_image = Image.open(png_filename)
    # 解析plist
    root = ElementTree.fromstring(open(plist_filename, 'r').read())
    plist_dict = tree_to_dict(root[0])
    # 通常遇到的两种plist类型 格式
    # food14.png {'frame': '{{107,214},{28,28}}', 'rotated': False, 'sourceColorRect': '{{0,0},{28,28}}', 'sourceSize': '{28,28}', 'offset': '{0,0}'}
    # res/shuihuzhuan/loading/logo.png {'spriteSize': '{280,296}', 'textureRect': '{{2,346},{280,296}}', 'textureRotated': True, 'spriteOffset': '{0,0}', 'spriteSourceSize': '{280,296}'}
    for k, v in plist_dict['frames'].items():
        spriteSourceSize = v["spriteSourceSize"] if v.has_key("spriteSourceSize") else v["sourceSize"]
        spriteSourceSize = [ int(x) for x in to_list(spriteSourceSize) ]
        # pack后剩下的有效区域
        textureRect = v["textureRect"] if v.has_key("textureRect") else v["frame"]
        textureRect = [ int(x) for x in to_list(textureRect) ]
        # 是否旋转
        isRotate = v["textureRotated"] if v.has_key("textureRotated") else v["rotated"]
        # 小图在大图上的区域
        spriteOffset = v["spriteOffset"] if v.has_key("spriteOffset") else v["offset"]
        spriteOffset = [ int(x) for x in to_list(spriteOffset) ]
        # 获得长宽
        width = int( textureRect[3] if isRotate else textureRect[2] )  
        height = int( textureRect[2] if isRotate else textureRect[3] ) 
        box = [ textureRect[0], textureRect[1], textureRect[0] + width, textureRect[1] + height ]

        rect_on_big = big_image.crop(box)
        if isRotate:
            rect_on_big = rect_on_big.rotate(90)

        result_image = Image.new('RGBA', spriteSourceSize, (0,0,0,0))
        if isRotate:
            result_box=(  
                ( spriteSourceSize[0] - height)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] - width)/2 - spriteOffset[1],  
                ( spriteSourceSize[0] + height)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] + width)/2 - spriteOffset[1]   
                )  
        else:
            result_box=(  
                ( spriteSourceSize[0] - width)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] - height)/2 - spriteOffset[1],  
                ( spriteSourceSize[0] + width)/2 + spriteOffset[0],  
                ( spriteSourceSize[1] + height)/2 - spriteOffset[1] 
                )  

        result_image.paste(rect_on_big, result_box, mask = 0)

        outfile = filename + '/' + k
        print outfile, "generated"
        if not os.path.exists(os.path.dirname(outfile)):
            os.makedirs(os.path.dirname(outfile))

        result_image.save(outfile)

        if isRotate:
            print("isRotate", isRotate, k)


def main():
    # 这里输入要解压的plist文件路径 不需要带.plist 同样的图片一样的名字
    # filename = r'C:\Users\Administrator\Desktop\mibao\xxx'
    filename = r"D:\xampp\htdocs\Aproject\mGit\mSnack\res\game\snakePack2"
    gen_png_from_plist(filename)

if __name__ == '__main__':
    main()

这里写图片描述
比如我要解压exit的图片,这里只需要填入filename = r’G:\quick\reName\exit’即可,前面带r的意思是正则表达式,也就是你输入什么字符串就是什么路径,不会像\n被解析为回车键。

好了到了这里我们就讲解完毕了

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值