Path: blob/master/src/engine/spritesheetutils.py
254 views
import xml.etree.ElementTree as ET1from engine.imgutils import pad_img2from utils import spritesheet_split_cache3from spriteframe import SpriteFrame4from PIL import Image56def get_true_frame(img , framex, framey, framew, frameh, flipx=False, flipy=False):7# if framex < 0, we pad, else we crop8final_frame = img9if framex < 0:10final_frame = pad_img(final_frame, False, 0, 0, 0, -framex)11else:12final_frame = final_frame.crop((framex, 0, final_frame.width, final_frame.height))1314# same for framey15if framey < 0:16final_frame = pad_img(final_frame, False, -framey, 0, 0, 0)17else:18final_frame = final_frame.crop((0, framey, final_frame.width, final_frame.height))1920# if framex + framew > img.width, we pad else we crop21if framex + framew > img.width:22final_frame = pad_img(final_frame, False, 0, framex+framew - img.width, 0, 0)23else:24final_frame = final_frame.crop((0, 0, framew, final_frame.height))2526# same for framey + frameh > img.height27if framey + frameh > img.height:28final_frame = pad_img(final_frame, False, 0, 0, framey + frameh - img.height, 0)29else:30final_frame = final_frame.crop((0, 0, final_frame.width, frameh))3132return final_frame3334def add_pose_numbers(frame_arr):35pose_arr = [ frame.data.pose_name for frame in frame_arr ]36unique_poses = list(set(pose_arr))37pose_counts = dict([ (ele, 0) for ele in unique_poses ])38new_pose_arr = list(pose_arr)39for i in range(len(new_pose_arr)):40pose_counts[new_pose_arr[i]] += 141new_pose_arr[i] = new_pose_arr[i] + str(pose_counts[new_pose_arr[i]] - 1).zfill(4)42return new_pose_arr434445def split_spsh(pngpath, xmlpath, udpdatefn):46# spritesheet = Image.open(pngpath)47try:48cleaned_xml = ""49quotepairity = 050with open(xmlpath, 'r', encoding='utf-8') as f:51ch = f.read(1)52while ch and ch != '<':53ch = f.read(1)54cleaned_xml += ch55while True:56ch = f.read(1)57if ch == '"':58quotepairity = 1 - quotepairity59elif (ch == '<' or ch == '>') and quotepairity == 1:60ch = '<' if ch == '<' else '>'61else:62if not ch:63break64cleaned_xml += ch6566xmltree = ET.fromstring(cleaned_xml) # ET.parse(xmlpath)67print("XML cleaned")68except ET.ParseError as e:69print("Error!", str(e))70return []71sprites = []7273root = xmltree # .getroot()74subtextures = root.findall("SubTexture")75# get_true_val = lambda val: int(val) if val else None7677# initialize cache for this spritesheet78if not spritesheet_split_cache.get(pngpath):79spritesheet_split_cache[pngpath] = {}8081# debug: current cache82print("Current cache:\n", spritesheet_split_cache)8384for i, subtex in enumerate(subtextures):85tex_x = int(subtex.attrib['x'])86tex_y = int(subtex.attrib['y'])87tex_width = int(subtex.attrib['width'])88tex_height = int(subtex.attrib['height'])89pose_name = subtex.attrib['name']90fx = int(subtex.attrib.get("frameX", 0))91fy = int(subtex.attrib.get("frameY", 0))92fw = int(subtex.attrib.get("frameWidth", tex_width))93fh = int(subtex.attrib.get("frameHeight", tex_height))94# sprite_img = spritesheet.crop((tex_x, tex_y, tex_x+tex_width, tex_y+tex_height)).convert('RGBA')95# sprite_img = sprite_img.convert('RGBA')96# qim = ImageQt(sprite_img)97# sprites.append((sprite_img.toqpixmap(), pose_name, tex_x, tex_y, tex_width, tex_height))98sprites.append(99SpriteFrame(100None, pngpath, False, pose_name,101tx=tex_x, ty=tex_y, tw=tex_width, th=tex_height,102framex=fx, framey=fy, framew=fw, frameh=fh103)104)105udpdatefn((i+1)*50//len(subtextures), pose_name)106107return sprites108109def get_gif_frames(gifpath, updatefn=None):110sprites = []111with Image.open(gifpath) as gif:112for i in range(gif.n_frames):113gif.seek(i)114gif.save("_tmp.png")115sprites.append(SpriteFrame(None, "_tmp.png", True))116if updatefn is not None:117updatefn((i+1)*50//gif.n_frames, f"Adding Frame-{i+1}")118119return sprites120121122