日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

工具 - 分解TexturePacker导出的大图

發布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 工具 - 分解TexturePacker导出的大图 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?這是一個用于分解TexturePacker導出的大圖的工具。

需要包含png圖片和.plist文件

使用Python編寫的,界面使用的是wxPython庫寫的。

以下是實現代碼:

''' 功能: 分解TexturePacker制作的圖集,要求包含plist文件和圖片1.制作一個簡單的界面來指定要分解的圖集(plist文件和圖片)1.提供選擇plist文件2.提供選擇圖片文件3.提供保存路徑選擇 2.根據選擇的文件做分解操作1.讀取plist文件,并解析2.根據解析出來的數據對圖集進行裁剪,并生成新的圖片3.將圖片保存到指定文件夾中參考: 1.wxpython教程1:https://blog.csdn.net/xufive/article/details/82665460?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166532024216782388061584%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166532024216782388061584&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_positive~default-1-82665460-null-null.nonecase&utm_term=wxpython&spm=1018.2226.3001.4450 2.wxpython教程2:https://edu.csdn.net/skill/python/python-3-176?category=9&typeId=17490 3.wxpython教程 - 事件:https://blog.csdn.net/weixin_42161954/article/details/109302843?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-109302843-blog-113688944.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-109302843-blog-113688944.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=5 4.Python中的Partial函數(偏函數):https://edu.csdn.net/skill/python/python-3-176?category=9&typeId=17490#41__429 5.wxpython教程Wiki:https://wiki.wxpython.org/Passing%20Arguments%20to%20Callbacks 6.with open() 結構:https://blog.csdn.net/m0_48936146/article/details/124360734 7.plist文件解析plistlib:https://www.osgeo.cn/cpython/library/plistlib.html 8.python打包exe:https://blog.csdn.net/m0_64355682/article/details/125043126 8.python打包exe:https://www.cnblogs.com/strides/p/16422602.html '''from email.mime import image from functools import partial from PIL import Image import wx import os import plistlibAPP_TITLE = "TexturePacker分解工具" APP_ICON = "" SPLITY_TYPE = "COCOS"# 這里是窗口類 class MainFrame(wx.Frame):__plistPath = None__imgPath = None__savePath = None__saveDir = None# 分解類型,根據TexturePacker導出的引擎定義對于的函數, 注意這里的函數名不能加上前面下劃線,否則無法調用__splitFuncDict = {'COCOS':'SplitImage_Cocos',}# 初始化窗口顯示界面def __init__(self):'''初始化,這里使用默認的樣式默認style是下列項的組合:wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN 但是不需要改變窗口的大小,所以加上 ^ wx.RESIZE_BORDER'''wx.Frame.__init__(self, None, style = wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)# 設置標題,背景色,大小,居中顯示self.SetTitle(APP_TITLE)self.SetBackgroundColour(wx.Colour(224, 224, 224))self.SetSize((450, 220))self.Center()# 創建一個Panel,存放控件panel = wx.Panel(self)# plist文件獲取# 固定文本顯示:label:文本內容,pos:在panel內的位置(x, y)wx.StaticText(panel, label = "Plist文件:", pos = (20, 20))# 文本框,size:控件大小(w, h),-1表示默認大小self.plistTxtBox = wx.TextCtrl(panel, pos = (80, 20), size = (250, -1))# 按鈕plistBtn = wx.Button(panel, label = "獲取", pos = (340, 20))# 綁定點擊事件,使用控件的Bind接口(事件類型,回調函數,對象),partial接口用于給回調事件中傳入額外的參數,可以用于判斷是哪個按鈕的回調plistBtn.Bind(wx.EVT_BUTTON, partial(self.OnSelectBtnClick, bPlist = True))# 圖片獲取wx.StaticText(panel, label = "圖片文件:", pos = (20, 60))self.imgTxtBox = wx.TextCtrl(panel, pos = (80, 60), size = (250, -1))imgBtn = wx.Button(panel, label = "獲取", pos = (340, 60))imgBtn.Bind(wx.EVT_BUTTON, partial(self.OnSelectBtnClick, bPlist = False))# 分解保存路徑wx.StaticText(panel, label = "保存地址:", pos = (20, 100))self.saveTxtBox = wx.TextCtrl(panel, pos = (80, 100), size = (250, -1))saveBtn = wx.Button(panel, label = "保存", pos = (340, 100))saveBtn.Bind(wx.EVT_BUTTON, self.OnSaveBtnClick, saveBtn)# 分解圖片splitBtn = wx.Button(panel, label = "分解", pos = (50, 140))splitBtn.Bind(wx.EVT_BUTTON, self.OnSplitBtnClick, splitBtn)# 選擇文件路徑按鈕點擊事件,用于獲取Plist、png文件路徑def OnSelectBtnClick(self, evt, bPlist):fileWildCard = "" # 篩選文件類型:描述|*.后綴|下一組...titleTips = "" # 文件瀏覽器的標題if bPlist :fileWildCard = "Plist files(*.plist)|*.plist|All files(*.*)|*.*" titleTips = "請選擇plist文件"else:fileWildCard = "PNG files(*.png)|*.png|All files(*.*)|*.*" titleTips = "請選擇圖片文件"# 通過 wx.FileDialog 打開文件瀏覽器,并選擇對應的文件, defaultDir:起始路徑fd = wx.FileDialog(self, titleTips, defaultDir = os.getcwd(), wildcard = fileWildCard) # 用戶確認后的操作,這一步必須寫上,不然彈窗無法正常打開,如果用戶取消則該值 = wx.ID_CANCELif fd.ShowModal() == wx.ID_OK :filePath = fd.GetPath()os.chdir(os.path.dirname(filePath))if bPlist :self.__plistPath = filePathself.plistTxtBox.write(self.__plistPath)else:self.__imgPath = filePathself.imgTxtBox.write(self.__imgPath) # 用完就關了fd.Destroy()# 保存路徑按鈕點擊事件def OnSaveBtnClick(self, evt):fd = wx.DirDialog(self, "請選擇保存文件夾", defaultPath = os.getcwd())if fd.ShowModal() == wx.ID_OK :self.__savePath = fd.GetPath()self.saveTxtBox.write(self.__savePath)fd.Destroy()# 分解按鈕點擊事件def OnSplitBtnClick(self, evt):if self.__plistPath == None or not os.path.exists(self.__plistPath) :wx.MessageBox("請指定有效的Plist文件!", "警告", style = wx.OK)returnif self.__imgPath == None or not os.path.exists(self.__imgPath) :wx.MessageBox("請指定有效的圖片文件!", "警告", style = wx.OK)returnif self.__savePath == None or not os.path.exists(self.__savePath) :wx.MessageBox("請指定有效的保存路徑!", "警告", style = wx.OK)return'''1.讀取plist文件內容,并轉換為python數據結構2.遍歷碎圖數據,對大圖進行裁剪3.將小圖生成到指定的路徑'''self.__InitPlistData()# 初始化Plist文件數據def __InitPlistData(self):funcStr = self.__splitFuncDict.get(SPLITY_TYPE, 'Defuault')if funcStr == 'Defuault' :wx.MessageBox(f"沒有{SPLITY_TYPE}對應的分解處理接口", "警告", style = wx.OK)return'''with open(文件路徑,打開方式:r只讀/w只寫/a追加) as 文件對象r: 以只讀方式打開文件。文件的指針將會放在文件的開頭。這是**默認模式**。rb: 以二進制格式打開一個文件用于只讀。文件指針將會放在文件的開頭。這是默認模式。r+: 打開一個文件用于讀寫。文件指針將會放在文件的開頭。rb+:以二進制格式打開一個文件用于讀寫。文件指針將會放在文件的開頭。w: 打開一個文件只用于寫入。如果該文件已存在則將其覆蓋。如果該文件不存在,創建新文件。wb: 以二進制格式打開一個文件只用于寫入。如果該文件已存在則將其覆蓋。如果該文件不存在,創建新文件。w+: 打開一個文件用于讀寫。如果該文件已存在則將其覆蓋。如果該文件不存在,創建新文件。wb+:以二進制格式打開一個文件用于讀寫。如果該文件已存在則將其覆蓋。如果該文件不存在,創建新文件。a: 打開一個文件用于追加。如果該文件已存在,文件指針將會放在文件的結尾。也就是說,新的內容將會被寫入到已有內容之后。如果該文件不存在,創建新文件進行寫入。ab: 以二進制格式打開一個文件用于追加。如果該文件已存在,文件指針將會放在文件的結尾。也就是說,新的內容將會被寫入到已有內容之后。如果該文件不存在,創建新文件進行寫入。a+: 打開一個文件用于讀寫。如果該文件已存在,文件指針將會放在文件的結尾。文件打開時會是追加模式。如果該文件不存在,創建新文件用于讀寫。ab+:以二進制格式打開一個文件用于追加。如果該文件已存在,文件指針將會放在文件的結尾。如果該文件不存在,創建新文件用于讀寫。'''with open(self.__plistPath, "rb") as fp:# 解析Plist文件plistDict = plistlib.load(fp)if plistDict == None :wx.MessageBox("Plist解析失敗", "錯誤", style = wx.OK)return# 獲取圖片名稱,并根據圖片名稱創建文件夾存儲小圖imgName = plistDict['metadata']['realTextureFileName']self.__saveDir = os.path.join(self.__savePath, imgName.replace(".png", "")) # 把后綴去掉,然后組合一下碎圖的保存路徑if not os.path.isdir(self.__saveDir) : # 判斷有沒有該目錄,沒有就創建os.mkdir(self.__saveDir) # 創建目錄# 打開圖片對象srcImage = Image.open(self.__imgPath)# 開始分解,getattr(self, xxx):相當于 self.xxxfunc = getattr(self, funcStr)func(plistDict['frames'], srcImage)# Cocos版本的分解接口def SplitImage_Cocos(self, imgsDic, srcImage):'''大圖中的原點是在左上角,右為x正軸,下為y正軸frame:小圖在大圖中的位置大小(這里是經過Trim去掉空白之后的):{x,y},{w,h}offset:小圖經過Trim之后的中心點與原小圖的中心點的偏移值,注意這里的坐標系是:右為x正軸,上為y正軸rotated:是否旋轉了90°sourceColorRect:原小圖經過Trim之后在原圖中的位置大小:{x,y},{w,h}sourceSize:原圖大小'''# 將json格式的數據轉換成數組json2List = lambda x : x.replace('{', '').replace('}', '').split(',')for key, value in imgsDic.items() :# 獲取裁剪的位置大小:[x,y,w,h]cutRect = []valueFrame = json2List(value['frame'])frameList = [int(valueFrame[0]), int(valueFrame[1]), int(valueFrame[2]), int(valueFrame[3])]if value['rotated'] == True :cutRect = [frameList[0], frameList[1], frameList[0] + frameList[3], frameList[1] + frameList[2],]else:cutRect = [frameList[0], frameList[1], frameList[0] + frameList[2], frameList[1] + frameList[3],]# 原始的圖片大小[w,h]valueSourceSize = json2List(value['sourceSize'])sourceSizeList = [int(valueSourceSize[0]), int(valueSourceSize[1])]# 獲取偏移值: [x,y]'''首先大圖里的小圖是有可能對原圖裁剪后的,所以如果要放回原圖中的話,需要用(原圖的大小 - 裁剪后的圖的大小)/ 2,得到一個偏移值小圖在原圖的位置應該從原點(0,0),即左上角做一個偏移再加上中心點的偏移值就是最終的位置,注意這里因為坐標系問題,y軸應該是減法寬高 = 位置 + 大小'''valueOffset = json2List(value['offset'])offsetList = [int(valueOffset[0]), int(valueOffset[1])]adjust_x = int((sourceSizeList[0] - frameList[2]) / 2)adjust_y = int((sourceSizeList[1] - frameList[3]) / 2)order_x = adjust_x + offsetList[0]order_y = adjust_y - offsetList[1]orderRect = [order_x, order_y, order_x + frameList[2], order_y + frameList[3],]# 存儲位置subImgPath = ""if key.endswith('.png') :subImgPath = os.path.join(self.__saveDir, key)else:subImgPath = os.path.join(self.__saveDir, key + ".png")self.GenerateImage(srcImage, cutRect, orderRect, subImgPath)# 創建小圖并保存def GenerateImage(self, srcImage, cutRect, orderRect, orderPath):subImage = srcImage.crop(cutRect)orderImage = Image.new("RGBA", [orderRect[2], orderRect[3]])orderImage.paste(subImage, orderRect)orderImage.save(orderPath)# 這里是程序類 class MainApp(wx.App):def OnInit(self):self.SetAppName(APP_TITLE)self.frame = MainFrame()self.frame.Show()return True# 啟動應用程序 if __name__ == "__main__":app = MainApp()app.MainLoop()

本人新學Python,有什么不對的地方,歡迎各位大佬指正~~?

總結

以上是生活随笔為你收集整理的工具 - 分解TexturePacker导出的大图的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。