网上有零散拆解图集的工具,没有整合的,也没有批量处理的,最近抽空,搞了一个整合并可以批量处理的工具,希望对大家有用。
加载配置文件
# 读取配置文件
con = configparser.ConfigParser()
# 读取当前目录下的config文件
con.read("config.ini",encoding="utf-8")
items=con.items('path')
# 解析出需要进行图片拆解的目录
pathOrigin = items[0][1]
# 需要存储解析后的目录
pathDes = items[1][1]
遍历源图片目录下的所有图片,根据类型辨别解析方式
# 遍历文件夹,如果是文件夹,在再往内部遍历
def recursive_listdir(path):
files = os.listdir(path)
for file in files:
file_path = os.path.join(path, file)
if os.path.isfile(file_path):
if fileType == "atlas" :
# 拆解spine的atlas文件
SplitPng.split_atlas(file_path,pathDes)
elif fileType == "plist":
# 拆解plist文件
SplitPng.split_plist(file_path,pathDes)
elif os.path.isdir(file_path):
# 如果是子目录,继续往里面遍历
recursive_listdir(file_path)
(spine)配置文件的解析
import re
# 读取spine的配置文件
def read_data(filepath):
list = []
arr = []
with open(filepath,'r') as f:
for lines in f.readlines():
str = ''.join(lines.split())
find = re.match(".*\.png.*",str)
# 文件里面如果有png,说明是一张图片的新开始
if find != None :
arr = [str]
list.append(arr)
else:
arr.append(str)
return list
# 数据已经从文件中读取为列表形式,当前需要把数据进行整合,那些数据是一个图片的
def parse_data(arr):
list = []
for index in range(len(arr)):
inputarr = arr[index]
temparr = [inputarr[0]]
list.append(temparr)
print("---------------------------------")
for index1 in range(5,len(inputarr)-1,7):
# 图片名称
spicinfo = {}
temparr.append(spicinfo)
spicinfo['name'] = inputarr[index1].replace('/','\\')
for index2 in range(7):
attri = inputarr[index1 + index2].split(':')
if re.match('.*rotate.*',attri[0]) != None:
# 是否旋转
spicinfo['rotate'] = attri[1]
elif re.match('.*size.*',attri[0]):
# 图集上单张图片的尺寸
spicinfo['size'] = attri[1].split(',')
elif re.match('.*xy.*',attri[0]):
# 图集上单张图片的位置
spicinfo['position'] = attri[1].split(',')
elif re.match('.*offset.*',attri[0]):
# 图集上单张图片在源图片上的偏移量
spicinfo['offset'] = attri[1].split(',')
# print(attri[0],"offset---------------")
elif re.match('.*orig.*',attri[0]):
# 原始图片的尺寸
spicinfo['orisize'] = attri[1].split(',')
return list
# 外部调用(读取配置文件)
def read_atlas(filepath):
list = read_data(filepath)
return parse_data(list)
读取plist文件配置,这里仅支持了两个版本的plist,都是比较新的版本
from plistlib import load,FMT_XML
import json
import re
# 读取图片信息和图集上各个图片的数据
def read_data(filepath):
print(filepath)
with open(filepath,"rb") as fp:
plist = load(fp,fmt=FMT_XML)
# frames = plist["frames"]
return plist["metadata"],plist["frames"]
# 将 '{12,12}'变为数组 [12,12]
def get_arr_by_str(str):
mdata = re.search("([-]*[\d]+),([-]*[\d]+)",str)
# print("bbbbb:",mdata.group(),str)
if mdata != None :
return mdata.group().split(',')
return False
# 从map中获取某个key的值
def get_val_from_dic(dic,key):
if key in dic:
return dic[key]
return False
# 从图集配置中,获取旋转角度
def get_rotate(dic,org):
tempval = get_val_from_dic(dic,'rotated')
if not tempval :
tempval = get_val_from_dic(dic,'textureRotated')
if tempval :
org['rotate'] = str(tempval).lower()
else:
org['rotate'] = 'false'
# 从图集配置中,获取图片的原始尺寸
def get_origin_size(dic,org):
tempval = get_val_from_dic(dic,'spriteSourceSize')
if not tempval :
tempval = get_val_from_dic(dic,'sourceSize')
if tempval :
org['orisize'] = get_arr_by_str(tempval)
# 从图集配置中,获取图片的原始尺寸
def get_offset(dic,org):
tempval = get_val_from_dic(dic,'spriteOffset')
if not tempval :
tempval = get_val_from_dic(dic,'sourceColorRect')
str = tempval.replace('{','')
str = str.replace('}','')
arr = str.split(',')
tempval = arr[0]+','+arr[1]
if tempval :
org['offset'] = get_arr_by_str(tempval)
# 从图集配置中,获取图片在图集上的位置
def get_position_size(dic,org):
tempval = get_val_from_dic(dic,'frame')
if not tempval :
tempval = get_val_from_dic(dic,'textureRect')
if tempval :
tempval = tempval.replace('{','')
tempval = tempval.replace('}','')
arr = tempval.split(',')
org['position'] = [arr[0],arr[1]]
org['size'] = [arr[2],arr[3]]
def parse_data(metadata,arr):
list = []
# 获取图片的名称
frames = [metadata['realTextureFileName']]
list.append(frames)
# print(list)
for key in arr:
# print(key,arr[key])
frame = {}
frames.append(frame)
frame['name'] = key.split('.')[0]
data = arr[key]
# 获取旋转数据
get_rotate(data,frame)
# 获取图片原始尺寸
get_origin_size(data,frame)
# 获取图片的偏移量
get_offset(data,frame)
# 获取图片的位置
get_position_size(data,frame)
return list
def read_plist(filepath):
metadata,list = read_data(filepath)
return parse_data(metadata,list)
开始拆解图片并保存
import AtlasFileReader
import PlistFileReader
import os
from PIL import Image
def create_dir(filepath):
arr = filepath.split('\\')
path = arr[0]
# 逐级遍历,如果文件夹没有,则进行创建
for index in range(1,len(arr)):
path = path +'\\'+ arr[index]
if not os.path.exists(path) :
os.mkdir(path)
# 检测图片中是否包含路径,如果存在路径,则进行文件夹的创建
def check_create_dir(pathdir,name):
# 如果名字中包含\,说明需要创建文件夹
name = name.replace('/','\\')
arrname = name.split('\\')
temppath = pathdir
print("检测是否创建文件夹:",pathdir,name)
if len(arrname) > 1 :
for pathindex in range(len(arrname)-1) :
temppath = temppath + '\\' + arrname[pathindex]
print("进行目录创建:",temppath)
create_dir(temppath)
# 进行图片拆解
def split_png(filepath,arr,pathdes,isatlas):
# 读取图片的路径,filename中只有文件名,而没有文件的类型
filename = os.path.basename(filepath).split('.')[0]
abspath = os.path.dirname(filepath)
for index in range(len(arr)):
arr1 = arr[index]
# 拼接读取图片的路径
path = abspath+'\\'+arr1[0]
print("加载图片进行拆解:",path)
# 判断是否有文件
if not os.path.exists(path) :
print('未找到资源:',path)
continue
img = Image.open(path)
# 遍历这个图片上的各个小图的信息
for index1 in range(1,len(arr1)):
data = arr1[index1]
# 取出一个大图中,某个小图的配置数据
name = data['name']
# 创建文件夹
check_create_dir(pathdes+'\\'+filename,name)
# 构建截图区域
pos = data['position']
offset = data['offset']
size = data['size']
# 在图集上是否进行了旋转
rotate = data['rotate']
orisize = data['orisize']
# 在图集上的位置
x = int(pos[0])
y = int(pos[1])
# 在图集上的图片尺寸,有可能是去除了透明区域
w = int(size[0])
h = int(size[1])
# 原始的图片尺寸
ow = int(orisize[0])
oh = int(orisize[1])
# 图集上的图片在原始图片上的偏移量
ox = int(offset[0])
oy = int(offset[1])
# 开始保存图片
if rotate == 'true':
# 根据原始图片尺寸,进行创建,验收模式,尺寸,验收默认值
resImg = Image.new("RGBA",(oh,ow),(0,0,0,0))
# 图集上的区域
box = (x,y,x+h,y+w)
recImg = img.crop(box)
# 将图集上的图片,粘贴到原始图片尺寸上,需要加上偏移量,目标位置的起点与终点位置,并非x,y,width,heigh
# 而是 lx,ly,rx,ry
lx = oy
ly = ox
rx = lx + h
ry = ly + w
resImg.paste(recImg,(lx,ly,rx,ry))
if isatlas :
resImg = resImg.transpose(Image.ROTATE_270)
else:
resImg = resImg.transpose(Image.ROTATE_90)
resImg.save(pathdes+'\\'+filename+'\\'+name+'.png')
else:
# 根据原始图片尺寸,进行创建,验收模式,尺寸,验收默认值
resImg = Image.new("RGBA",(ow,oh),(0,0,0,0))
# 图集上的区域
box = (x,y,x+w,y+h)
recImg = img.crop(box)
lx = ox
ly = oy
rx = lx + w
ry = ly + h
resImg.paste(recImg,(lx,ly,rx,ry))
resImg.save(pathdes+'\\'+filename+'\\'+name+'.png')
# 外部调用,解析atlas文件
def split_atlas(filepath,pathdes):
list = AtlasFileReader.read_atlas(filepath)
split_png(filepath,list,pathdes,True)
# 外部调用,解析plist文件
def split_plist(filepath,pathdes):
list = PlistFileReader.read_plist(filepath)
split_png(filepath,list,pathdes,False)
下载地址:https://download.csdn.net/download/wushi333333/88540646
有问题,可以发邮件给:wushi333333@163.com或者V:wuahi333333