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循环...等等。

你可能感兴趣的:(Python资源打包脚本)