#!/usr/bin/env python3 """Find where two captures of the same screen differ, in CSS pixels. Capture a screen twice, once with one value changed (a price, a count, a status), then use the box for the template's proof.box so the ring and the callout land exactly on the change. python3 diff-box.py a/phone.png a/phone-after.png --dpr 3 -> image px [1091, 1610, 1115, 1648] css px [364, 537, 8, 13] (x, y, w, h) The box covers only changed pixels (often just the digits that differ), so widen it by hand to the whole value if the ring should frame "$18", not "8". Needs Pillow (pip install pillow). """ import argparse from PIL import Image, ImageChops ap = argparse.ArgumentParser() ap.add_argument("before") ap.add_argument("after") ap.add_argument("--dpr", type=float, default=1.0, help="device pixel ratio the captures were taken at") ap.add_argument("--threshold", type=int, default=40, help="per-channel difference that counts as a change") a = ap.parse_args() before = Image.open(a.before).convert("RGB") after = Image.open(a.after).convert("RGB") if before.size != after.size: h = min(before.height, after.height) print(f"note: sizes differ {before.size} vs {after.size}; comparing the top {h}px") before, after = before.crop((0, 0, before.width, h)), after.crop((0, 0, after.width, h)) mask = ImageChops.difference(before, after).convert("L").point(lambda v: 255 if v > a.threshold else 0) box = mask.getbbox() if not box: raise SystemExit("no difference found") x0, y0, x1, y1 = box css = [round(x0 / a.dpr), round(y0 / a.dpr), round((x1 - x0) / a.dpr), round((y1 - y0) / a.dpr)] print(f"image px {list(box)} css px {css} (x, y, w, h)")