-
-
Save xyzz/fbb344f4c2e9bba1ad12215a72db5035 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# based on https://github.com/xdanieldzd/Scarlet/blob/master/Scarlet.IO.ImageFormats/SHTXFS.cs | |
import datetime | |
from sys import argv, exit | |
from PIL import Image | |
def log(s): | |
print("[{}] {}".format(datetime.datetime.now(), s)) | |
def shtx_to_png(in_path, out_path): | |
fin = open(in_path, "rb") | |
tag = fin.read(6) | |
width = int.from_bytes(fin.read(2), byteorder="little") | |
height = int.from_bytes(fin.read(2), byteorder="little") | |
unk = fin.read(2) | |
log("Converting...") | |
palette = [] | |
for x in range(256): | |
palette.append(int.from_bytes(fin.read(4), byteorder="little")) | |
im = Image.new("RGBA", (width, height)) | |
pixels = im.load() | |
for y in range(height): | |
for x in range(width): | |
pixel = palette[ord(fin.read(1))] | |
pixels[(x, y)] = (pixel & 0xFF, (pixel & 0xFF00) >> 8, (pixel & 0xFF0000) >> 16, (pixel & 0xFF000000) >> 24) | |
fin.close() | |
im.save(out_path) | |
log("Saved {}".format(out_path)) | |
def png_to_shtx(orig_path, in_path, out_path): | |
fin = open(orig_path, "rb") | |
fin.seek(0xA) | |
magic = fin.read(2) | |
log("Reusing magic 0x{:x}".format(int.from_bytes(magic, byteorder="little"))) | |
fin.close() | |
im = Image.open(in_path) | |
width, height = im.size | |
pixels = im.load() | |
log("Building the palette...") | |
colors = set() | |
for y in range(height): | |
for x in range(width): | |
p = pixels[(x, y)] | |
color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24) | |
colors.add(color) | |
if len(colors) > 256: | |
log("Error: palette is too big. Make sure your image only contains 256 different colors. (Use pngquant)") | |
return -1 | |
color_to_idx = dict() | |
palette = [] | |
for color in colors: | |
color_to_idx[color] = len(palette) | |
palette.append(color) | |
log("Writing the image...") | |
fout = open(out_path, "wb") | |
fout.write(b"SHTXFS") | |
fout.write(width.to_bytes(2, byteorder="little")) | |
fout.write(height.to_bytes(2, byteorder="little")) | |
fout.write(magic) | |
for color in palette: | |
fout.write(color.to_bytes(4, byteorder="little")) | |
for y in range(height): | |
for x in range(width): | |
p = pixels[(x, y)] | |
color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24) | |
fout.write(color_to_idx[color].to_bytes(1, byteorder="little")) | |
fout.close() | |
log("Saved {}".format(out_path)) | |
def main(): | |
if len(argv) == 3: | |
return shtx_to_png(argv[1], argv[2]) | |
elif len(argv) == 4: | |
return png_to_shtx(argv[1], argv[2], argv[3]) | |
else: | |
print("Usage:") | |
print("\tConvert shtx to png:") | |
print("\t\tpython tool.py source.shtx output.png") | |
print("\tConvert png to shtx:") | |
print("\t\tpython tool.py original.shtx source.png output.shtx") | |
return -1 | |
if __name__ == "__main__": | |
exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment