Calibre OCR: why your EPUB comes out empty
0
words in the EPUB, after OCRmyPDF
OCRmyPDF first is not enough
Calibre has no OCR step, so I ran OCRmyPDF first. Then I made EPUBs with ebook-convert.
| Into ebook-convert | Words | Page images |
|---|---|---|
| The scan | 0 | 10 |
| OCRmyPDF's PDF | 0 | 10 |
| Same, sandwich renderer | 0 | 10 |
| OCRmyPDF's text file | 2,042 | 0 |
OCRmyPDF hides its text in an invisible layer. pdftotext read 2,047 words from that PDF. Calibre's PDF engines, calibre and pdftohtml, both gave 0.
The fix: give Calibre the text
--sidecar writes OCRmyPDF's text to a file, and Calibre
makes an EPUB from a text file. I saved this as pdf2epub.sh and ran
sh pdf2epub.sh eng:
ocrmypdf --jobs 2 --mode force -l "$1" --output-type none --sidecar book.txt book.pdf -
ebook-convert book.txt book.epub
1,866 of 1,955 words, in order
35 s for 10 pages, 2 cores
The EPUB is text only, with no page images. 10 words kept a line-end
hyphen, like gath-ered. --enable-heuristics did not join
them.
A typed page needs --mode force
I put a typed cover page in front of the scan. The OCRmyPDF mode decides if that page gets into the text file.
| Mode | Result |
|---|---|
default |
Stopped: page 1 already has text |
skip |
Typed page left out |
redo |
Typed page left out |
force |
All 11 pages, 13 of 13 typed words |
All 3 that ran found the same 1,866 scan words. More on skip in OCRmyPDF output to text.
German needs a full tessdata folder
With eng, the 3 German pages lost all 206 umlauts. With deu, OCRmyPDF stopped: Homebrew Tesseract had only eng and osd.
A folder with only deu.traineddata failed too:
read_params_file: Can't open hocr. OCRmyPDF needs
Tesseract's configs folder. My lang.sh copies it:
cp -RL "$(brew --prefix)/share/tessdata" tessdata
curl -sL -o tessdata/deu.traineddata https://github.com/tesseract-ocr/tessdata/raw/main/deu.traineddata
Then I set TESSDATA_PREFIX to that folder and ran
sh pdf2epub.sh deu.
193 of 206 umlauts
928 of 972 words in order, two columns
Want clean text? Use the Actor
Calibre also reads Markdown. Our OCR Actor gives Markdown from a file URL. On the 11-page file:
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' > mixed.md
ebook-convert mixed.md mixed.epub
1,874 of 1,955 words, OCRmyPDF 1,866
954 of 972 in order on two columns, OCRmyPDF 928
It joined every line-end hyphen and needed no mode for the typed page.
It was slower: 156 s for the 11 pages, OCRmyPDF 27 s. It got one umlaut less (192). It costs $0.006 a page. OCRmyPDF is free and offline.
How I tested it
- Scan: the 10 pages of OCR in n8n, proofread Wikisource book scans, 1,955 true words. The 11-page file adds the 13-word typed cover page of AnythingLLM OCR.
- German: the 3 pages of Paperless-ngx OCR, 1,887 words, 206 umlauts. One is a two-column magazine page.
- Score: I turned each EPUB back into text with ebook-convert. Then true words found in order, with the scorer of the tessdata test. German: the scorer of Tesseract German.
- Calibre 9.18.0 from the official macOS download, OCRmyPDF 17.13.0, Homebrew Tesseract 5.5.4, on an arm64 Mac. 2 cores at the lowest priority.
- The code blocks above are the files that ran. The Actor: two real runs, build 0.1.65.
What I did not test
- The Calibre app window. I used its command, ebook-convert.
- Calibre plugins, and Windows or Linux.
- Output formats other than EPUB, like AZW3.
Sources
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
Does Calibre have OCR?
Not in my test. ebook-convert 9.18.0 has no OCR option. A 10-page scan became an EPUB with 10 page images and 0 words.
Why is my EPUB empty after OCRmyPDF?
OCRmyPDF puts its text in an invisible layer, and Calibre skipped it with both PDF engines. Give Calibre the --sidecar text file instead. That EPUB had 1,866 of 1,955 words.
How do I OCR a PDF that has a typed page for Calibre?
Use --mode force. With skip or redo, the text file left the typed page out. The default mode stopped with page already has text.
Related guides
- OCRmyPDF output to text: --sidecar, tested
- OCRmyPDF "page already has text": which flag to use
- OCRmyPDF language: set -l, or lose the accents
- Tesseract and two columns: the default reads them right
- A PDF OCR API in one curl call
- Zotero OCR, tested on a real scan
- LibreOffice OCR: what works on a scanned PDF