Tools,

JPG to searchable PDF, free, tested on 10 pages

1,875

of 1,955 words, JPGs unchanged

Get the script

Two lines, one searchable PDF

32 s for 10 pages, 2 cores

6.5 MB PDF, same as the JPGs

  1. Install Tesseract once. I used brew install tesseract.
  2. Name the JPGs page-01.jpg, page-02.jpg and so on, so page 10 comes last.
  3. Save jpg.sh in that folder and run sh jpg.sh.
ls page-*.jpg > list.txt
tesseract --dpi 300 list.txt book pdf

Tesseract reads each JPG and puts the words, hidden, behind the picture. It writes book.pdf, one page per JPG.

No DPI tag: pages 44 inches tall

My JPGs have no DPI tag, so each tool guessed a page size. Without --dpi 300, Tesseract made pages 27.4 x 44 inches.

Page 1 of four PDFs from the same JPG, to scale. At 300 dpi the page is small. At 96, 72 and 70 dpi it is 3 to 4 times as tall.
The same JPG, page 1 of four PDFs, to scale. Left to right: 300 dpi set, then the guesses of img2pdf, ImageMagick and Tesseract.
Page 1, no DPI set
Tool Guess Page
Tesseract 70 dpi 27.4 x 44 in
ImageMagick 72 dpi 26.7 x 42.8 in
img2pdf 96 dpi 20 x 32.1 in

The words barely changed: Tesseract found 1,877 at its guess and 1,875 at 300 dpi. Only the page size was wrong.

OCRmyPDF wants a PDF first

OCRmyPDF takes one JPG at a time. With no DPI tag, it stopped:

DpiError: Input file is an image, but has no resolution (DPI) in its metadata.

--image-dpi 300 fixed it. For many JPGs, img2pdf joins them into one PDF first, with no new JPEG pass:

img2pdf --imgsize 300dpi page-*.jpg -o pages.pdf
ocrmypdf --jobs 2 pages.pdf book.pdf

That found 1,853 words in 24 s and kept all 10 JPGs byte for byte. Without --imgsize 300dpi, img2pdf made pages 20 x 32.1 inches.

Five ways, same 10 JPGs

Words found in order, of 1,955
Route Words JPGs kept
Tesseract --dpi 300 1,875 10 of 10
Tesseract, no DPI 1,877 10 of 10
img2pdf 300 dpi, OCRmyPDF 1,853 10 of 10
img2pdf, OCRmyPDF 1,856 10 of 10
ImageMagick, OCRmyPDF 1,845 0 of 10

Every PDF was 6.5 MB. ImageMagick wrote each picture as a new JPEG, so the pages are no longer your original files.

Need the text, not a PDF?

Our Actor takes JPG, PNG and PDF 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
  • JPGs: the 10 pages of OCR in n8n, proofread Wikisource book scans, 1,955 true words. 1920 pixels wide, no DPI tag.
  • Score: true words found in order in the text of each PDF (pdftotext), with the scorer of the tessdata test. JPGs kept: pdfimages, then a SHA-256 match with the input files.
  • Tools: Tesseract 5.5.4, OCRmyPDF 17.13.0, img2pdf 0.6.3, ImageMagick 7.1.2-11. Apple Silicon Mac, lowest priority, 2 cores, one run each.
  • The Actor: one real run, build 0.1.65, on November 12. Its file holds the same 10 JPEG pages plus a 13-word typed cover page.
What I did not test
  • Adobe Acrobat, Preview and online converters.
  • Phone photos, PNG files and handwriting.
  • Languages other than English.
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

How do I turn JPG files into a searchable PDF for free?

Put the file names in a list and run tesseract --dpi 300 list.txt book pdf. On 10 book pages, it found 1,875 of 1,955 words and kept the JPGs byte for byte.

Why are the pages of my PDF so big?

The JPG has no DPI tag, so the tool guesses. Tesseract used 70 dpi and made pages 27.4 x 44 inches. Add --dpi 300 to Tesseract, or --imgsize 300dpi to img2pdf.

Can OCRmyPDF read a JPG?

Yes, one JPG at a time. With no DPI tag, it stops with a DpiError until you add --image-dpi 300. For many JPGs, join them with img2pdf first.