#!/usr/bin/env python3 """Generate the derivative images the site serves in-page. Three outputs, all derived from the existing PNGs: 1. `public/banners/.webp` article banner, q78 (~42% of the PNG) 2. `public/og/thumb/-800.webp` list thumbnail @2x, q72 3. `public/og/thumb/-400.webp` list thumbnail @1x, q72 Why not JPEG anywhere: this art is flat terminal-style with sharp text edges, and it measured *larger* as JPEG q85 than as PNG (129%); WebP came out at 42%. The PNGs stay the source of truth for `og:image` (social scrapers do not reliably render WebP share cards), and the banner PNG doubles as the fallback. Usage: uv run --with pillow python scripts/optimize-images.py # everything uv run --with pillow python scripts/optimize-images.py ... # one post """ import glob, os, sys from PIL import Image ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BANNERS = os.path.join(ROOT, "public", "banners") OG = os.path.join(ROOT, "public", "og") THUMBS = os.path.join(OG, "thumb") BANNER_Q = 78 THUMB_Q = 72 def save_webp(im, path, quality): os.makedirs(os.path.dirname(path), exist_ok=True) if im.mode not in ("RGB", "RGBA"): im = im.convert("RGBA" if "A" in im.mode else "RGB") im.save(path, "WEBP", quality=quality, method=6) return os.path.getsize(path) def banner(slug): png = os.path.join(BANNERS, slug + ".png") if not os.path.exists(png): return None return os.path.getsize(png), save_webp(Image.open(png), png[:-4] + ".webp", BANNER_Q) def thumbs(slug): png = os.path.join(OG, slug + ".png") if not os.path.exists(png): return None im = Image.open(png) src = os.path.getsize(png) out = [] for w in (400, 800): h = round(w * 630 / 1200) out.append(save_webp(im.resize((w, h), Image.LANCZOS), os.path.join(THUMBS, f"{slug}-{w}.webp"), THUMB_Q)) return src, out targets = sys.argv[1:] slugs = targets or sorted(os.path.basename(p)[:-4] for p in glob.glob(os.path.join(OG, "*.png")) if not p.endswith("og-default.png")) b_png = b_webp = 0 t_png = t_400 = t_800 = 0 for s in slugs: b = banner(s) if b: b_png += b[0]; b_webp += b[1] t = thumbs(s) if t: t_png += t[0]; t_400 += t[1][0]; t_800 += t[1][1] n = max(1, len(slugs)) print(f"banners : {len(slugs)} files {b_png/1024/1024:.2f} MB PNG -> {b_webp/1024/1024:.2f} MB WebP " f"({100*b_webp/max(1,b_png):.0f}%) [{b_webp/n/1024:.1f} KB/file]") print(f"thumbs : 400w {t_400/1024:.0f} KB ({t_400/n/1024:.1f} KB/file) + 800w " f"{t_800/1024:.0f} KB ({t_800/n/1024:.1f} KB/file) vs PNG {t_png/1024/1024:.2f} MB " f"({100*(t_400+t_800)/max(1,t_png):.0f}% of PNG)")