Claimed floors back to fitted flagstones in the masters' colours with damage; high-res floor decals

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-07 22:11:41 +01:00
1 parent 362f4e7670
commit ca8494aea0
51 files changed
+154 -39

No files matched your search

+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Turn a generated decal (a picture on a flat magenta background) into a transparent tile for
the high-res atlas: magenta keyed out, scaled down without magenta fringes (premultiplied), the
alpha made hard (pixels are either there or not, like the rest of the pixel art).
Usage:
make_decal.py raw.png out_prefix --size 128 [--gray]
--gray neutral grey (a dark crack whose lines took on the magenta of the background)
Writes out_prefix-<size>.png and out_prefix-<size>-preview.png (on a grey floor, scaled up 3x).
Needs Pillow.
"""
import argparse
from PIL import Image
def main():
ap = argparse.ArgumentParser()
ap.add_argument("raw")
ap.add_argument("out")
ap.add_argument("--size", type=int, default=128)
ap.add_argument("--gray", action="store_true")
a = ap.parse_args()
img = Image.open(a.raw).convert("RGBA")
px = img.load()
for y in range(img.height):
for x in range(img.width):
r, g, b, _ = px[x, y]
if r > g + 40 and b > g + 40:
px[x, y] = (0, 0, 0, 0)
# premultiplied scaling: transparent pixels add nothing to the colour
small = img.resize((a.size, a.size), Image.BOX)
sp = small.load()
for y in range(a.size):
for x in range(a.size):
r, g, b, al = sp[x, y]
if al < 110:
sp[x, y] = (0, 0, 0, 0)
else:
k = 255 / al
c = (min(255, int(r * k)), min(255, int(g * k)), min(255, int(b * k)))
if a.gray:
v = min(c) * 0.9
c = (int(v), int(v), int(v * 1.05))
sp[x, y] = c + (255,)
# Pillow's BOX filter works on straight alpha; transparent pixels were black, so colours near
# the edges come out darker, which suits the dark outlines
small.save(f"{a.out}-{a.size}.png")
prev = Image.new("RGBA", (a.size, a.size), (90, 86, 84, 255))
prev.alpha_composite(small)
prev.resize((a.size * 3, a.size * 3), Image.NEAREST).save(f"{a.out}-{a.size}-preview.png")
print(f"{a.out}-{a.size}.png")
if __name__ == "__main__":
main()