#!/usr/bin/env python3 """One-off: generate additional sprites without re-running the whole batch. Usage: python3 tools/mb_add.py (edit NEW below per run)""" import json, pathlib, sys sys.path.insert(0, str(pathlib.Path(__file__).parent)) from mb_gen import ROOT, STYLE, flux_spec, run_batch, upload, beat NEW = [ ("dumb_switch", "a small cheap plastic 5-port ethernet switch with green blinking LEDs and a few patch cables"), ("managed_switch", "a professional 1U rackmount managed network switch with many ports and orange status LEDs"), ("ssd_shoebox", "an old shoebox overflowing with loose SATA SSDs and tangled cables"), ("nvme_hoard", "a small stack of NVMe M.2 drives in an open anti-static tray next to a drive dock"), ("nas_tower", "a black tower NAS storage server with six visible drive bays, one bay open"), ("gpu_budget", "a single old dusty budget graphics card with one small fan, product photo style"), ("gpu_gaming", "a chunky three-fan RGB gaming graphics card, product photo style"), ("gpu_workstation", "a sleek blower-style professional workstation graphics card, product photo style"), ("gpu_datacenter", "a gold-and-black datacenter AI accelerator card with no fans and huge heatsink, product photo style"), ] gen = ROOT / "public/assets/gen" raw = run_batch([flux_spec(n, STYLE + d, 768, 768) for n, d in NEW], gen) beat("bg removal for new sprites") cuts = run_batch( [(f"{n}_cut", "bg_remove_local", upload(gen / f"{n}.png"), {"resolution": 1024, "background": "transparent"}) for n, _ in NEW], gen) # autocrop like the main pipeline from PIL import Image for n, _ in NEW: p = gen / f"{n}_cut.png" im = Image.open(p).convert("RGBA") bbox = im.split()[-1].getbbox() if bbox: l, t, r, b = bbox im.crop((max(0, l - 8), max(0, t - 8), min(im.width, r + 8), min(im.height, b + 8))).save(p) mpath = ROOT / "tools/mb_manifest.json" m = json.loads(mpath.read_text()) m.update(raw); m.update(cuts) mpath.write_text(json.dumps(m, indent=2)) beat(f"added {list(raw)} + cuts")