Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2016
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.69 KB | None | 0 0
  1. import os
  2. import plistlib
  3. from PIL import Image
  4.  
  5.  
  6. class Matrix(object):
  7. def __init__(self, src_box, clip_box, offset):
  8. self.src_box = src_box
  9. self.clip_box = clip_box
  10. self.offset = offset
  11. self.src_size = [self.src_box[2] - self.src_box[0], self.src_box[3] - self.src_box[1]]
  12. self.clip_size = [self.clip_box[2] - self.clip_box[0], self.clip_box[3] - self.clip_box[1]]
  13.  
  14.  
  15. class TextureUnpacker(object):
  16. @classmethod
  17. def split_with_plist(cls, plist, save=None):
  18. plist = os.path.abspath(plist)
  19. if save is None:
  20. save = plist + '_split'
  21. else:
  22. save = os.path.abspath(save)
  23.  
  24. dt = plistlib.readPlist(plist)
  25. metadata, frames = dt['metadata'], dt['frames']
  26. format_version = metadata['format']
  27. big_img = Image.open(metadata['realTextureFileName'])
  28. for frame, info in frames.iteritems():
  29. if format_version == 2:
  30. info = cls.parse_as_plist_v2(info)
  31. elif format_version == 3:
  32. info = cls.parse_as_plist_v3(info)
  33. else:
  34. raise Exception('not support version' + str(format_version))
  35. cls.generate_little_image(big_img, info, os.path.join(save, frame))
  36.  
  37. @classmethod
  38. def generate_little_image(cls, big_img, info, path):
  39. little_img = Image.new('RGBA', info['sz'])
  40. region = big_img.crop(info['box'])
  41. if info['rotated']:
  42. # region = region.rotate(90, expand=1)
  43. region = region.transpose(Image.ROTATE_90)
  44. little_img.paste(region, info['xy'])
  45. dir_ = os.path.dirname(path)
  46. if not os.path.exists(dir_):
  47. os.makedirs(dir_)
  48. little_img.save(path)
  49.  
  50. @classmethod
  51. def parse_as_plist_v2(cls, info):
  52. """
  53. {
  54. 'frame': '{{1,1},{430,635}}',
  55. 'offset': '{2,-2}',
  56. 'rotated': False,
  57. 'sourceSize': '{639,639}'
  58. }
  59. """
  60. info['frame'] = cls.__convert_rect(info['frame'])
  61. info['offset'] = cls.__convert_point(info['offset'])
  62. info['sourceSize'] = cls.__convert_point(info['sourceSize'])
  63.  
  64. rotated = info['rotated']
  65. if rotated:
  66. box = (info['frame'][0], info['frame'][1],
  67. info['frame'][0] + info['frame'][3],
  68. info['frame'][1] + info['frame'][2])
  69. else:
  70. box = (info['frame'][0], info['frame'][1],
  71. info['frame'][0] + info['frame'][2],
  72. info['frame'][1] + info['frame'][3])
  73.  
  74. x = info['offset'][0] + (info['sourceSize'][0] - info['frame'][2]) / 2
  75. y = (info['sourceSize'][1] - info['frame'][3]) / 2 - info['offset'][1]
  76.  
  77. return {
  78. 'box': box,
  79. 'rotated': rotated,
  80. 'xy': (x, y),
  81. 'sz': info['sourceSize']
  82. }
  83.  
  84. @classmethod
  85. def parse_as_plist_v3(cls, info):
  86. """
  87. {
  88. 'aliases': [],
  89. 'spriteOffset': '{1,-1}',
  90. 'spriteSize': '{433,637}',
  91. 'spriteSourceSize': '{639,639}',
  92. 'textureRect': '{{1,1},{433,637}}',
  93. 'textureRotated': False
  94. }
  95. """
  96. info['spriteSize'] = cls.__convert_point(info['spriteSize'])
  97. info['spriteOffset'] = cls.__convert_point(info['spriteOffset'])
  98. info['textureRect'] = cls.__convert_rect(info['textureRect'])
  99. info['spriteSourceSize'] = cls.__convert_point(info['spriteSourceSize'])
  100.  
  101. rotated = info['textureRotated']
  102. if rotated:
  103. box = (info['textureRect'][0], info['textureRect'][1],
  104. info['textureRect'][0] + info['textureRect'][3],
  105. info['textureRect'][1] + info['textureRect'][2])
  106. else:
  107. box = (info['textureRect'][0], info['textureRect'][1],
  108. info['textureRect'][0] + info['textureRect'][2],
  109. info['textureRect'][1] + info['textureRect'][3])
  110.  
  111. x = info['spriteOffset'][0] + (info['spriteSourceSize'][0] - info['spriteSize'][0]) / 2
  112. y = (info['spriteSourceSize'][1] - info['spriteSize'][1]) / 2 - info['spriteOffset'][1]
  113.  
  114. return {
  115. 'box': box,
  116. 'rotated': rotated,
  117. 'xy': (x, y),
  118. 'sz': info['spriteSourceSize']
  119. }
  120.  
  121. @classmethod
  122. def __convert_rect(cls, rect):
  123. s = rect.replace('{', '')
  124. s = s.replace('}', '')
  125. x, y, w, h = s.split(',')
  126. return [int(x), int(y), int(w), int(h)]
  127.  
  128. @classmethod
  129. def __convert_point(cls, pt):
  130. s = pt.replace('{', '')
  131. s = s.replace('}', '')
  132. x, y = s.split(',')
  133. return [int(x), int(y)]
  134.  
  135.  
  136. if __name__ == '__main__':
  137. import sys
  138. TextureUnpacker.split_with_plist(sys.argv[1])
  139.  
  140. <plist version="1.0">
  141. <dict>
  142. <key>frames</key>
  143. <dict>
  144. <key>Sprite_ID1212</key>
  145. <dict>
  146. <key>frame</key>
  147. <string>{{0, 0}, {640, 1156}}</string>
  148. <key>offset</key>
  149. <string>{0, -0}</string>
  150. <key>rotated</key>
  151. <string>false</string>
  152. <key>sourceColorRect</key>
  153. <string>{{0, 0}, {640, 1156}}</string>
  154. <key>sourceSize</key>
  155. <string>{640, 1156}</string>
  156. </dict>
  157. <key>Sprite_ID160</key>
  158. <dict>
  159. <key>frame</key>
  160. <string>{{644, 0}, {640, 1156}}</string>
  161. <key>offset</key>
  162. <string>{0, -0}</string>
  163. <key>rotated</key>
  164. <string>false</string>
  165. <key>sourceColorRect</key>
  166. <string>{{0, 0}, {640, 1156}}</string>
  167. <key>sourceSize</key>
  168. <string>{640, 1156}</string>
  169. </dict>
  170. <key>Sprite_ID1113</key>
  171. <dict>
  172. <key>frame</key>
  173. <string>{{1288, 0}, {640, 1156}}</string>
  174. <key>offset</key>
  175. <string>{0, -0}</string>
  176. <key>rotated</key>
  177. <string>false</string>
  178. <key>sourceColorRect</key>
  179. <string>{{0, 0}, {640, 1156}}</string>
  180. <key>sourceSize</key>
  181. <string>{640, 1156}</string>
  182. </dict>
  183. <key>metadata</key>
  184. <dict>
  185. <key>format</key>
  186. <string>2</string>
  187. <key>realTextureFileName</key>
  188. <string>atlas_ID101.png</string>
  189. <key>size</key>
  190. <string>{2048, 2048}</string>
  191. <key>smartupdate</key>
  192. <string>$Potion:Smartupdate:$</string>
  193. <key>textureFileName</key>
  194. <string>atlas_ID101.png</string>
  195. </dict>
  196. </dict>
  197. </plist>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement