from __future__ import annotations import hashlib import json from pathlib import Path from PIL import Image ROOT = Path(__file__).resolve().parents[2] MANIFEST = ROOT / "design-pipeline/manifests/module-page-backgrounds.json" def sha256(path: Path) -> str: digest = hashlib.sha256() with path.open("rb") as stream: for chunk in iter(lambda: stream.read(1024 * 1024), b""): digest.update(chunk) return digest.hexdigest() def normalize(source: Path, output: Path, width: int, height: int) -> None: with Image.open(source) as image: image = image.convert("RGB") scale = max(width / image.width, height / image.height) resized = image.resize( (round(image.width * scale), round(image.height * scale)), Image.Resampling.LANCZOS, ) left = max(0, (resized.width - width) // 2) top = max(0, (resized.height - height) // 2) normalized = resized.crop((left, top, left + width, top + height)) output.parent.mkdir(parents=True, exist_ok=True) normalized.save(output, format="PNG", optimize=True) def main() -> None: manifest = json.loads(MANIFEST.read_text(encoding="utf-8")) width = int(manifest["width"]) height = int(manifest["height"]) report = [] for item in manifest["backgrounds"]: source = ROOT / item["source"] output = ROOT / item["output"] if not source.is_file(): raise FileNotFoundError(source) normalize(source, output, width, height) report.append( { "module": item["module"], "source": item["source"], "output": item["output"], "size": [width, height], "sha256": sha256(output), } ) print(json.dumps(report, ensure_ascii=False, indent=2)) if __name__ == "__main__": main()