← Home

Talpatra Scan

An offline document scanner for Android, built to scan my son's books, PDFs and notes, and designed so nothing he scans ever leaves the phone.

Built for
My son's books, printed PDFs and handwritten notes, and my own learning of native Android with AI
Time
26 Aug – 26 Sep 2026 (about 1 month, 144 commits)
AI tools
Claude Code with Claude Fable 5 and Sonnet, guided by a living improvement plan and written agent conventions
Stack
Kotlin, Jetpack Compose, Hilt, Room with full-text search, CameraX, OpenCV, ML Kit text recognition, Gradle multi-module

User stories

  • As a student, I want to point my phone at a book page and get a flat, clean scan, so that I can keep my study material on my phone.
  • As a student, I want the page to capture itself when the phone is steady, so that scanning doesn't need two hands.
  • As a student, I want to search the text of my scans and export a searchable PDF, so that I can find things later.
  • As a parent, I want nothing scanned to leave the phone, so that a child's study material stays private.

Situation & constraint

I built Talpatra Scan to help my son turn his books, printed PDFs and handwritten notes into clean, searchable copies. Like my other Labs, it is a learning project: a way to build a complete native Android app with AI. I wanted it private by design, so the app has no internet permission at all, no accounts, no ads and no analytics. The name comes from talpatra, the palm leaf that held India's knowledge for centuries.

Architecture

  • The capture pipeline: live page-boundary detection, an auto-capture state machine that fires when the phone is steady, perspective correction (with page dewarping in Book mode), enhancement, on-device OCR, then a searchable PDF.
  • A multi-module Gradle project: an app shell, core modules (database, storage, UI), and one feature module each for capture, imaging, boundary and dewarp models, OCR, PDF, export and the library.
  • Local storage in Room, with full-text search over the OCR'd text.
  • A no-internet guarantee enforced in the build: the manifest removes the INTERNET permission, and the build fails if a dependency tries to add it back. Anyone can check this from the APK.
  • Image logic is tested as pure JVM unit tests, with a desktop harness for PDF quality.