Files
aetherbound-guild/tools/build_grid_layout_guide.py

48 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Build a non-production grid placement guide with centered safe envelopes."""
from __future__ import annotations
import argparse
from pathlib import Path
from PIL import Image, ImageDraw
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--rows", type=int, required=True)
parser.add_argument("--cols", type=int, required=True)
parser.add_argument("--width", type=int, required=True)
parser.add_argument("--height", type=int, required=True)
parser.add_argument("--output", type=Path, required=True)
return parser.parse_args()
def main() -> None:
args = parse_args()
if min(args.rows, args.cols, args.width, args.height) < 1:
raise SystemExit("all dimensions must be positive")
image = Image.new("RGB", (args.width, args.height), (0, 255, 0))
draw = ImageDraw.Draw(image)
for row in range(args.rows):
for col in range(args.cols):
left = round(col * args.width / args.cols)
right = round((col + 1) * args.width / args.cols)
top = round(row * args.height / args.rows)
bottom = round((row + 1) * args.height / args.rows)
cell_w, cell_h = right - left, bottom - top
margin_x, margin_y = round(cell_w * 0.23), round(cell_h * 0.23)
box = (left + margin_x, top + margin_y, right - margin_x, bottom - margin_y)
draw.rectangle(box, outline=(42, 48, 60), width=6)
cx, cy = (left + right) // 2, (top + bottom) // 2
draw.line((cx - 18, cy, cx + 18, cy), fill=(240, 240, 232), width=4)
draw.line((cx, cy - 18, cx, cy + 18), fill=(240, 240, 232), width=4)
args.output.parent.mkdir(parents=True, exist_ok=True)
image.save(args.output, optimize=True)
print(f"GRID_LAYOUT_GUIDE_OK cells={args.rows * args.cols} output={args.output}")
if __name__ == "__main__":
main()