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