"""Resize the flicker frame PNGs to embeddable JPGs and inject into the HTML report.
Reads flicker_investigation_handover.html, replaces the static "ul.tight" frame
list in Section 1 with an inline gallery of base64-embedded JPGs, and writes
back the same file.
"""
import base64
import sys
from pathlib import Path
from PIL import Image
REPO = Path(__file__).parent
PICS = REPO / "data" / "pics"
HTML = REPO / "flicker_investigation_continued.html"
TMP = REPO / ".embed_tmp"
# (filename, caption)
FRAMES = [
("frame0362.png", "Frame 362 — baseline. Clean image."),
("frame0363.png", "Frame 363 — flicker. Vertical displacement; content recognisable but geometry wrong."),
("frame0370.png", "Frame 370 — flicker. Same vertical shift pattern."),
("frame0376.png", "Frame 376 — flicker. Lower-amplitude shift."),
("frame0381.png", "Frame 381 — flicker (most dramatic). Multi-band tearing; multiple partial frames stacked vertically."),
("frame0382.png", "Frame 382 — flicker. Frame after the dramatic shift; partial recovery still showing artifacts."),
]
def resize_to_jpg(src: Path, dst: Path, width: int = 800, quality: int = 75) -> None:
"""Resize src to width px and write as JPG at given quality, via Pillow."""
img = Image.open(src)
if img.mode != "RGB":
img = img.convert("RGB")
w, h = img.size
if w > width:
new_h = int(h * width / w)
img = img.resize((width, new_h), Image.LANCZOS)
img.save(dst, "JPEG", quality=quality, optimize=True)
def main() -> int:
if not HTML.exists():
print(f"missing {HTML}", file=sys.stderr); return 1
TMP.mkdir(exist_ok=True)
blocks = []
for fname, caption in FRAMES:
src = PICS / fname
if not src.exists():
print(f"skip (missing): {src}"); continue
dst = TMP / (src.stem + ".jpg")
resize_to_jpg(src, dst)
b64 = base64.b64encode(dst.read_bytes()).decode("ascii")
kb = len(b64) * 3 // 4 // 1024
blocks.append(
f'\n'
f'