在游戏开发、UI 设计等领域,图集打包是一项常见且重要的工作。合理的图集打包可以减少内存占用,提高资源加载效率。今天,我们就来介绍一款强大的图集打包工具 ——texture_packer
,它由texture_packer.bat和texture_packer.py两个文件组成,能帮助我们快速完成图集打包任务。
这是一个 Windows 批处理脚本,主要用于设置参数和调用 Python 脚本。
@echo off
setlocal enabledelayedexpansion
chcp 65001 >nul
::输入文件路径
set DEFAULT_INPUT=C:\Users\13294\Desktop\danny\图集1
::输出目标路径
set DEFAULT_OUTPUT=C:\Users\13294\Desktop\danny\tar
::是否删除原图集文件
set DELETE_FLAG=true
::是否扁平化路径
set FLATTEN_FLAG=true
::是否生成Cocos 2d的plist格式的元数据
set COCOS_FLAG=true
::是否生成JSON格式的元数据
set JSON_FLAG=true
:: 是否生成Unity的TPSheet格式的元数据
set UNITY_FLAG=true
:: 参数解析
set "INPUT_PATH=%~1" :: 文件路径
set "OUTPUT_PATH=%~2" :: 图集存储路径
:: 遍历所有参数,查找标识
for %%a in (%*) do (
if /i "%%a"=="-D" (
set DELETE_FLAG=true
) else if /i "%%a"=="-F" (
set FLATTEN_FLAG=true
) else if /i "%%a"=="-J" (
set JSON_FLAG=true
) else if /i "%%a"=="-U" (
set UNITY_FLAG=true
) else if /i "%%a"=="-C" (
set COCOS_FLAG=true
)
)
:: 设置默认值(当无参数时)
if "%~1"=="" (
set "INPUT_PATH=%DEFAULT_INPUT%"
set "OUTPUT_PATH=%DEFAULT_OUTPUT%"
set "DELETE_FLAG=%DELETE_FLAG%"
set "FLATTEN_FLAG=%FLATTEN_FLAG%"
set "JSON_FLAG=%JSON_FLAG%"
set "UNITY_FLAG=%UNITY_FLAG%"
set "COCOS_FLAG=%COCOS_FLAG%"
)
:: 输入路径验证
if not exist "%INPUT_PATH%" (
echo [ERROR] Invalid input path: "%INPUT_PATH%"
exit /b 1
)
:: 自动生成输出文件名
for %%A in ("%INPUT_PATH%") do set "OUTPUT_NAME=%%~nxA"
:: 显示执行参数
echo [INFO] Runtime parameters:
echo -----------------------------------
echo Input Path : "%INPUT_PATH%"
echo Output Path : "%OUTPUT_PATH%"
echo Delete Flag : %DELETE_FLAG%
echo Flatten Flag : %FLATTEN_FLAG%
echo COCOS FLAG : %COCOS_FLAG%
echo JSON Flag : %JSON_FLAG%
echo UNITY FLAG : %UNITY_FLAG%
echo -----------------------------------
:: 执行打包命令
python texture_packer.py "%INPUT_PATH%" "%OUTPUT_PATH%" %DELETE_FLAG% %FLATTEN_FLAG% %COCOS_FLAG% %JSON_FLAG% %UNITY_FLAG%
:: 保持窗口打开
echo [INFO] Process completed
pause
endlocal
这是一个 Python 脚本,主要负责具体的图集打包操作。
logging
模块记录操作过程中的信息和错误。subprocess
模块调用 TexturePacker
命令进行图集打包,并生成 JSON 和 Cocos2d PLIST 格式的元数据文件。import sys
import os
import subprocess
import logging
# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 排除的图集文件扩展名(避免循环打包)
EXCLUDE_EXTENSIONS = {'.json', '.plist', '.atlas', '.db','.tpsheet'}
def delete_existing_files(base_path):
"""删除原有图集文件"""
json_file = f"{base_path}.json"
plist_file = f"{base_path}.plist"
png_file = f"{base_path}.png"
unity_file = f"{base_path}.tpsheet"
for file in [json_file, plist_file, png_file,unity_file]:
try:
if os.path.exists(file):
os.remove(file)
logging.info(f"删除原有文件:{file}")
except Exception as e:
logging.error(f"删除失败:{file} - {str(e)}")
def check_residual_files(base_path):
"""检查残留文件"""
json_file = f"{base_path}.json"
plist_file = f"{base_path}.plist"
png_file = f"{base_path}.png"
unity_file = f"{base_path}.tpsheet"
return any(os.path.exists(f) for f in [json_file, plist_file, png_file,unity_file])
def get_valid_files(input_dir):
"""获取当前目录的有效图片文件"""
valid_files = []
for entry in os.listdir(input_dir):
full_path = os.path.join(input_dir, entry)
#logging.info(f"发现文件: {full_path}")
if os.path.isfile(full_path):
ext = os.path.splitext(entry)[1].lower()
if ext not in EXCLUDE_EXTENSIONS:
valid_files.append(full_path)
logging.info(f"检查目录 {input_dir} 中有效文件数量: {len(valid_files)}")
return valid_files
def run_texture_packer(common_params, format_type, data_file):
"""运行TexturePacker命令"""
try:
subprocess.run(
[*common_params, "--format", format_type, "--data", data_file],
check=True,
capture_output=True,
text=True,
encoding='gbk', # 关键修复:指定GBK编码适配Windows环境
errors='replace' # 替换无法解码的字符避免报错
)
logging.info(f"生成 {format_type} 格式成功")
except subprocess.CalledProcessError as e:
logging.error(f"生成 {format_type} 格式失败:{e.stderr}")
except Exception as e:
logging.error(f"未知错误:{str(e)}")
def process_directory(
input_dir: str,
output_base: str,
delete_existing: bool,
flatten_output: bool,
root_input_dir: str,
cocos_flag: bool,
json_flag: bool,
unity_flag: bool
):
"""处理单个目录的打包逻辑,支持自定义输出路径和扁平化模式"""
# 计算相对路径用于非扁平化模式
if not flatten_output:
relative_path = os.path.relpath(input_dir, root_input_dir)
final_output_path = os.path.join(output_base, relative_path)
else:
final_output_path = output_base
os.makedirs(final_output_path, exist_ok=True)
final_output_name = os.path.basename(input_dir)
base_path = os.path.join(final_output_path, final_output_name)
# 删除原有图集文件(如果需要)
if delete_existing:
delete_existing_files(base_path)
# 检查残留文件
if check_residual_files(base_path):
logging.info(f"跳过打包:存在残留文件 - {input_dir}")
return
# 获取有效图片文件
valid_files = get_valid_files(input_dir)
if not valid_files:
logging.info(f"跳过打包:无有效图片文件 - {input_dir}")
return
# 通用TexturePacker参数
common_params = [
"TexturePacker",
"--sheet", f"{base_path}.png",
"--opt", "RGBA8888",
"--trim-mode", "None",
"--disable-rotation",
*valid_files # 只传入当前目录的有效文件
]
logging.info(f"\n开始处理:{input_dir}")
logging.info(f"输出位置:{final_output_path}")
logging.info(f"图集名称:{final_output_name}")
logging.info(f"有效文件:{len(valid_files)} 个")
if json_flag:
# 生成JSON格式
run_texture_packer(common_params, "json", f"{base_path}.json")
if unity_flag:
# 生成UNITY TPSHEEP格式
run_texture_packer(common_params, "unity", f"{base_path}.tpsheet")
if cocos_flag:
# 生成Cocos2d PLIST格式
run_texture_packer(common_params, "cocos2d", f"{base_path}.plist")
logging.info(f"✅ 打包完成 - {input_dir}")
def batch_process(
input_path: str,
output_base: str,
delete_existing: bool,
flatten_output: bool,
cocos_flag: bool,
json_flag: bool,
unity_flag: bool
):
"""递归处理目录结构,支持扁平化输出"""
input_abs_path = os.path.abspath(input_path)
if not os.path.exists(input_abs_path):
logging.error(f"错误:输入路径不存在 - {input_abs_path}")
return
logging.info(f"开始处理:{input_abs_path}")
logging.info(f"输出基准路径:{output_base}")
logging.info(f"删除模式:{'启用' if delete_existing else '禁用'}")
logging.info(f"扁平化模式:{'启用' if flatten_output else '禁用'}")
logging.info(f"COCOS模式:{'启用' if cocos_flag else '禁用'}")
logging.info(f"JSON模式:{'启用' if json_flag else '禁用'}")
logging.info(f"UNITY模式:{'启用' if unity_flag else '禁用'}")
def process_recursive(current_dir):
# 处理当前目录
process_directory(
current_dir,
output_base=output_base,
delete_existing=delete_existing,
flatten_output=flatten_output,
root_input_dir=input_abs_path,
cocos_flag=cocos_flag,
json_flag=json_flag,
unity_flag=unity_flag
)
# 递归处理子目录
for entry in os.listdir(current_dir):
subdir_path = os.path.join(current_dir, entry)
if os.path.isdir(subdir_path):
process_recursive(subdir_path)
process_recursive(input_abs_path)
logging.info("\n所有处理完成!")
if __name__ == "__main__":
args = sys.argv[1:]
input_path = args[0] if len(args) > 0 else None
output_path = args[1] if len(args) > 1 else None
delete_flag = args[2].lower() == 'true' if len(args) > 2 else False
flatten_flag = args[3].lower() == 'true' if len(args) > 3 else False
cocos_flag = args[4].lower() == 'true' if len(args) > 4 else False
json_flag = args[5].lower() == 'true' if len(args) > 5 else False
unity_flag = args[6].lower() == 'true' if len(args) > 6 else False
if not input_path:
logging.error("错误:必须指定输入路径")
sys.exit(1)
# 处理默认输出路径:如果未指定则使用输入路径的父目录
final_output_base = output_path or os.path.dirname(os.path.abspath(input_path))
batch_process(
input_path,
output_base=final_output_base,
delete_existing=delete_flag,
flatten_output=flatten_flag,
cocos_flag=cocos_flag,
json_flag=json_flag,
unity_flag=unity_flag
)
texture_packer.bat "C:\path\to\input" "C:\path\to\output" -C -D -F -J
其中,-D表示删除原图集文件,-F表示扁平化路径,-J表示生成 JSON 格式的元数据,-U表示生成 Unity 的 TPSheet 格式的元数据,-C表示生成 Cocos 2d 的 plist 格式的元数据。除了路径其他参数不分先后
或者在texture_packer.bat脚本内替换默认参数,直接双击该脚本
添加新的元数据格式:如果需要支持其他格式的元数据,可以在texture_packer.py文件中添加新的处理逻辑。例如,添加对XML格式的支持,只需在process_directory函数中添加相应的调用代码:
if xml_flag:
# 生成XML格式
run_texture_packer(common_params, "xml", f"{base_path}.xml")
同时,在texture_packer.bat文件中添加对应的参数解析逻辑。
TexturePacker
的参数进行调整,例如修改--opt
参数来改变图片的优化模式,以达到更好的打包效果。texture_packer
是一款功能强大、灵活配置的图集打包工具,通过批处理文件和 Python 脚本的结合,实现了高效的图集打包任务。同时,它具有良好的可扩展性,可以根据实际需求进行定制和优化。希望本文能帮助你更好地使用该工具,提高工作效率。
如果喜欢我的文章,欢迎关注、点赞、转发、评论,大家的支持是我最大的动力
如有疑问或BUG,请加入QQ群一起交流探讨!!!
技术交流QQ群:1011399921!!!