几行脚本搞定压缩纹理缓存,打包速度快到起飞,Mac OS 10.15 & Windows10 均测试成功

大神有没有试过这种方案:
在项目中仍旧用的png,打包后再用工具etcpack将png转为压缩纹理pkm。
如果直接用pkm覆盖png运行是会报错,说找不到png图片。
如果修改pkm的后缀为png,再覆盖原png,可以运行,但是解析的图片有问题。我新建一个helloworld,运行后是这样的:


请问知道是什么问题吗?

你弄个 hello world ,先用 png 构建一次,构建结果提交, 再换成 压缩纹理构建一次, 一对比文件变化就知道了

如果我想在打包之后再用工具转压缩纹理,正确的步骤应该怎么操作。我看之前的帖子是这样的:

2赞

你看的帖子,不适合 2.2.2 或更高的版本,看我前面发的图,那个 json 文件, 用 “|” 分隔后,第一个数字 0 就是 png,6@1026 就是 pkm,你如果要自己搞,就要最后把那个 json 文件修改一下,比较麻烦

1赞

好的,明白了,谢谢

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import hashlib
import subprocess
import gzip


def doGZip(fileSrc,fileOutPut):
    f_in = open(fileSrc, 'rb')
    f_in_content = f_in.read()
    f_in.close()
    f_out = gzip.open(fileOutPut, "wb")
    f_out.write(f_in_content)
    f_out.close()


cachePath = "/Volumes/Data/work/compressedTexturesCache/"
# textureTypes = ["etc1","etc2"]
# # 创建缓存目录
# for textureType in textureTypes:
#     if not os.path.exists(cachePath + textureType):
#         os.makedirs(cachePath + textureType)
#     if not os.path.exists(cachePath + textureType + "/gzip/"):
#         os.makedirs(cachePath + textureType + "/gzip/")

fromPath = sys.argv[1]
targetPath = sys.argv[2]
cacheDir = cachePath + sys.argv[4] + "/" + sys.argv[6]
cacheDirGzip = cacheDir + "/gzip/"
if not os.path.exists(cacheDir):
    os.makedirs(cacheDir)
if not os.path.exists(cacheDirGzip):
    os.makedirs(cacheDirGzip)
fileDir,fileName = os.path.split(fromPath)
baseName=fileName.split(".")[0]

md5 = hashlib.md5(open(fromPath, "rb").read() + fromPath).hexdigest()
pkmUrl=cacheDir + "/" + md5 + ".pkm"
pkmGzipUrl=cacheDirGzip + "/" + md5 + ".pkm"

if not os.path.exists(pkmUrl):
    print("开始压缩",fileName, md5)
    # 缓存文件不存在, 压缩此图片
    res = subprocess.call(["./etcpacktool", fromPath, cacheDir] + sys.argv[3:])
    if res == 0:
        # 压缩成功, 根据 MD5 重命名
        os.rename(cacheDir + "/" + baseName + ".pkm", pkmUrl)
else:
    print("文件存在")

# gzip压缩
if not os.path.exists(pkmGzipUrl):
    print("开始gzip压缩")
    doGZip(pkmUrl,pkmGzipUrl)

# 拷贝文件
status = subprocess.call("cp" + " " + pkmGzipUrl + " " + targetPath + "/" + baseName + ".pkm", shell=True)
if status != 0:
    if status < 0:
        print("Killed by signal", status)
    else:
        print("Command failed with return code - ", status)
else:
    print("拷贝成功")

分享一个修改过后的脚本,增加功能:
1.添加GZip压缩
2.额外区别压缩模式
3.额外区别资源路径

5赞

mark…

这个是替换引擎内置压缩纹理工具的,建议看一下,我前面的教程

老哥 有没有demo提供一个~

老哥 用了win10的那个方案 还是报那个错呀

老哥,有办法在打包中,使用多线程调用etcpack进行纹理压缩吗

我觉得能,只要这个脚本接到任务后,直接返回成功, 然后自己创建一个线程去压缩纹理, 引擎应该就会触发下一个图片的压缩操作,这样应该就能实现多线程了,就是管理起来要麻烦些, 不过理论上应该可以实现

我这边,尝试去使用,碰见了两个问题,第一:etcpack每次进行纹理压缩,会生成一个临时文件,如果,尝试使用多线程去转换,会导致,转出来的pkm文件缺少。第二:cocos传递参数过去的时候是一个一个传递的,等上一个图片转换完毕,才会传第二个图片,主要是cocos传递完之后,会去对应的目录下寻找转换后的pkm文件,如果没找到,会报某个js错误,问题是那个js是打在 app.asar文件里,我尝试进行反编译,发现是被加密的,导致也无法修改js,所以目前这个优化卡着了

http://docs.cocos.com/creator/manual/zh/publish/custom-project-build-template.html


也可以这样,自己弄个插件, 定制构建流程, 在引擎构建开始时使用多线程去做压缩纹理,等引擎到这步的时候,已经有缓存了就快了

1赞

好的 老哥,我这边将尝试使用该方法进行处理,有效果的话 ,我跟你讲,并分享给你

1赞

老哥,我在使用缓存脚本过程中,发现有的图片压缩失败 返回command failed wiwth return code 1,这是什么原因导致的呢,大部分图片都可以压缩成功,只有极个别会发生这种情况,导致最后打包失败

1赞

而且 res = subprocess.call(["./etcpacktool", fromPath, cacheDir] + sys.argv[3:])
返回 res为 -6

这最好能把失败的图片打包发上来, 才好分析,应该是压缩工具返回的错误码,脚本的确也有点问题, 应该把错误抛出去, 让引擎知道发生了错误

我尝试了 用原本的工具进行压缩这张图片,发现是可以的,但是用python脚本的话,这几张图片就会失败,但是其他图片都可以正常 ,我现在将尝试 使用shell脚本 编写中间层,然后尝试,是否跟python一样 拿几张图片是否失败 老哥等我消息 :wink:

更新 引擎从3.3开始又不支持压缩纹理缓存了