#!/usr/bin/env python3 """Save single-row review images from an assembled WhaleTown spritesheet.""" from __future__ import annotations import argparse from pathlib import Path from PIL import Image, ImageDraw, ImageFont def checkerboard(width: int, height: int, tile: int) -> Image.Image: image = Image.new("RGBA", (width, height), (226, 226, 226, 255)) draw = ImageDraw.Draw(image) for y in range(0, height, tile): for x in range(0, width, tile): if (x // tile + y // tile) % 2 == 0: draw.rectangle((x, y, x + tile - 1, y + tile - 1), fill=(248, 248, 248, 255)) return image def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--sheet", type=Path, required=True) parser.add_argument("--direction", default="down") parser.add_argument("--row", type=int, default=0) parser.add_argument("--output", type=Path, required=True) parser.add_argument("--feet-output", type=Path, required=True) args = parser.parse_args() frame_size = 160 columns = 8 row = Image.open(args.sheet).convert("RGBA").crop( (0, args.row * frame_size, columns * frame_size, (args.row + 1) * frame_size) ) font = ImageFont.load_default() scale = 2 label_width = 68 preview = row.resize((row.width * scale, row.height * scale), Image.Resampling.NEAREST) canvas = Image.new("RGB", (label_width + preview.width, preview.height), (246, 247, 250)) plate = checkerboard(preview.width, preview.height, 16) plate.alpha_composite(preview) canvas.paste(plate.convert("RGB"), (label_width, 0)) draw = ImageDraw.Draw(canvas) draw.text((8, preview.height // 2 - 5), args.direction, fill=(28, 32, 36), font=font) for index in range(columns + 1): x = label_width + index * frame_size * scale draw.line((x, 0, x, preview.height), fill=(205, 60, 60), width=1) args.output.parent.mkdir(parents=True, exist_ok=True) canvas.save(args.output) feet_y = round(frame_size * 0.49) feet_scale = 4 feet_height = frame_size - feet_y cell_width = frame_size * feet_scale cell_height = feet_height * feet_scale label_height = 22 feet_canvas = Image.new( "RGB", (label_width + columns * cell_width, label_height + cell_height), (246, 247, 250) ) feet_draw = ImageDraw.Draw(feet_canvas) feet_draw.text((7, label_height + cell_height // 2 - 5), args.direction, fill=(28, 32, 36), font=font) for index in range(columns): feet_draw.text((label_width + index * cell_width + 4, 5), f"F{index + 1}", fill=(72, 76, 82), font=font) cell = row.crop((index * frame_size, feet_y, (index + 1) * frame_size, frame_size)).resize( (cell_width, cell_height), Image.Resampling.NEAREST ) plate = checkerboard(cell_width, cell_height, 20) plate.alpha_composite(cell) x = label_width + index * cell_width feet_canvas.paste(plate.convert("RGB"), (x, label_height)) feet_draw.rectangle( (x, label_height, x + cell_width - 1, label_height + cell_height - 1), outline=(188, 194, 202), width=1, ) feet_canvas.save(args.feet_output) if __name__ == "__main__": main()