"""Build a side-by-side plate from a reference photograph and a rendered capture. python3 Tools/review/hero_compare.py \ --reference Art/reference/hero-masonic/02-masonictemple01.jpg \ --render Screenshots/review/review-hero-facade-front.png \ --out Screenshots/review/hero-compare-front.png Both halves are scaled to the same height and labelled, so the two can be read at a glance instead of flipping between files. Reference photography is git-ignored and never committed; only the plate is. Result: the plate path on stdout. """ import argparse import os from PIL import Image, ImageDraw LABEL_H = 56 TARGET_H = 900 def load_scaled(path, height): image = Image.open(path).convert("RGB") width = int(image.width * height / image.height) return image.resize((width, height), Image.LANCZOS) def main(): parser = argparse.ArgumentParser() parser.add_argument("--reference", required=True) parser.add_argument("--render", required=True) parser.add_argument("--out", required=True) parser.add_argument("--left-label", default="reference") parser.add_argument("--right-label", default="rendered") args = parser.parse_args() left = load_scaled(args.reference, TARGET_H) right = load_scaled(args.render, TARGET_H) gap = 16 width = left.width + right.width + gap * 3 plate = Image.new("RGB", (width, TARGET_H + LABEL_H + gap * 2), (24, 24, 26)) plate.paste(left, (gap, LABEL_H + gap)) plate.paste(right, (gap * 2 + left.width, LABEL_H + gap)) draw = ImageDraw.Draw(plate) draw.text((gap, 18), args.left_label, fill=(235, 235, 235)) draw.text((gap * 2 + left.width, 18), args.right_label, fill=(235, 235, 235)) os.makedirs(os.path.dirname(os.path.abspath(args.out)), exist_ok=True) plate.save(args.out) print(args.out) main()