Tools,

Nextcloud OCR, tested on scanned PDFs

0

words in the scan, stock image

Get the fix

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}
3 German pages, 1,887 words, 206 umlauts
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.

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.

Try the Actor

Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.

Get one 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.