#!/usr/bin/env python3 # Raw portraits (1024x1024) -> 128x128 pixel-art portraits (box downscale, 48 colours, no # dithering, opaque) and the atlas assets/portraits/portraits.png (8 columns) + order.txt. import os, sys from PIL import Image, ImageEnhance sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from portraits import CREATURES ROOT = "/home/zink/Projects/dungeoncraft" D = f"{ROOT}/art/generated/portraits" OUT = f"{ROOT}/assets/portraits" SIZE, COLORS, COLS = 128, 48, 8 CROP = {} # id -> (l, t, r, b) fractions, default the whole picture os.makedirs(OUT, exist_ok=True) rows = (len(CREATURES) + COLS - 1) // COLS atlas = Image.new("RGB", (COLS * SIZE, rows * SIZE), (0, 0, 0)) order = [] for i, c in enumerate(CREATURES): im = Image.open(f"{D}/{c['id']}-raw.png").convert("RGB") l, t, r, b = CROP.get(c["id"], (0, 0, 1, 1)) w, h = im.size im = im.crop((round(l * w), round(t * h), round(r * w), round(b * h))) im = im.resize((SIZE, SIZE), Image.BOX) im = ImageEnhance.Sharpness(im).enhance(1.6) im = im.quantize(colors=COLORS, method=Image.Quantize.MAXCOVERAGE, kmeans=4, dither=Image.Dither.NONE).convert("RGB") im.save(f"{D}/{c['id']}-{SIZE}.png", optimize=True) atlas.paste(im, ((i % COLS) * SIZE, (i // COLS) * SIZE)) order.append(c["kind"]) atlas.save(f"{OUT}/portraits.png", optimize=True) open(f"{OUT}/order.txt", "w").write("\n".join(order) + "\n") print(atlas.size, os.path.getsize(f"{OUT}/portraits.png"), "bytes")