Files
AI_spine/compose_preview.py
T
2026-09-12 13:06:59 +08:00

33 lines
1.4 KiB
Python

#!/usr/bin/env python3
"""Rasterize a Genielabs layout for quick visual QA beside the Spine preview."""
import argparse, json, os
from pathlib import Path
from PIL import Image
def main():
p = argparse.ArgumentParser()
p.add_argument('--reference', required=True)
p.add_argument('--parts', required=True)
p.add_argument('--layout', required=True)
p.add_argument('--output', required=True)
a = p.parse_args()
ref = Image.open(a.reference).convert('RGBA')
layout = json.loads(Path(a.layout).read_text())
canvas = Image.new('RGBA', ref.size, (26, 26, 48, 255))
for name in layout.get('z_order', list(layout.get('parts', {}))):
pos = layout.get('parts', {}).get(name)
if not pos: continue
fp = Path(a.parts) / f'{name}.png'
if not fp.exists(): continue
im = Image.open(fp).convert('RGBA')
w, h = max(1, round(pos.get('width', im.width))), max(1, round(pos.get('height', im.height)))
im = im.resize((w, h), Image.Resampling.LANCZOS)
angle = float(pos.get('rotation', 0) or 0)
if abs(angle) > 0.01: im = im.rotate(-angle, expand=True, resample=Image.Resampling.BICUBIC)
cx = float(pos.get('x', 0)) + float(pos.get('width', w)) / 2
cy = float(pos.get('y', 0)) + float(pos.get('height', h)) / 2
canvas.alpha_composite(im, (round(cx - im.width / 2), round(cy - im.height / 2)))
canvas.save(a.output)
if __name__ == '__main__': main()