首页 > Python > python2分割有plist文件的精灵表(TexturePacker的线上版)

python2分割有plist文件的精灵表(TexturePacker的线上版)

  置顶更新:最近写了一个MAC版的APP来分割有plist文件的精灵表(照顾用python脚本总是出现问题的朋友),请移步至https://github.com/afantree/CutPicture。点击下载按钮即可下载,也可自己下载code手工编译。

==========时间分割线==========

  曾经有一个朋友给我说我以前写的文章《python2_04分割有plist文件的精灵表》有问题,原因是图片资源打包器常见的有两种,Zwoptex 和 Texture Packer,他们生成的XML(plist)文件的格式是不一样的,我的这个是解析Zwoptex 生成的png 和 plist。
  今天又有一个朋友有过来问我,我把资源文件要过来分析了一下,发现这个文件还是用Texture Packer打包的,我的这个代码不适用的。为了适用Texture Packer的打包,我现在原来的基础上再写一个脚本吧。他是从线上的APP中直接拿来的素材,这个我在操作的过程中,还遇到了一些问题,现在也记一下。

问题1:plist的二进制问题

  执行脚本,报错

Traceback (most recent call last):
  File "encrypt_res.py", line 18, in <module>
    treeroot=ElementTree.parse(filepath+'.plist').getroot()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/etree/ElementTree.py", line 1182, in parse
    tree.parse(source, parser)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/etree/ElementTree.py", line 656, in parse
    parser.feed(data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/etree/ElementTree.py", line 1642, in feed
    self._raiseerror(v)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/etree/ElementTree.py", line 1506, in _raiseerror
    raise err
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 9

  我打开一看,文件头竟然是bplistXXX的,也难怪Xcode发布上线的APP的所有资源都是经过优化的。这个以前见过参见《PList文件的XML与二进制》、《详解Binary Plist格式》,这下不难,输入下面的命令行就解决了问题。

plutil -convert xml1 a.plist

问题2:png的优化问题

  修好了plist开始执行,但是又发现了png的错误,错误如下:

Traceback (most recent call last):
  File "encrypt_res.py", line 60, in <module>
    xim=image.crop(box)
  File "/Library/Python/2.7/site-packages/PIL/Image.py", line 1012, in crop
    self.load()
  File "/Library/Python/2.7/site-packages/PIL/ImageFile.py", line 247, in load
    raise_ioerror(e)
  File "/Library/Python/2.7/site-packages/PIL/ImageFile.py", line 59, in raise_ioerror
    raise IOError(message + " when reading image file")
IOError: broken data stream when reading image file

  鉴于刚才的plist的原因,我直觉判断这个png也是已经被优化过的,网上一查,还真是,苹果官方给的方法,参考自 Technical Q&A QA1681 。执行下面的命令解决:

xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations -q a.png as.png

  下面用file看一下,第一张是被优化过的,第二张是还原后的。

$ file a.png 
a.png: PNG image data, 1342185474 x 735425407, 0-bit grayscale,
$ file as.png 
as.png: PNG image data, 1024 x 1024, 8-bit/color RGBA, non-interlaced

干货3:上代码喽

#encoding=utf-8
import os,sys
from PIL import Image
from xml.etree import ElementTree
filenames=os.listdir(os.getcwd())
i=0
if len(sys.argv)==2:
    filepath=sys.argv[1]
    for filename in filenames:
        if (filename==filepath+'.png') or (filename==filepath+'.plist'):
            i +=1
    if i==0:
        print("No such file or directory!")
    elif i==1:
        print("Both .png and .plist are need!")
    else:
        print("path  ===="+ filepath)
        treeroot=ElementTree.parse(filepath+'.plist').getroot()
        #p=list(per.iter("key"))
        image=Image.open(filepath+'.png')  #open image
        sizelist=(0,0)
        
        #box=(0,0,0,0)
        
        for dict1 in treeroot:
            for index1,item1 in enumerate(dict1): #
                #        print (item1.tag,item1.attrib,item1.text)
                if item1.text=='frames':  #get node who Value=frames
                    #            print (index1)
                    i=0
                    dict2 = dict1[index1+1]
                    #            print(len(dict2))
                    #            for index2,item2 in enumerate(dict2):
                    #                print(item2.tag,item2.attrib,item2.text)
                    while i<len(dict2):
                        print("name:"+dict2[i].text)
                        picname=dict2[i].text
                        dict3 = dict2[i+1]
                        for index3,item3 in enumerate(dict3):
                            #                    print(item3.tag,item3.attrib,item3.text)
                            if item3.text=='frame':
                                #                        print(dict3[index3+1].text)
                                rect=dict3[index3+1].text
                                rectlist = rect.replace('{','').replace('}','').split(',')
                                #                        print(rectlist)
                                box=(int(rectlist[0]),int(rectlist[1]),int(rectlist[0])+int(rectlist[2]),int(rectlist[1])+int(rectlist[3]))

                            if item3.text=='sourceSize':
                                #                        print(dict3[index3+1].text)
                                size=dict3[index3+1].text
                                sizelist = size.replace('{','').replace('}','').split(',')
                                sizelist=(int(sizelist[0]),int(sizelist[1]));
                            #print(sizelist)
                            
                                print("size:")
                                print(sizelist)
                                print("onBig:")
                                print(box)
                                xim=image.crop(box)
                                xxim=Image.new('RGB',sizelist,(255,255,255))
                                box1=((sizelist[0]-box[2]+box[0])/2,(sizelist[1]-box[3]+box[1])/2,(sizelist[0]+box[2]-box[0])/2,(sizelist[1]+box[3]-box[1])/2)
                                print("onNew:")
                                print(box1)
                                xxim.paste(xim,box1,mask=0)
                                if os.path.isdir(filepath):
                                    pass
                                else:
                                    os.mkdir(filepath)
                                if not picname.endswith('.png'):
                                    picname=picname+'.png'
                                outfile=filepath+'/'+picname
                                print("newPath:"+outfile)
                                xxim.save(outfile)
                        i +=2
else:
    print("Please enter only one parameter!")
  1. 还没有评论
评论提交中, 请稍候...

留言


可以使用的标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Trackbacks & Pingbacks ( 0 )
  1. 还没有 trackbacks