NAPS2 OCR, tested: why imported PDFs get no text
1,879
of 1,955 words, Fast mode
OCR in NAPS2, in the app or Terminal
16 s for 10 pages, 2 cores
28 MB English models, one download
- In NAPS2, click Tools, then OCR, and download English.
- Check "Make PDFs searchable using OCR".
- Import or scan, then save as PDF. OCR runs as it saves.
Or paste these in Terminal, in the folder with scan.pdf:
alias naps2.console="/Applications/NAPS2.app/Contents/MacOS/NAPS2 console"
naps2.console --install ocr-eng
naps2.console -i "$PWD/scan.pdf" -n 0 -o "$PWD/book.pdf" --ocrlang eng -f
The alias comes from the NAPS2 docs. book.pdf has the words hidden behind each page.
Use full paths, or nothing happens
On a Mac, NAPS2 looks for a short path like scan.pdf inside NAPS2.app. I got these two errors:
Error importing file. Path: scan.pdf
You don't have permission to save files at this location.
Both runs ended with exit code 0, so a script cannot tell. Put
$PWD/ in front of each file name, as above.
One line of text, no OCR at all
The NAPS2 docs give the rule: if a page already has text, NAPS2 leaves it alone. I added a "Page 1 of 10" line to each scanned page.
| File | OCR ran | Text out |
|---|---|---|
| Scanned PDF | Yes | 1,879 of 1,955 words |
| Same, with page numbers | No | Only the 40 page number words |
| Scan with old OCR text | No | The old text, unchanged |
| Typed cover and 10 scans | Scans only | Cover 13 of 13, scans 1,879 |
There was no warning, and the exit code was 0. Any text on a page counts, even one word.
Why NAPS2 does this
In NAPS2 8.6.0, a PDF page that is one picture filling the page comes in as a picture and gets OCR. Any other page stays a PDF page. It gets OCR only if it has no text at all.
The check is in PdfExporter.cs. Invisible OCR text counts as text too.
Two fixes for a skipped page
| Try | Words |
|---|---|
Add --deskew |
1,868 |
| Pictures first, with pdftoppm | 1,882 |
Add --rotate 360 |
10, no OCR ran |
Add --rotate 180 |
6, pages upside down |
naps2.console -i "$PWD/stamped.pdf" -n 0 -o "$PWD/book.pdf" --ocrlang eng -f --deskew
pdftoppm -r 300 -jpeg stamped.pdf pg && naps2.console -i "$(ls "$PWD"/pg-*.jpg | paste -sd ';' -)" -n 0 -o "$PWD/book.pdf" --ocrlang eng -f
Both fixes turn each page into a picture first. The page number becomes pixels, and the old text layer is gone.
Fast or Best: one word apart
| Mode | Words | Time |
|---|---|---|
| Fast, 4.1 MB model | 1,879 | 16 s |
| Best, 23.5 MB model | 1,880 | 19 s |
| Fast, fix white balance | 1,879 | 17 s |
| Best, fix white balance | 1,880 | 19 s |
"Fix white balance and remove noise" changed nothing in my runs. Tesseract got the same image, byte for byte. On clean scans, leave it off.
NAPS2 against OCRmyPDF
| Route | Words | |
|---|---|---|
| NAPS2, from the PDF | 1,879 | 4.2 MB |
| NAPS2, from the 10 JPGs | 1,873 | 6.5 MB |
| OCRmyPDF | 1,855 | 6.5 MB |
From the PDF, NAPS2 saved each page as a new, smaller JPEG. From the JPGs it kept the files, but with no DPI tag it made pages 20 x 32.1 inches.
Need the text, not a PDF?
Our Actor takes PDF, JPG and PNG files and returns Markdown, with no install. On the same 10 pages, inside a PDF, it found 1,874 words:
curl -s -X POST "https://api.apify.com/v2/acts/brasspage~pdf-ocr-to-markdown/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"documentUrls": ["https://api.apify.com/v2/key-value-stores/sTnmNrGoSsi7tLQvs/records/anythingllm-mixed-11-pages.pdf"]}' \
| jq -r '.[].markdown' > book.md
It costs $0.006 a page. It gives you text, not a searchable PDF.
How I tested it
- Pages: the 10 scans of OCR in n8n, proofread Wikisource book pages, 1,955 true words. Each page is one 300 ppi JPEG.
- NAPS2 8.6.0 for Apple Silicon, from GitHub, SHA-256 checked. It ran from the unpacked package with a wrapper that does what the alias does.
-
NAPS2 starts one Tesseract per core, up to 8. I held it to 2 with
DOTNET_PROCESSOR_COUNT=2, at lowest priority. - Score: true words found in order in the PDF text (pdftotext), with the scorer of the tessdata test.
- Page numbers: Helvetica text added with pypdf. Old OCR text: Tesseract 5.5.4. OCRmyPDF 17.13.0 with 2 jobs.
- Modes: set in config.xml, as the app saves them. One run each.
- The Actor: one real run, build 0.1.65, on November 12. Its file holds the same 10 pages plus a typed cover page.
What I did not test
- Scanning from a real scanner, and the NAPS2 window itself.
- Windows and Linux.
- Phone photos, handwriting, and languages other than English.
Two ways to skip the work
Run it yourself. Our Apify Actor turns scanned PDFs into Markdown, tables included.
Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.
Questions people ask
How do I use OCR in NAPS2?
Click Tools, then OCR, download a language, and check Make PDFs searchable using OCR. OCR runs when you save a PDF. In Terminal, add --ocrlang eng to naps2.console.
Why does NAPS2 OCR not work on my imported PDF?
NAPS2 skips a PDF page that already has any text, even one page number. Add --deskew, or turn the pages into pictures first with pdftoppm -r 300 -jpeg.
Is NAPS2 OCR Best mode better than Fast?
On 10 clean book scans, Best found 1,880 words and Fast 1,879, of 1,955. Best took 19 s, Fast 16 s.