Skip to main content
Developer Guide

Tesseract OCR for PDFs
and searchable PDFs.

The complete, tested guide to OCRing PDFs with Tesseract: rasterizing pages, creating searchable PDFs, using OCRmyPDF and pdfsandwich, running it end-to-end in Python, and fixing the errors people actually hit.

TL;DR (one command)

For a real multi-page PDF, OCRmyPDF is the fastest path.

bash
pip install ocrmypdf      # or: apt install ocrmypdf
ocrmypdf input.pdf output.pdf

No OCRmyPDF? Rasterize and use the Tesseract CLI directly — see below.

Why PDFs must be rasterized

Tesseract recognises images, not PDF containers.

A PDF is a container: it may hold vector text, embedded fonts, or scanned page images. Tesseract reads raster images (TIFF, PNG, JPEG, WebP, …), so PDF pages must be converted to images first. Choose the rasterizer based on what you have installed:

ToolInstallNotes
pdftoppm (poppler)apt install poppler-utilsFast, scriptable, the classic choice
pdftocairo (poppler)poppler-utilsSimilar to pdftoppm, Cairo output
ImageMagickapt install imagemagickconvert -density 300 in.pdf out.tif
PyMuPDFpip install pymupdfPure Python, no external binaries
pdf2imagepip install pdf2imagePython wrapper around poppler
bash
# PDF -> one PNG per page at 300 DPI
pdftoppm -png -r 300 input.pdf page

DPI matters most: 300 DPI is the standard balance; 600 DPI for small fonts or archival work; avoid below 200 DPI where accuracy drops sharply.

Create a searchable PDF with the Tesseract CLI

One image becomes one searchable PDF page with the pdf output config.

bash
# Image -> searchable PDF
tesseract page-1.png out pdf

# Text layer only (no visible image)
tesseract scan.png out textonly_pdf

# Multiple pages into one searchable PDF: pass a list of images
tesseract imagelist.txt out pdf

For a multi-page PDF, put each image path on its own line in imagelist.txt. Full CLI output-format reference: documentation.

Method B — OCRmyPDF (recommended for real PDFs)

OCRmyPDF handles rasterizing, OCR, deskewing, rotation and the invisible text layer in one command.

bash
ocrmypdf input.pdf output.pdf                    # basic
ocrmypdf -l eng+deu input.pdf output.pdf         # languages
ocrmypdf --deskew --rotate-pages input.pdf output.pdf
ocrmypdf --optimize 2 input.pdf output.pdf       # shrink the file
ocrmypdf --skip-text input.pdf output.pdf        # keep pages that already have text

OCRmyPDF uses Tesseract under the hood and requires Ghostscript and the poppler tools. Useful flags: --force-ocr, --redo-ocr, --pages 1-10.

Method C — pdfsandwich

A lighter wrapper that adds a text layer and performs preprocessing such as deskewing.

bash
pdfsandwich scanned.pdf          # produces scanned_ocr.pdf
pdfsandwich -lang eng+fra scanned.pdf

Method D — Python end-to-end

Use pdf2image to rasterize and pytesseract to build the searchable PDF, then merge with pypdf.

pdf.py
import io, pytesseract
from pdf2image import convert_from_path
from pypdf import PdfWriter, PdfReader

pages = convert_from_path("input.pdf", dpi=300)   # needs poppler
writer = PdfWriter()
for page in pages:
    pdf_bytes = pytesseract.image_to_pdf_or_hocr(page, extension="pdf", lang="eng")
    writer.add_page(PdfReader(io.BytesIO(pdf_bytes)).pages[0])
with open("output.pdf", "wb") as f:
    writer.write(f)

On Windows, pass the poppler bin folder via poppler_path=. More Python detail in the pytesseract guide.

Which method should I use?

MethodBest forSetupMulti-page
OCRmyPDFReal PDFs, automationGhostscript + popplerYes, in one command
pdfsandwichQuick text layer with preprocessingpoppler + ImageMagickYes
Tesseract CLIImages or image listsJust TesseractVia an image list
Python (pdf2image)Pipelines and custom logicpoppler + pytesseractLoop and merge

Layout fidelity and text overlay

Why searchable PDFs sometimes look misaligned, and how to keep geometry accurate.

Quality and performance

Troubleshooting

SymptomCauseFix
Unable to get page count. Is poppler installed?pdf2image cannot find popplerInstall poppler-utils, or set poppler_path on Windows.
Output PDF has no searchable textOCR did not run or used the wrong languageConfirm success and set -l/--language to the document language.
Text overlay is misalignedWrong DPI or page sizeRasterize at 300 DPI matching the original size.
Output file is hugeLossless 600 DPI imagesUse --optimize / JPEG, or reduce DPI.
Password-protected PDF failsEncrypted inputDecrypt first, or pass the password flag supported by your tool.

PDF FAQ

How do I make a PDF searchable?

Use ocrmypdf input.pdf output.pdf, or rasterize the pages and run tesseract page.tif out pdf.

Why can't Tesseract read a PDF directly?

Tesseract recognises raster images, so PDF pages must be converted to images first.

What DPI should I use?

300 DPI for most documents; 600 DPI for small fonts or archiving.

Can I OCR a PDF in Python?

Yes — use pdf2image with poppler and pytesseract.image_to_pdf_or_hocr, then merge pages with pypdf.

How do I keep the layout accurate?

Match the original page size and DPI, and prefer OCRmyPDF, which preserves the original raster and adds the text layer in place.