當素材圖標數量較多難以打理、或者減輕資源大小、模塊化管理等多方面的需求時,經常運用工具將圖片合成一個圖片,雖有對應軟件但也經常卡死。
運用網上搜尋資料與本身知識敲了一個腳本,較為粗略。文末有資源下載
核心代碼:
class AreaNode():
def __init__(self):#x,y,w,h
self.occupied = False
self.lchild = None
self.rchild = None
self.region = [0,0,MaxSize,MaxSize]
def set_region(self,region):
self.region = region
def get_region(self):
return self.region
class AreaTree():
def __init__(self):
self.root = AreaNode()
def pasteimg(self,item):
if(self.root is None):
raise ValueError("area root not found")
if(item is None):
return
return self.paste_img(self.root,item)
def paste_img(self,now_node,item):
global CountSucceed
if(now_node is None):
return False
sregion = now_node.get_region()
if(now_node.occupied):
# lregion = now_node.lchild.get_region()
# rregion = now_node.rchild.get_region()
# if((not now_node.lchild.occupied) and lregion[1] + item.height < rregion[0] + item.width):
# if(self.paste_img(now_node.lchild,item)):
# return True
# else:
# return self.paste_img(now_node.rchild,item)
# else:
# if(self.paste_img(now_node.rchild,item)):
# return True
# else:
# return self.paste_img(now_node.lchild,item)
if(self.paste_img(now_node.rchild,item)):
return True
elif(self.paste_img(now_node.lchild,item)):
return True
else:
return False
else:
if(sregion[2] >= item.width and sregion[3] >= item.height):
ReasultList[AreaIndex].paste(item,(sregion[0],sregion[1]))
WidthList[AreaIndex] = max(WidthList[AreaIndex],sregion[0] + item.width)
HeightList[AreaIndex] = max(HeightList[AreaIndex],sregion[1] + item.height)
write_json(item,sregion[0],sregion[1])
rregion = [sregion[0] + item.width,sregion[1],sregion[2] - item.width,item.height]
lregion = [sregion[0],sregion[1] + item.height,sregion[2],sregion[3] - item.height]
now_node.lchild = AreaNode()
now_node.lchild.set_region(lregion)
now_node.rchild = AreaNode()
now_node.rchild.set_region(rregion)
now_node.occupied = True
CountSucceed = CountSucceed + 1
return True
else:
return False
AreaTreeList = []
ImageList = []
def walk_type(path, file_type):
path_dir = os.path.join(path,file_type)
paths = glob.glob(path_dir)
return paths
def find_last(string,str):
last_position=-1
while True:
position=string.find(str,last_position+1)
if position==-1:
return last_position
last_position=position
def get_file_all():
global IMAGE_SAVE_PATH
packet = raw_input("resource:")
if(os.path.isdir(packet)):
FileNameIndex = find_last(packet,"\\")
FileName = packet[FileNameIndex+1:]
print("FileName = %s"%FileName)
content["file"] = FileName
IMAGE_SAVE_PATH = FileName
push_img(packet)
else:
print("file isn't dir")
def push_img(name):
if(os.path.isfile(name)):
return
for file in os.listdir(name):
newDir = os.path.join(name,file)
push_img(newDir)
image_names = walk_type(name, IMAGES_FORMAT)
for image in image_names:
from_image = Image.open(image)
if(from_image.width > MaxSize or from_image.height > MaxSize):
print("a photo too big")
continue
ImageList.append(from_image)
def write_json(item,x,y):
global content
FileNameIndex = find_last(item.filename,"\\")
content["frames"][item.filename[FileNameIndex+1:]] = {
"x":x,"y":y,"h":item.height,"w":item.width}
if __name__ == "__main__":
get_file_all()
ImageList.sort(lambda a,b: b.height - a.height)
count_file = len(ImageList)
while(len(ImageList)):
AreaIndex = AreaIndex + 1
AreaTreeList.append(AreaTree())
ReasultList.append(Image.new('RGBA', (MaxSize , MaxSize)))
WidthList.append(0)
HeightList.append(0)
for image in list(ImageList):
if(AreaTreeList[AreaIndex].pasteimg(image)):
ImageList.remove(image)
for i in range(0, AreaIndex + 1):
result = ReasultList[i].crop([0,0,WidthList[i],HeightList[i]])
result.save(IMAGE_SAVE_PATH + "_" + str(i) + ".png")
print("%d successed %d fail"%(CountSucceed,count_file - CountSucceed))
json.dump(content,open(IMAGE_SAVE_PATH + ".json",'w'),indent=4)
raw_input("enter any to exit...")
資源傳送門