I did this once already for audio. Transcripts turned hundreds of hours of recordings into something you could search — type a phrase, jump straight to the moment. This time the black box wasn’t audio. It was paper.

We have a set of printed booklets — a sermon series, scanned page by page from the original book. The content is good. The problem is the same problem the audio had before transcription: you remember there’s a page about a certain verse, but not which of the hundred-plus pages it’s on. A scanned book is just a folder of JPGs. You can look at every page, one at a time, or you can give up and guess.

I wanted the same thing I built for the recordings: type a word, find every page that has it.

The Proof: Ctrl+F on a Scanned Book

The output is two kinds of PDF, both searchable:

  • One file per chapter, so you can print or share just the part you need.
  • One file with the whole book, so you can search across all of it at once.

Open either one, hit Ctrl+F, type a phrase, and it jumps to the page — even though every page is really just a photograph of a printed page. The image looks exactly like the original scan. There’s an invisible layer of text sitting behind it that your PDF reader searches.

The Story: Why This Needed to Exist

These are sermon booklets my family scans and prints for personal study and for sharing at church. Up to now, “find the page about X” meant flipping through a hundred pages by hand, in a stack that keeps growing every time a new book gets scanned. It’s the exact shape of problem I’d already solved once for audio — a good archive that nobody could actually search. I just hadn’t gotten around to the paper version yet.

The How: OCR, But Skip the Slow Part First

The tool is Tesseract, running entirely on my own PC. No cloud API, no per-page cost. Total cost: $0.

The books are scanned at 300dpi, one JPG per page, a few hundred pages per book. Running full OCR on every page just to find where each chapter starts would work, but it’s slow, and I didn’t need the whole page — I only needed to know where the chapters change.

Step 1 — find chapter boundaries by reading only the header. Every page in these books has a small header printed at the top: the chapter number and page number. So instead of OCR-ing the whole page, I crop just the top strip (roughly the top 3–12% of the image height), scale that sliver up 3x, convert it to grayscale, and run Tesseract only on that crop (--psm 6 -l kor). That’s a tiny image, so it’s fast, and the header text is usually short and clean enough to read reliably. Scanning just the headers across a few hundred pages told me exactly where each chapter starts, in a fraction of the time full-page OCR would have taken.

Step 2 — check the boundaries by eye. Header OCR gets you close, but I don’t trust it blindly. I opened the actual page images at each detected chapter start and confirmed by eye that it really was a title page. Then I added up the page counts per chapter and checked the total matched the number of scanned images — a cheap sanity check that catches an off-by-one before it turns into a badly split PDF.

Step 3 — OCR each page for real, and keep the image. Once I knew the chapter boundaries, I ran Tesseract properly on every page, in a mode that outputs a PDF: the original scanned image, unchanged, with an invisible text layer laid on top (tesseract page.jpg out -l kor --psm 6 pdf). This is what makes the PDF searchable without changing how it looks — you’re still looking at the real scan.

Step 4 — merge. With one small PDF per page, pypdf stitches them into the final files: one per chapter, and one for the whole book.

A Windows Gotcha That Cost Me Some Time

Printing the OCR’d Korean text straight to the console to check it came out as garbled mojibake. The text itself was fine — this was just Windows console encoding being unable to display it. Writing it to a file and reading the file back showed the real, correct text.

🗂 Claude.md Rule Don’t debug Korean OCR output by printing to the Windows console — it mangles the display even when the underlying text is correct UTF-8. Save to a file and read the file to check the actual content.

The Honest Limit

Tesseract’s Korean OCR isn’t perfect on an older typeface — you’ll get the occasional dropped space or misread character. It’s good enough to search by; it’s not good enough to trust as a clean text export. I tell everyone who uses these PDFs that up front.


Key Takeaways

  • A scanned book has the same “you know it’s in there somewhere” problem an untranscribed audio archive has.
  • OCR turns a scanned page into a searchable page without changing how it looks — the image stays the same, a text layer sits underneath it.
  • Reading just the page header first (a small cropped, upscaled strip) finds chapter boundaries far faster than OCR-ing every full page.
  • Always sanity-check automated boundary detection against the real page count before trusting it.
  • Total cost: $0 — Tesseract, Pillow, and pypdf all run locally.