Skip to content

Instantly share code, notes, and snippets.

@cabalex
Last active February 20, 2023 04:59
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cabalex/931885371f20a226e4c6a3391e2d3982 to your computer and use it in GitHub Desktop.
Save cabalex/931885371f20a226e4c6a3391e2d3982 to your computer and use it in GitHub Desktop.
Basic XML unpacker written in Python for usage with textures like FNF's
"""
Python script to extract images from XML/PNG pairs (I've used it for FNF)
Scans the "d" directory for any XML and PNG pairs, and if it finds them, creates a new folder in the "out" directory with the same name as the images
Note that it won't output images in the "d" directory if they have no corresponding XML file
Requires os, PIL, BeautifulSoup, lxml (html reader for BeautifulSoup) and re
"""
# Change this to the game's images folder (the one with the textures and XML files).
d = r"C:\Funkin-master\assets\week7\images"
# Change this to the folder you want the final, separated textures to be outputted.
out = r"C:\funkin-assets-output"
import os
from PIL import Image
from bs4 import BeautifulSoup
import re
print("parsing")
for path, currentDirectory, files in os.walk(d):
for file in files:
if file.endswith(".xml"):
print(f"! found {file}")
namewithoutfile = file.split(".")[0]
try:
os.mkdir(out + "/" + file.split(".")[0])
except:
print(f"Already done {file}, continuing")
continue
wholeimage = Image.open(os.path.join(path, file.replace(".xml", ".png")))
with open(os.path.join(path, file)) as xmldata:
soup = BeautifulSoup(xmldata.read(), "lxml")
allsubtx = soup.find_all("subtexture")
uniquex = []
uniquey = []
for subtx in allsubtx:
name = re.sub(r'[^A-Za-z0-9 _%]+', '', subtx["name"])
left = int(subtx["x"])
top = int(subtx["y"])
if left in uniquex and top in uniquey and uniquey[uniquex.index(left)] == top:
continue
else:
uniquex.append(left)
uniquey.append(top)
right = left + int(subtx["width"])
bottom = top + int(subtx["height"])
subimg = wholeimage.crop((left, top, right, bottom))
try:
subimg.save(f"{out}/{namewithoutfile}/{name}.png")
print(f"> saved {name}.png")
except Exception as e:
print(f"!> error saving {name}.png - {e}")
print("done")
@MythixYt
Copy link

MythixYt commented May 3, 2021

Waht is this for?

@Stunnindude123
Copy link

How do i use it

@SwiftRasin
Copy link

It does not work lol

@SwiftRasin
Copy link

I got python just for this, hmm

@SwiftRasin
Copy link

DUDE THANKS SO MUCH

@SwiftRasin
Copy link

IT WORKS

@swordcube
Copy link

THIS WOULD HAVE BEEN SO USEFUL WHEN I WAS EXTRACTING THE WHOLE ALPHABET FROM FNF

@swordcube
Copy link

bruh i can't install the required things

@imadethisaccountsoicanmakeanissue

fake

@frostzzone
Copy link

Amazing, I got this to work on google colab XD
[Really works]

@BombasticTom
Copy link

I like this code, I've never used re but I watched some tutorials on BeautifulSoup from TechWithTim

@BapiDev
Copy link

BapiDev commented Dec 3, 2021

can someone help me get this to work

@BapiDev
Copy link

BapiDev commented Dec 3, 2021

nevermind, i found out!

@skidxml
Copy link

skidxml commented Dec 3, 2021

how do i install this with colab?

@Juarez2010
Copy link

For anyone that wants to do this with google colab, go here. https://github.com/frostzzone/xml-unpacker

@LilMarz
Copy link

LilMarz commented Mar 4, 2022

still dunno how to do it

@BombasticTom
Copy link

still dunno how to do it

you need to install python 3 (latest version) and additionally install BeautifulSoup4 (pip install beautifulsoup4) and Pillow ( pip install Pillow ) with command prompt

@BombasticTom
Copy link

Also you have to change the output variable out = r"C:\funkin-assets-output" to out = r"YOUR DIRECTORY HERE (CAN'T BE RELATIVE FOLDER POSITION)"

@roaring213
Copy link

how do i run this code?

@Random-Guy-2
Copy link

OMG, THANK YOU SO MUCH! THIS IS WAY EASIER THAN WHAT I WAS DOING (Which Was Opening The Sprite Sheet Into A Image Editor And Then Taking A Screenshot Of EACH AND EVERY FRAME, And Then Importing Them Into Scratch, Cutting Out The BG, And Aligning Them.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment