Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
UncertainProd
GitHub Repository: UncertainProd/FnF-Spritesheet-and-XML-Maker
Path: blob/master/src/engine/spritesheetutils.py
254 views
1
import xml.etree.ElementTree as ET
2
from engine.imgutils import pad_img
3
from utils import spritesheet_split_cache
4
from spriteframe import SpriteFrame
5
from PIL import Image
6
7
def get_true_frame(img , framex, framey, framew, frameh, flipx=False, flipy=False):
8
# if framex < 0, we pad, else we crop
9
final_frame = img
10
if framex < 0:
11
final_frame = pad_img(final_frame, False, 0, 0, 0, -framex)
12
else:
13
final_frame = final_frame.crop((framex, 0, final_frame.width, final_frame.height))
14
15
# same for framey
16
if framey < 0:
17
final_frame = pad_img(final_frame, False, -framey, 0, 0, 0)
18
else:
19
final_frame = final_frame.crop((0, framey, final_frame.width, final_frame.height))
20
21
# if framex + framew > img.width, we pad else we crop
22
if framex + framew > img.width:
23
final_frame = pad_img(final_frame, False, 0, framex+framew - img.width, 0, 0)
24
else:
25
final_frame = final_frame.crop((0, 0, framew, final_frame.height))
26
27
# same for framey + frameh > img.height
28
if framey + frameh > img.height:
29
final_frame = pad_img(final_frame, False, 0, 0, framey + frameh - img.height, 0)
30
else:
31
final_frame = final_frame.crop((0, 0, final_frame.width, frameh))
32
33
return final_frame
34
35
def add_pose_numbers(frame_arr):
36
pose_arr = [ frame.data.pose_name for frame in frame_arr ]
37
unique_poses = list(set(pose_arr))
38
pose_counts = dict([ (ele, 0) for ele in unique_poses ])
39
new_pose_arr = list(pose_arr)
40
for i in range(len(new_pose_arr)):
41
pose_counts[new_pose_arr[i]] += 1
42
new_pose_arr[i] = new_pose_arr[i] + str(pose_counts[new_pose_arr[i]] - 1).zfill(4)
43
return new_pose_arr
44
45
46
def split_spsh(pngpath, xmlpath, udpdatefn):
47
# spritesheet = Image.open(pngpath)
48
try:
49
cleaned_xml = ""
50
quotepairity = 0
51
with open(xmlpath, 'r', encoding='utf-8') as f:
52
ch = f.read(1)
53
while ch and ch != '<':
54
ch = f.read(1)
55
cleaned_xml += ch
56
while True:
57
ch = f.read(1)
58
if ch == '"':
59
quotepairity = 1 - quotepairity
60
elif (ch == '<' or ch == '>') and quotepairity == 1:
61
ch = '&lt;' if ch == '<' else '&gt;'
62
else:
63
if not ch:
64
break
65
cleaned_xml += ch
66
67
xmltree = ET.fromstring(cleaned_xml) # ET.parse(xmlpath)
68
print("XML cleaned")
69
except ET.ParseError as e:
70
print("Error!", str(e))
71
return []
72
sprites = []
73
74
root = xmltree # .getroot()
75
subtextures = root.findall("SubTexture")
76
# get_true_val = lambda val: int(val) if val else None
77
78
# initialize cache for this spritesheet
79
if not spritesheet_split_cache.get(pngpath):
80
spritesheet_split_cache[pngpath] = {}
81
82
# debug: current cache
83
print("Current cache:\n", spritesheet_split_cache)
84
85
for i, subtex in enumerate(subtextures):
86
tex_x = int(subtex.attrib['x'])
87
tex_y = int(subtex.attrib['y'])
88
tex_width = int(subtex.attrib['width'])
89
tex_height = int(subtex.attrib['height'])
90
pose_name = subtex.attrib['name']
91
fx = int(subtex.attrib.get("frameX", 0))
92
fy = int(subtex.attrib.get("frameY", 0))
93
fw = int(subtex.attrib.get("frameWidth", tex_width))
94
fh = int(subtex.attrib.get("frameHeight", tex_height))
95
# sprite_img = spritesheet.crop((tex_x, tex_y, tex_x+tex_width, tex_y+tex_height)).convert('RGBA')
96
# sprite_img = sprite_img.convert('RGBA')
97
# qim = ImageQt(sprite_img)
98
# sprites.append((sprite_img.toqpixmap(), pose_name, tex_x, tex_y, tex_width, tex_height))
99
sprites.append(
100
SpriteFrame(
101
None, pngpath, False, pose_name,
102
tx=tex_x, ty=tex_y, tw=tex_width, th=tex_height,
103
framex=fx, framey=fy, framew=fw, frameh=fh
104
)
105
)
106
udpdatefn((i+1)*50//len(subtextures), pose_name)
107
108
return sprites
109
110
def get_gif_frames(gifpath, updatefn=None):
111
sprites = []
112
with Image.open(gifpath) as gif:
113
for i in range(gif.n_frames):
114
gif.seek(i)
115
gif.save("_tmp.png")
116
sprites.append(SpriteFrame(None, "_tmp.png", True))
117
if updatefn is not None:
118
updatefn((i+1)*50//gif.n_frames, f"Adding Frame-{i+1}")
119
120
return sprites
121
122