249 lines
9.2 KiB
Python
249 lines
9.2 KiB
Python
#!/usr/bin/env python
|
||
# coding:utf-8
|
||
import os
|
||
import sys
|
||
|
||
curr_dir = os.path.split(os.path.abspath(__file__))[0]
|
||
sys.path.append(os.path.join(curr_dir, '../'))
|
||
sys.path.append(os.path.join(curr_dir, '../config_convert'))
|
||
|
||
import utils as utils
|
||
import config as config
|
||
import json
|
||
import re
|
||
import numpy as np
|
||
from psd_tools import PSDImage
|
||
from PIL import Image
|
||
from config_convert.game_play_type import MainPlayType
|
||
|
||
|
||
levels_root_path = os.path.join(curr_dir, "../../Assets/AssetRaw/UIRaw/Raw/Level/")
|
||
thumbnail_root_path = os.path.join(curr_dir, "../../Assets/AssetRaw/UIRaw/Raw/Thum/")
|
||
version_path = os.path.join(curr_dir, "../../../../../unity_ap_bundle_resource/psd_version.json")
|
||
|
||
# 游戏玩法的设计分辨率
|
||
design_width = 1040
|
||
design_height = 1280
|
||
|
||
thumbnail_size = (2000,2910)
|
||
crop_rect = (250,0,1250,1000)
|
||
crop_size = (1000,1000)
|
||
|
||
#psd需要用到的一些命名规则
|
||
titem_group = 'titem'
|
||
nouse_group = 'nouse'
|
||
tfull_layer = 'tfull'
|
||
base_layer = 'base'
|
||
mask_layer = 'tmask'
|
||
tlight_name = 'tlight'
|
||
tshadow_name = 'tshadow'
|
||
group_name = 'group_'
|
||
|
||
json_level_id = 'levelId'
|
||
json_list = 'JsonPiecesDataList'
|
||
json_x_pos = 'XPos'
|
||
json_y_pos = 'YPos'
|
||
json_name = 'Name'
|
||
scale = 0
|
||
|
||
version = {}
|
||
|
||
def run(psd_path, levels_output_dir, thumbnail_output_dir):
|
||
"""
|
||
解析PSD文件
|
||
:param path: psd文件路径
|
||
:param levels_output_dir: 关卡资源输出文件夹路径,
|
||
:param thumbnail_output_dir: 缩略图资源输出文件夹路径
|
||
:return: 无
|
||
"""
|
||
print(f'开始解析:{psd_path}')
|
||
psd_name = os.path.split(psd_path)[1].replace('.psd','')
|
||
psd_type = psd_name.split('_')[0]
|
||
# export_dir = os.path.join(levels_root_path,psd_type)
|
||
if not os.path.exists(levels_output_dir):
|
||
os.mkdir(levels_output_dir)
|
||
|
||
if not os.path.exists(thumbnail_output_dir):
|
||
os.mkdir(thumbnail_output_dir)
|
||
|
||
psd = PSDImage.open(psd_path)
|
||
level_info_json_data = {}
|
||
level_info_json_data[json_level_id] = psd_name
|
||
piece_list = []
|
||
titem_out_path = os.path.join(levels_output_dir, 'titem')
|
||
if not os.path.exists(titem_out_path):
|
||
os.mkdir(titem_out_path)
|
||
|
||
for layer in psd:
|
||
layer.visible = True
|
||
if layer.name == nouse_group and layer.is_group():
|
||
# layer.visible = False
|
||
continue
|
||
if layer.name == titem_group and layer.is_group():
|
||
for item_layer in layer:
|
||
piece_data = {}
|
||
item_layer.visible = True
|
||
# lt_x, lt_y = layer.offset
|
||
# c_w, c_h = layer.size
|
||
# c_x, c_y = lt_x + c_w / 2, lt_y + c_h / 2
|
||
# piece_data[json_x_pos] = c_x
|
||
# piece_data[json_y_pos] = c_y
|
||
piece_data[json_name] = f'{psd_name}_{item_layer.name}'
|
||
piece_list.append(piece_data)
|
||
img_cur_item_layer = item_layer.composite()
|
||
img_cur_item_layer.save(f"{titem_out_path}/{psd_name}_{item_layer.name}.png")
|
||
|
||
if layer.is_group() and group_name in layer.name:
|
||
for child_layer in layer:
|
||
piece_data = {}
|
||
lt_x, lt_y = child_layer.offset
|
||
c_w, c_h = child_layer.size
|
||
c_x, c_y = lt_x + c_w / 2, lt_y + c_h / 2
|
||
piece_data[json_x_pos] = c_x
|
||
piece_data[json_y_pos] = c_y
|
||
piece_data[json_name] = f'{psd_name}_{child_layer.name}'
|
||
|
||
img_cur_layer = child_layer.composite()
|
||
img_cur_layer.save(f"{levels_output_dir}/{psd_name}_{child_layer.name}.png")
|
||
piece_list.append(piece_data)
|
||
if not layer.is_group():
|
||
piece_data = {}
|
||
lt_x, lt_y = layer.offset
|
||
c_w, c_h = layer.size
|
||
c_x, c_y = lt_x + c_w / 2, lt_y + c_h / 2
|
||
piece_data[json_x_pos] = c_x
|
||
piece_data[json_y_pos] = c_y
|
||
piece_data[json_name] = f'{psd_name}_{layer.name}'
|
||
|
||
img_cur_layer = layer.composite()
|
||
img_cur_layer.save(f"{levels_output_dir}/{psd_name}_{layer.name}.png")
|
||
piece_list.append(piece_data)
|
||
level_info_json_data[json_list] = piece_list
|
||
json_path = os.path.join(levels_output_dir, f'{psd_name}.json')
|
||
with open(json_path, "w") as f:
|
||
f.write(json.dumps(level_info_json_data))
|
||
|
||
# print(level_info_json_data)
|
||
thumbnail_path = os.path.join(thumbnail_output_dir, f'{psd_name}_thum.png')
|
||
|
||
psd_image = psd.composite(layer_filter=lambda
|
||
mix_layer : mask_layer in (mix_layer.name) or tfull_layer in (mix_layer.name) or base_layer in (mix_layer.name))
|
||
# psd_image = psd.composite()
|
||
psd_image.thumbnail(thumbnail_size)
|
||
crop_image = psd_image.crop(crop_rect)
|
||
crop_image.save(thumbnail_path)
|
||
print(f'解析完毕:{psd_path}')
|
||
pass
|
||
|
||
def make_version_file(remake):
|
||
"""
|
||
生成version文件
|
||
:param remake: 重新生成
|
||
:return:
|
||
"""
|
||
version_file = os.path.join(curr_dir, version_path)
|
||
if remake:
|
||
if os.path.exists(version_file):
|
||
os.remove(version_file)
|
||
if not os.path.exists(version_file):
|
||
with open(version_file, "w") as f:
|
||
json.dump({}, f, sort_keys=True, indent=4)
|
||
|
||
def load_version():
|
||
"""
|
||
加载版本文件
|
||
"""
|
||
global versions
|
||
make_version_file(False)
|
||
version_file = os.path.join(curr_dir, version_path)
|
||
with open(version_file, "r") as f:
|
||
try:
|
||
versions = json.load(f)
|
||
except Exception as e:
|
||
print(e)
|
||
# 删除版本文件并重新生成
|
||
make_version_file(True)
|
||
|
||
def write_version():
|
||
version_file = os.path.join(curr_dir, version_path)
|
||
with open(version_file, "w") as f:
|
||
json.dump(versions, f, sort_keys=True, indent=4)
|
||
|
||
def parse_psd(path, output_root, specific_files, platform):
|
||
"""
|
||
解析psd文件
|
||
:param path: psd文件路径
|
||
:param output_root: 资源输出路径
|
||
:param specific_files: 需要解析文件列表, 如果为[]则解析所有文件,否则只解析列表中的文件
|
||
:return: 所有解析psd name
|
||
"""
|
||
print("解析指定文件", specific_files)
|
||
mainPlayType = MainPlayType()
|
||
global levels_root_path, thumbnail_root_path, version_path
|
||
# 重置保存路径
|
||
levels_root_path = os.path.join(output_root, "Raw/Level")
|
||
thumbnail_root_path = os.path.join(output_root, "Raw/Thum")
|
||
utils.mkdirs(levels_root_path)
|
||
utils.mkdirs(thumbnail_root_path)
|
||
version_path = os.path.join(output_root, f"../psd_version.json")
|
||
load_version()
|
||
all_parse_asset_names = []
|
||
for root, dirs, files in os.walk(path):
|
||
for name in files:
|
||
if name.endswith(".zip"):
|
||
src_filename = os.path.join(root, name)
|
||
file_name = os.path.split(src_filename)[1]
|
||
asset_id = file_name.split(".")[0]
|
||
if asset_id not in specific_files:
|
||
continue
|
||
|
||
hash_old = ""
|
||
if asset_id in versions:
|
||
hash_old = versions[asset_id]
|
||
hash_now = utils.calc_hash(src_filename)
|
||
print("文件:" + src_filename + " => old = " + hash_old + " now = " + hash_now)
|
||
if hash_old != hash_now:
|
||
print("文件更改:" + src_filename + " => old = " + hash_old + " now = " + hash_now)
|
||
levels_output_dir = None
|
||
thumbnail_output_dir = None
|
||
for gameplay in mainPlayType.all_main_play_type_list:
|
||
if gameplay in asset_id:
|
||
gameplay_dir = os.path.join(levels_root_path, gameplay)
|
||
if not os.path.exists(gameplay_dir):
|
||
os.mkdir(gameplay_dir)
|
||
levels_output_dir = os.path.join(gameplay_dir, asset_id)
|
||
thumbnail_output_dir = os.path.join(thumbnail_root_path, gameplay)
|
||
utils.clear_dirs(levels_output_dir)
|
||
break
|
||
|
||
if levels_output_dir is None or thumbnail_output_dir is None:
|
||
print(asset_id + "资源命名异常,找不到对应玩法gameplay")
|
||
continue
|
||
psd_zip_filename = os.path.join(root, name)
|
||
utils.unzip_file(psd_zip_filename)
|
||
psd_filename = "{}.psd".format(os.path.splitext(os.path.join(root, name))[0])
|
||
run(psd_filename, levels_output_dir, thumbnail_output_dir)
|
||
all_parse_asset_names.append(asset_id)
|
||
versions[asset_id] = hash_now
|
||
write_version()
|
||
os.remove(psd_filename)
|
||
return all_parse_asset_names
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# pass
|
||
# PSD测试方法
|
||
# parse_psd(sys.argv[1], sys.argv[2], [])
|
||
# print(os.getcwd())
|
||
# print(os.path.curdir)
|
||
# psd_path = "./CheckPsd/main_30point_ws20250422_1.psd"
|
||
psd_dir = "./CheckPsd"
|
||
psd_files = {}
|
||
for filename in os.listdir(psd_dir):
|
||
filepath = os.path.join(psd_dir, filename)
|
||
if os.path.isfile(filepath) and filename.lower().endswith('.psd'):
|
||
file_name = filename.replace('.psd', '')
|
||
psd_files[file_name] = filepath
|
||
print(psd_files)
|
||
for k,v in psd_files.items():
|
||
run(v,f'./{k}',f'./{k}/thu') |