Scanline: turning a phone camera into a searchable photo scanner
Phone-scan-to-searchable-library for physical photographs. Perspective correction, face clustering, duplicate detection by perceptual hash, full-text search, and AI vision tagging — a shoebox of prints in, a searchable library out.
Scanline is FSA-003 in the Full Stack Assets catalog: a browser-based pipeline that turns an ordinary phone camera into a photo scanner, then goes further than any scanner does on its own — cleaning up what it captures, figuring out who's in it, catching the copies you didn't mean to take, and describing it well enough that it's actually searchable a decade later.
The problem
Most family archives are still physical. Decades of prints sit in shoeboxes, albums, and drawers, and "digitizing" them tends to mean one of two things: pay a scanning service by the box and wait weeks for a hard drive back, or point a phone camera at each print and snap a photo of a photo. The second option is what most people actually do, and it's the worse of the two — the print is rarely dead flat, so the shot comes out keystoned and slightly warped; glare off the glossy surface blows out a corner; and the result lands in a camera roll as an untagged, unsearchable JPEG indistinguishable from a thousand other photos. Nothing about the process makes the archive easier to search later — it just moves the shoebox from a physical drawer to a digital one.
The real cost isn't the scanning itself, it's what happens after: nobody can find "the photo of Dad's boat" six months later, because nothing about the file says that's what it is.
The approach
Scanline treats the phone camera as the front end of a real scanning pipeline, not a substitute for one. Everything that can happen client-side, happens client-side:
- Perspective correction —
OpenCV.jsdetects the edges of the photographed print and squares it off, correcting the keystone warp that comes from shooting a flat print at an angle, along with basic glare and quality cleanup, entirely in the browser. - Face clustering —
face-api.jsgroups faces across the whole library, so "who is this" becomes a filter you click instead of a memory test you fail. - Duplicate detection — a perceptual hash fingerprints every scan, so the same print re-photographed from three slightly different angles gets caught and merged instead of cluttering the library as three separate photos.
- AI vision tagging — Claude Vision is wired in end-to-end to auto-tag scene content, estimate a rough era or context for the photo, and generate a searchable description, so full-text search works on a scan the same way it works on a modern digital photo.
The result is that a scan isn't just a picture of a picture — it's a corrected, deduplicated, face-indexed, described record that a full-text search can actually find.
Architecture
Scanline is a deliberately single-file, client-heavy React build — over 2,300 lines. That's a conscious choice, not a shortcut: for a fundamentally personal-scale tool, having the entire pipeline auditable in one place beats scattering capture, correction, hashing, clustering, tagging, and indexing across a microservice mesh built for a scale this tool will never hit.
Correction, hashing, and clustering all run locally against the image data already in the browser, which keeps the pipeline fast and keeps raw photos off a server by default. The one stage that leaves the browser is tagging, where Claude Vision is called to describe and contextualize the corrected image — the single point in the pipeline where an outside model does the heavy lifting.
Results
Scanline is an MVP, not a benchmarked product — the numbers below describe what shipped, not a performance claim against a baseline.
Lessons learned
The stage I underrated going in was dedup. It seemed like a minor cleanup step compared to face clustering or AI tagging — until real use made it obvious that people don't scan a print once. They scan it, check the result, don't love the angle or the glare, and scan it again. Sometimes three or four times before they're satisfied. Without the perceptual-hash dedup step, the library doesn't just get bigger, it gets worse to search: a query for "the photo of Dad's boat" returns four near-identical crops of the same print instead of one clean result. Catching those duplicates before they hit the index turned out to matter more for search quality than any of the AI tagging on top of it — a reminder that the unglamorous cleanup stage is often the one holding the rest of the pipeline together.
Related case studies
Interested in licensing or acquiring Scanline?
The full pipeline and build are available for technical review.