Nextcloud OCR, tested on scanned PDFs
0
words in the scan, stock image
Fix "ocrmypdf: not found"
On the official Nextcloud 35.0.2 image, workflow_ocr 1.35.0 failed on a 10-page scan:
OCR not possible: sh: 1: ocrmypdf: not found sh: 1: ocrmypdf: not found
The image has no OCRmyPDF. I saved this as Dockerfile:
FROM nextcloud:latest
RUN apt-get update && apt-get install -y --no-install-recommends ocrmypdf tesseract-ocr-deu \
&& rm -rf /var/lib/apt/lists/*
With this image on the same volume, the setup check passed.
The failed job does not come back, so upload the scan again.
Make the flow by API
I saved the flow (File created, MIME type PDF, OCR file) as flow.sh:
jq -n --arg op "$1" '{class: "OCA\\WorkflowOcr\\Operation", name: "", operation: $op,
entity: "OCA\\WorkflowEngine\\Entity\\File", events: ["\\OCP\\Files::postCreate"],
checks: [{class: "OCA\\WorkflowEngine\\Check\\FileMimeType", operator: "is", value: "application/pdf"}]}' |
curl -s -u "$NC_USER:$NC_PASS" -H "OCS-APIRequest: true" -H "Content-Type: application/json" \
-d @- "$NC/ocs/v2.php/apps/workflowengine/api/v1/workflows/global?format=json" | jq -r .ocs.meta.status
sh flow.sh '{}' sets the defaults. Then upload a PDF.
OCR waits for cron
0 words after 60 s, with no cron
1,862 of 1,955 true words after cron
The app only queues a job, and the image runs no cron. I saved this as cron.sh:
docker exec -u www-data nextcloud php cron.php
It took 25 s for 10 pages, on 2 CPUs. Run it from the host's crontab every 5 minutes. The default AJAX mode runs a job only when someone loads a Nextcloud page.
A typed cover page in front changed nothing: 1,862 words, and 13 of 13 cover words kept.
Set the language in the flow
With no language set, OCRmyPDF reads English. I set German and the sidecar text file:
{"languages": ["deu"], "createSidecarFile": true}
| Setup | Words right | Umlauts right |
|---|---|---|
| No language set | 1,389 | 0 |
| deu, PDF text layer | 1,618 | 165 |
| deu, sidecar .txt | 1,843 | 192 |
The .txt lands next to the PDF. The PDF text layer mixed a magazine page's two columns.
A missing language fails the job
The Dockerfile adds only German. With ita in the flow, the job failed: the OCR engine "does not have language data" for ita. The file kept 0 words.
Add its pack, here tesseract-ocr-ita, to the apt-get line and build again.
Search does not find the OCR text
After OCR, I searched for 3 words from the scan with search.sh:
curl -s -u "$NC_USER:$NC_PASS" -H "OCS-APIRequest: true" \
"$NC/ocs/v2.php/search/providers/files/search?term=$1&format=json" | jq '.ocs.data.entries | length'
0 hits for Hatton, lifeboat and yacht
1 hit for the file name, scan-2
pdftotext found all 3 in the PDF. Content search needs the Full text search apps (not tested).
Want Markdown out? Use the Actor
Nextcloud OCR is free and keeps the PDF in place. Our OCR Actor gives Markdown from a file URL. On the same scan:
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/langchain-scan-10-pages.pdf"]}' \
| jq -r '.[].markdown' > scan.md
1,874 of 1,955 true words, Nextcloud 1,862
175 s for 10 pages, Nextcloud 25 s
It was 7 times slower, and it does not put the text back in Nextcloud. It costs $0.006 a page.
How I tested it
- Scan: the 10-page PDF of OCR in n8n, proofread Wikisource book scans with no text layer. 1,955 true words.
- Typed page: a 13-word cover sheet in front of the scan, the file of AnythingLLM OCR.
- German: the 3 pages of Paperless-ngx OCR.
- Score: true words found in order, with the scorer of the tessdata test. Text of each PDF: pdftotext.
- Nextcloud 35.0.2 on arm64 with SQLite, workflow_ocr 1.35.0, OCRmyPDF 16.7.0 and Tesseract 5.5.0 from Debian trixie. One volume, 2 CPUs.
- The code blocks above are the files that ran. cron.sh ran with my container's name. The Actor: one real run.
What I did not test
- The web page, the Tag assigned trigger, and JPG or PNG files.
- Nextcloud AIO and the workflow_ocr_backend app.
- Full text search, Redo OCR, Force OCR, and handwriting.
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
Why does Nextcloud OCR say ocrmypdf not found?
The official Nextcloud image has no OCRmyPDF, and the workflow_ocr app needs it. Add ocrmypdf to the image with a Dockerfile, then upload the file again.
Why does my uploaded PDF still have no text in Nextcloud?
workflow_ocr runs OCR in a background job. With no cron run, my scan still had 0 words after 60 s. Run php cron.php as www-data every 5 minutes.
Can Nextcloud search find the text inside an OCR PDF?
Not by default. After OCR, Nextcloud 35 search found the file by its name, but 0 hits for 3 words inside it. The Full text search apps add that. I did not test them.