#!/usr/bin/env python3 """ optimize_web_resources.py - Resize PNG images for the web build. Copies to /resources/, then downscales all PNG files: - resources/w/ui/img/** -> 1/8 original size - all other PNGs -> 1/4 original size Files listed in EXCEPTIONS are copied unchanged. Usage (manual): python optimize_web_resources.py [--src resources] [--dst web_resources] Usage (CMake): ${Python3_EXECUTABLE} optimize_web_resources.py --src --dst """ import argparse import os import shutil try: from PIL import Image except ImportError: raise SystemExit("Pillow is required: pip install Pillow") # Paths relative to the resources directory — these files are never resized. EXCEPTIONS = { "loading.png", "black.png", } # Path prefixes (relative to resources root, forward-slash) that get 8x reduction. HIGH_REDUCTION_PREFIXES = ( "w/ui/img", ) def _resize_factor(rel: str) -> int: norm = rel.replace("\\", "/") for prefix in HIGH_REDUCTION_PREFIXES: if norm.startswith(prefix): return 8 return 4 def _next_pot(n: int) -> int: if n < 1: return 1 p = 1 while p < n: p <<= 1 return p def optimize(src_dir: str, dst_parent: str) -> None: src_dir = os.path.abspath(src_dir) dst_resources = os.path.join(os.path.abspath(dst_parent), "resources") print(f"Copying {src_dir} -> {dst_resources}") if os.path.exists(dst_resources): shutil.rmtree(dst_resources) shutil.copytree(src_dir, dst_resources) total = 0 for root, _dirs, files in os.walk(dst_resources): for filename in files: if not filename.lower().endswith(".png"): continue full_path = os.path.join(root, filename) rel = os.path.relpath(full_path, dst_resources).replace("\\", "/") if rel in EXCEPTIONS: print(f" skip (exception): {rel}") continue factor = _resize_factor(rel) with Image.open(full_path) as img: orig_w, orig_h = img.size new_w = _next_pot(max(1, orig_w // factor)) new_h = _next_pot(max(1, orig_h // factor)) resized = img.resize((new_w, new_h), Image.LANCZOS) resized.save(full_path) print(f" {rel}: {orig_w}x{orig_h} -> {new_w}x{new_h} (/{factor} + POT)") total += 1 print(f"Done. Resized {total} PNG file(s).") if __name__ == "__main__": parser = argparse.ArgumentParser(description="Optimize PNG images for web build") parser.add_argument("--src", default="resources", help="Source resources directory (default: resources)") parser.add_argument("--dst", default="web_resources", help="Destination parent directory; will contain a 'resources' subdir " "(default: web_resources)") args = parser.parse_args() optimize(args.src, args.dst)