ShitboxInfinity/tools/crop_poster.py
m3ultra 1db71420a3 Scenery v4: traffic signals, power lines, local FLUX fallback
Taps the last big unused seam in the OSM data: 140 highway=traffic_signals per
CBD level become pole + mast arm + two lantern heads with emissive lenses.
Timber power poles with catenary-sagging wires run down one side of every
residential street. Billboards now cycle three fictional ad designs.

Cloudflare's free tier (10k neurons/day) ran out mid-session, so flux_texture.sh
now falls back to the local MODELBEAST farm automatically -- transparent, same
output contract. tools/crop_poster.py trims generated billboards to the poster
face by saturation, since FLUX renders them in situ with sky and support pole
however the prompt is worded.

Fixed: signal lenses were built as 0.04 m beams and beam() bails under 0.05 m,
so they silently never existed -- caught by inspecting the exported GLB, not
the screenshot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 17:21:35 +10:00

48 lines
1.6 KiB
Python

#!/usr/bin/env python3
"""Trim a generated billboard down to just its poster face.
Usage: crop_poster.py <image.jpg> [more.jpg ...]
FLUX renders a billboard *in situ* -- sky, support pole, sometimes a wall --
however hard the prompt asks for the poster alone. Mapped onto a flat panel
that bakes sky into the sign. The poster is always the saturated part and the
surroundings are always washed out, so trim rows/columns whose mean saturation
falls below a fraction of the image's peak. Survives regeneration, unlike a
hand-measured crop box.
"""
import sys
from PIL import Image
FLOOR = 0.42 # keep bands at >=42% of peak row/col saturation
MIN_KEEP = 0.35 # never crop away more than 65% of a dimension
def band_keep(profile):
peak = max(profile) or 1
thresh = peak * FLOOR
idx = [i for i, v in enumerate(profile) if v >= thresh]
if not idx:
return 0, len(profile)
lo, hi = idx[0], idx[-1] + 1
if (hi - lo) < len(profile) * MIN_KEEP: # suspiciously tight -> leave it alone
return 0, len(profile)
return lo, hi
def crop(path):
im = Image.open(path).convert("RGB")
sat = im.convert("HSV").split()[1]
w, h = im.size
px = sat.load()
cols = [sum(px[x, y] for y in range(0, h, 4)) for x in range(w)]
rows = [sum(px[x, y] for x in range(0, w, 4)) for y in range(h)]
x0, x1 = band_keep(cols)
y0, y1 = band_keep(rows)
out = im.crop((x0, y0, x1, y1)).resize((w, h), Image.LANCZOS)
out.save(path, quality=90)
print("%s: kept x %d-%d, y %d-%d of %dx%d" % (path.split("/")[-1], x0, x1, y0, y1, w, h))
for p in sys.argv[1:]:
crop(p)