non-256 faceSize fixes

This commit is contained in:
Firq 2024-10-04 19:30:40 +02:00
parent 7dfc5dcefa
commit 4cb46ca102
Signed by: Firq
GPG key ID: 3ACC61C8CEC83C20
3 changed files with 58 additions and 19 deletions

View file

@ -1,6 +1,6 @@
import requests
from .cli import Paths
from .cli import Paths, ExpressionDefaults
def fetch_image(servantid: str, imageid: str):
@ -39,4 +39,9 @@ def fetch_data(servantid: str):
print(response)
data = response.json()
return { str(spritesheet["id"]): (spritesheet["faceX"], spritesheet["faceY"]) for spritesheet in data["mstSvtScript"] }
return {
str(spritesheet["id"]): {
"faceSize": spritesheet["extendData"].get("faceSize", ExpressionDefaults.faceSize),
"position": (spritesheet["faceX"], spritesheet["faceY"])
} for spritesheet in data["mstSvtScript"]
}

View file

@ -36,6 +36,5 @@ class Paths:
if _args.output:
OUTPUT = pathlib.Path(_args.output)
class Expressions:
height = 256
width = 256
class ExpressionDefaults:
faceSize = 256

View file

@ -1,3 +1,4 @@
import math
import pathlib
import sys
@ -6,7 +7,7 @@ from PIL import Image
from tqdm.contrib import itertools as tqdm_itertools
from .atlas import fetch_data, fetch_image
from .cli import Expressions, Paths
from .cli import ExpressionDefaults, Paths
def welcome():
@ -35,10 +36,10 @@ def run():
path = Paths.IMAGES / servantid
for f in path.iterdir():
process_sprite(f, sprites[f.stem], servantid)
process_sprite(f, sprites[f.stem]["position"], sprites[f.stem]["faceSize"], servantid)
print(f"Files have been saved at: {(Paths.OUTPUT / servantid).absolute()}")
def process_sprite(filepath: pathlib.Path, position: tuple, servantid: str):
def process_sprite(filepath: pathlib.Path, position: tuple, faceSize: int, servantid: str):
im = Image.open(filepath)
width, height = im.size
@ -46,13 +47,47 @@ def process_sprite(filepath: pathlib.Path, position: tuple, servantid: str):
save_sprite(main_sprite, servantid, filepath.stem)
expressions = im.crop((0, 768, width, height))
_, expressionheight = expressions.size
rows = expressionheight // Expressions.height
expressionwidth, expressionheight = expressions.size
rows = expressionheight // faceSize
expressions_p_row = expressionwidth // faceSize
for x, y in tqdm_itertools.product(range(0, rows), range(0, 4, 1), ascii="-="):
img = generate_sprite(main_sprite, expressions, x, y, position)
exp_per_row = 4
if faceSize != ExpressionDefaults.faceSize:
w, h = expressions.size
composites = []
per_composite = (1280 - ExpressionDefaults.faceSize) // faceSize
exp_per_row = per_composite
offset = (faceSize * ExpressionDefaults.faceSize) / 1280
composite_count = math.ceil((h - 1280) / (offset + faceSize * per_composite)) + 1
expressions = expressions.crop((0, 256, w, h))
floating_offset = 0
for count in range(0, composite_count + 1):
composites.append((
0,
3 * count * faceSize + floating_offset,
w,
(3 * count + 3) * faceSize + floating_offset - 1
))
floating_offset += offset
overrides = Image.new("RGBA", (w, faceSize * composite_count * 3), (255, 0, 0, 0))
for idx, c in enumerate(composites):
crop = expressions.crop(c)
pos = (
0,
idx * 3 * faceSize,
)
overrides.paste(crop, pos, crop)
expressions = overrides.copy()
for x, y in tqdm_itertools.product(range(0, rows), range(0, expressions_p_row, 1), ascii="-="):
img = generate_sprite(main_sprite, expressions, x, y, position, faceSize)
if img is not None:
save_sprite(img, servantid, filepath.stem, (x, y))
save_sprite(img, servantid, filepath.stem, (x, y, exp_per_row))
def is_empty(img: Image.Image):
data = np.asarray(img.crop((96, 96, 160, 160)).convert('LA'))
@ -62,12 +97,12 @@ def is_empty(img: Image.Image):
return True
return False
def generate_sprite(sprite: Image.Image, expressions: Image.Image, row: int, col: int, position: tuple) -> Image.Image | None:
def generate_sprite(sprite: Image.Image, expressions: Image.Image, row: int, col: int, position: tuple, faceSize: int) -> Image.Image | None:
area = (
col * Expressions.width,
row * Expressions.height,
(col + 1) * Expressions.width - 1,
(row + 1) * Expressions.height - 1
col * faceSize,
row * faceSize,
(col + 1) * faceSize - 1,
(row + 1) * faceSize - 1
)
expression = expressions.crop(area)
@ -82,7 +117,7 @@ def save_sprite(image: Image.Image, folder: str, name: str, rowcol: tuple | None
savefolder = Paths.OUTPUT / folder
if not savefolder.is_dir():
savefolder.mkdir()
postfix = f"_{rowcol[0] * 4 + rowcol[1] + 1}" if rowcol is not None else "_0"
postfix = f"_{rowcol[0] * rowcol[2] + rowcol[1] + 1}" if rowcol is not None else "_0"
outfile = savefolder / f"{name}{postfix}.png"
with open(outfile, 'wb') as file:
image.save(file)