Python资源打包脚本

  • 利用Python实现调用系统api执行TexturePacker指令来对资源合图
  • 利用Python中zipfile库来对合完后的图进行打成zip包操作
  • python我也是现学现卖,做到这些,首先要熟悉python对文件操作相关函数
  • 环境:windows7 | python2.7.5 | TexturePacker3.0.9

利用脚本执行TexturePacker指令对图片资源合图操作

资源分布示意图

  • 对res文件夹内所有子文件夹中的资源操作
  • 例如path:../dir/res/1_001/(3-5张图)

合图代码

  • TexturePacker安装并且配置好环境变量这是必需。在终端中输入TexturePacker来检测
  • 关于TexturePacker指令相关推荐这篇文章

代码:

import os,os.path,sys
# 打包
class PackerHelper(object):
    def __init__(self,inputDir,outputDir):
        super(PackerHelper, self).__init__()
        # TexturePacker指令
        self.sCmd_tp = 'TexturePacker'
        # 接收参数 资源路径
        self.inputDir   = inputDir  
        # 接收参数 输出路径         
        self.outputDir  = outputDir
        print u"\n******************"
        print u"所要合图的资源路径   -> %s"%self.inputDir
        print u"所要合图的资源输出路径 -> %s"%self.outputDir
        print u"******************\n"

    # ----------
    # 打包资源
    def packer(self):
        resDirList = os.listdir(self.inputDir)
        print u"存在%d个文件夹待合图 "%len(resDirList)
        # 遍历文件夹(也就是1_001 -- 1_024这些文件夹)
        for n in range(len(resDirList)):
            # 拼接新的保存路径
            outPath = os.path.join(self.outputDir,resDirList[n])
            # 拼接新的输入路径
            inputPath = os.path.join(self.inputDir,resDirList[n])
            # 获取每个文件夹中的文件名
            fimeNameList = os.listdir(inputPath)
            # 指令拷贝
            tp_cmd = self.sCmd_tp
            # 拼接资源路径(path/fileName paht/fileName.....)
            allImage = ""
            for im in range(len(fimeNameList)):
                allImage = allImage + " " + inputPath + os.sep + fimeNameList[im]
            # 拼接打包指令(这里只对散图合成大图操作,其他处理先不要,指令可以参考http://blog.csdn.net/lovehappy108/article/details/51462831)
            tp_cmd = tp_cmd + " " + allImage +\
                    " --data " + outPath + os.sep + resDirList[n] + ".plist"\
                    " --sheet " + outPath + os.sep + resDirList[n] + ".png"\
                    " --format " + "cocos2d"
                    # " --border-padding 0" \
                    # " --trim-mode Trim" \
                    # " --basic-sort-by Name" \
                    # " --basic-order Ascending" \
                    # ....
            # 调用系统api执行TexturePacker指令
            os.system(tp_cmd)
        print u"合图完成!"

if __name__ =='__main__':
    inputDir        = 'C:\\Users\\Administrator\\Desktop\\dir\\res\\'         # 资源路径
    inputDir_pack   = 'C:\\Users\\Administrator\\Desktop\\dir\\outDir_pack'   # 导出的合图路径

    # 先打包散图资源
    sPackerHelper = PackerHelper(inputDir,inputDir_pack)
    sPackerHelper.packer()

结果图

  • 接下来是对合完图后的文件夹(outDir_pack里的字文件夹)进行zip操作

利用Python中zipfile库来对文件夹进行zip操作

  • 我所要把各个文件夹成zip的目的是,为了在游戏客户端提供下载和解压操作,这里就涉及到了这几点:
    • zip包大小保存
    • zip包名称保存
    • zip包中资源数量保存
    • zip包的md5保存(后期图片资源修改了,需要从新下载,用于判断zip包是否有变化)
  • 根据上述涉及到这几点,在打包过程中需要生成对应的配置文件来进行保存。
  • 这里先做压缩操作,至于配置文件后面步骤来生产。

打包代码

import os,os.path,sys
import zipfile  # zip操作
import hashlib  # md5生成

