Photograph a handwritten daily crew schedule; get the morning crew texts.
Built for one operations manager who writes his schedule by hand on a pre-printed grid form and intends to keep doing that. This does not replace the pen, the paper, or his judgement — it only removes the twenty minutes he spends typing the same information into Messages every morning.
Part 1 complete: capture. Photo in, deskewed and tiled images out. Parsing and message generation are not wired up yet.
| File | |
|---|---|
index.html |
The capture screen. All UI. |
capture.js |
The pipeline: detect → pad → deskew → rotate → tile. No DOM chrome. |
opencv.js |
10.4 MB. Only Canny + HoughLinesP + warpPerspective are actually used. |
sw.js |
Offline shell. Bump CACHE on every deploy. |
manifest.json |
PWA metadata. |
GitHub Pages, served from the repository root.
git add -A && git commit -m "..." && git push
Bump CACHE in sw.js (-v1 → -v2) with every deploy. An installed
phone will otherwise keep serving the old version indefinitely.
Camera in standalone (home-screen) mode. getUserMedia has broken in two
consecutive major iOS releases — entirely in 18.0/18.1 (fixed 18.1.1), and on
iOS 26 it returns 90°-rotated video while screen.orientation reports
portrait-primary regardless. The rotation does not matter here: the pipeline
deskews to the detected grid and normalises orientation from the warp aspect
ratio, so it never trusts the browser.
If camera access breaks again, the escape hatch is removing the
apple-mobile-web-app-capable meta tag from index.html. The app then opens
in Safari while still launching from a home-screen icon, and the camera works
normally. The file picker needs no camera API at all and cannot break this way.
Detection needs the printed grid, not the page edge. Sheets get photographed on a stack of other paper. Detection uses Hough line intersection rather than contour finding — the standard document-scanner recipe scored 1/5 on real photos, because handwriting crossing the grid borders breaks the closed contour. Hough scored 5/5.
This repository is public. Schedule photographs contain customer addresses,
names, phone numbers and lockbox codes. Never commit one. Test images live
outside this directory for exactly that reason, and .gitignore is set up to
catch accidents.