# 压缩
class ZipHelper(object):
    def __init__(self,desPath,outpath):
        super(ZipHelper, self).__init__()
        # 要打包的路径
        self.desPath = desPath 
        # 打包完成的输出路径
        self.outpath = outpath
        print u"\n******************"
        print u"所要打包的资源路径   -> %s"%self.desPath
        print u"所要打包的资源输出路径 -> %s"%self.outpath
        print u"******************\n"
        # zip文件保存路径是否存在校验
        if not os.path.exists(self.outpath):
            print u"压缩包输出文件夹  ->%s 不存在!!"%self.outpath
            os.makedirs(self.outpath)
            print u"压缩包输出文件创建完成 ->%s"%self.outpath

        # 需要压缩的文件夹集合
        self.zipDirs = []

    # 获取一个文件夹下的所有文件
    def getDirFiles(self,dirPath):
        # 装载文件的容器(['C:\Users\Administrator\Desktop\dir\outDir_pack\1_001\1_001.plist', 'C:\Users\Administrator\Desktop\dir\outDir_pack\1_001\1_001.png'])
        fileList = []
        # 是文件的话直接加到容器中
        if os.path.isfile(dirPath):
            fileList.append(dirPath) 
        else :
            # 不是文件则遍历目录
            for root, dirs, files in os.walk(dirPath):
                for name in files:
                    # 将路径和文件名拼接上加到容器中
                    fileList.append(os.path.join(root, name))
        return fileList

    def run(self):
        # 得到目录下的所有文件夹名(dir/outDir_pack下所有的字文件夹名称['1_001', '1_002',...'1_024'])
        rootList = os.listdir(self.desPath)
        # 循环这些文件夹进行操作
        for i in range(0,len(rootList)):
            # 获取到每个文件夹名称(1_001...)
            dirName = rootList[i]
            # 拼接文件夹路径(资源路径+子文件名称[C:\Users\Administrator\Desktop\dir\outDir_pack\1_001、C:\Users\Administrator\Desktop\dir\outDir_pack\1_002...])
            filepath = os.path.join(self.desPath,rootList[i])
            # 判断路径是否是文件
            if not os.path.isfile(filepath):
                # 不是文件的话就获取文件夹里面的所有资源(目前是.plst和一张png图,前面不是已经合成大图了嘛)
                files = self.getDirFiles(filepath)
                # 组装每个zip包的数据(名称,zip包命名[路径+文件名+后缀],所要打包的资源[plist,png])
                task = {'name':('name="%s"'%dirName),'des' : self.outpath+dirName+".zip",'fileList' : files}
                # 将要打包的zip数据存在容器中,待打包操作
                self.zipDirs.append(task)

        print u"zip 数量:%d" % len(self.zipDirs)

        # 遍历要打包的容器数据
        for task in self.zipDirs:
            # 取出zip名(路径+文件名+后缀)
            zipFileName = task['des']
            # 取出要打进zip包的资源(plist+png)
            fileList = task['fileList']
            # 调用zipfile库进行打包(param01:zip名,param02:新建一个zip或覆盖一个已经存在的zip,param03:压缩方式)
            zf = zipfile.ZipFile(zipFileName, "w", zipfile.ZIP_STORED)
            # 循环遍历将资源(plist,和png)打进zip包
            for tar in fileList:
                arcname = tar[len(self.desPath):]
                # 将文件资源添加到zip包中去并且携带路径(在解压的时候就用到了,文件资源[plist,png])
                zf.write(tar,"res\\normal\\atlas_image\\"+arcname)
            zf.close()
            print u"正在压缩...  -> %s" % (task['des'])
            #self.zipDirs容器中每条数据后面会追加2个字段md5\size
            # task 后面增加一个字段md5
            task['md5']  = 'md5="%s"'%self.getFileMD5New(zipFileName)
            # task 后面增加一个字段size 记录字节
            task['size'] = 'size="%s"'%os.path.getsize(zipFileName)
        print u"压缩完成!"

    # 生成zip文件的MD5码
    def getFileMD5New(self,filePath):
        # zip包
        zipInfo = zipfile.ZipFile(filePath,'r')
        # MD5操作
        md5 = hashlib.md5()
        # 获取到zip每个文件来更新生产md5
        for oneFile in zipInfo.infolist():
            text = zipInfo.read(oneFile)
            md5.update(text)
        zipInfo.close()
        return md5.hexdigest()

if __name__ =='__main__':
    inputDir_pack   = 'C:\\Users\\Administrator\\Desktop\\dir\\outDir_pack'   # 导出的合图路径
    inputDir_zip    = 'C:\\Users\\Administrator\\Desktop\\dir\\outDir_zip\\'  # 导出的zip包路径

    # 后压缩Zip包
    sZipHelper = ZipHelper(inputDir_pack,inputDir_zip)
    # 开始处理
    sZipHelper.run()

结果图

  • 接下来要处理生产配置文件

生产配置文件

  • 上面说了生成配置文件需要保存的数据(名称、大小、资源数量、md5)并且也将除了资源数量的其他信息保存到了容器里了。
  • 这里需要知道的资源数量不是合图之后的数量(即plist和png),而是未合图之前的资源个数,所以这里需要在PackerHelper类中增加一个容器,用来保存每个文件夹中的资源数量。
  • 然后在ZipHelper类中调用PackerHelper中的保存数量的容器来获取每个文件夹的资源数量,这样就即可,这些操作在下面的源代码文件中可以看到。这里就只列出写入到配置文件的函数。
  • 在ZipHelper类中增加一个方法start_create_Info_file(),用来写入数据到配置文件中,因为这里我是在lua端做调试,所以这些字段我都是按照lua表格式保存的。

创建并写入配置文件代码

# 开始创建版本文件
def start_create_Info_file(self):
    # 创建版本文件
    pFile = open(os.path.join(self.outpath, "config.txt"),'w')
    # 写入其起始数据
    pFile.write("local atlas_config = {\n")
    # 遍历数据容器
    for task in self.zipDirs:
        name  = task['name']    # 文件名
        count = task['count']   # 文件数量
        md5   = task['md5']     # 文件MD5
        size  = task['size']    # 文件字节(大小)
        # 写入数据
        pFile.write("{%s,%s,%s,%s},\n" % (name,count,size,md5))
    # 写入结尾数据
    pFile.write("}\nreturn atlas_config")
    pFile.close()

结果图

资源下载

点击这里去CSDN下载

  • 这个脚本中各个小函数都需要拿出来单个实践实践,看它的用处,将这些小函数称为组块,当你了解这些组块后在将它们融合在一起。我在做这些也是如此,比如os.path.join | os.listdir | for循环...等等。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,475评论 4 372
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,744评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,101评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,732评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,141评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,049评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,188评论 2 320
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,965评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,716评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,867评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,341评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,663评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,376评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,200评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,990评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,179评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,979评论 2 279

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,111评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,598评论 25 707
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 98,616评论 9 467
  • 触地时间则是个非常奇妙的数据,它和“衡”,“柔”都有关系,你既要做到“衡”,也就是让自己的身体左右和上下起伏过大,...
    一沭阅读 191评论 0 0
  • 1号宝宝 第1天 症状:1 热咳 :(咳嗽,打喷嚏,粘黄鼻涕,舌尖红); 2 虚火:舌苔不厚,身体偏瘦...
    Alisa小英阅读 469评论 0 0