---
title: "OCR a PDF in C#"
url: https://recursiveai.org/oneocr/cookbook/ocr-pdf/
description: "OCR a scanned PDF in C# and get its text: a complete program with local OCR, no Tesseract or cloud service. Pages that already have text use it; scanned images are read with OCR."
version: "1.0.0"
---

# OCR a PDF in C#

Pass the PDF to `PdfOcr.Read`: each page comes back with its text, read with OCR where the page is a scan. The program below reads a scanned invoice, a PDF with no text layer that you can download to try it.

```shell
dotnet new console -o OcrPdf && cd OcrPdf
dotnet add package RecursiveAI.OneOcr --version 1.0.0
dotnet add package RecursiveAI.OneOcr.Pdf --version 1.0.0
curl -O https://recursiveai.org/oneocr/samples/scanned-invoice.pdf
```

Put this in `Program.cs` and run `dotnet run`:

```csharp
using OneOcr;
using OneOcr.Pdf;

OcrEngine engine = OcrEngine.LoadBundled();
IReadOnlyList<OcrPage> pages = PdfOcr.Read("scanned-invoice.pdf", engine);

foreach (OcrPage page in pages)
{
    Console.WriteLine($"--- page {page.Index + 1}, {page.Words.Count} words");
    Console.WriteLine(page.ToText());
}
```

```text
--- page 1, 99 words
Northwind Supply Ltd
14 Harbour Street
BS1 4DJ Bristol
United Kingdom
VAT ID: GB284193752
INVOICE
Bill to
Blue Heron Bakery
- 88 Elm Road
OX1 2JD Oxford
United Kingdom
Invoice no.	INV-2041
Date	14/10/2026
Due date	13/11/2026
Order no.	PO-7731
Description	Qty	Unit price	VAT	Amount
Flour, 25 kg bag	4 pcs	31.50	0%	126.00
Cane sugar, 10 kg	2 pcs	18.25	0%	36.50
Baking parchment roll	6 pcs	7.40	20%	44.40
Subtotal
VAT total
Total
£206.90
£8.88
£215.78
Payment terms: Payable within 30 days
IBAN: GB33 BUKB 2020 1555 5555 55	BIC: BUKBGB22	Tel. +44 117 496 0321
```

The scan is a little tilted and grainy; the page was straightened before it was read, and one speck came through as the `-` before “88 Elm Road”. Each page is an `OcrPage`, the same model you get from an image, with coordinates in PDF points.

## Pages with both text and scans

Many PDFs mix real text with scanned images. The text layer is used where it exists and only the images are read with OCR, so every word says where it came from. This expense report has a typed paragraph and a photo of a receipt:

```shell
curl -O https://recursiveai.org/oneocr/samples/expense.pdf
```

```csharp
using OneOcr;
using OneOcr.Pdf;

OcrEngine engine = OcrEngine.LoadBundled();
OcrPage page = PdfOcr.Read("expense.pdf", engine)[0];

foreach (var group in page.Words.GroupBy(w => w.Source))
{
    string start = string.Join(" ", group.Take(7).Select(w => w.Text));
    Console.WriteLine($"{group.Key}: {group.Count()} words: {start} ...");
}
foreach (OcrDiagnostic d in page.Diagnostics)
    Console.WriteLine($"{d.Code}: {d.Message}");
```

```text
TextLayer: 26 words: Expense report EX-118 Submitted by Dana Whitfield ...
Ocr: 49 words: Corner Market 1402 Oak Street 78704 Austin ...
OCR301: 1 regions were read from pixels at 300 DPI (49 words).
```

`TextLayer` words are copied from the PDF; `Ocr` words were read from the image, rendered at 300 DPI. A text layer isn’t trusted blindly: an invisible layer left by an earlier OCR pass is read again, and garbled lines are checked against a render. [PDF pages](https://recursiveai.org/oneocr/docs/pdf-bridge/) has the rules.

## Options

`new PdfOcrOptions { … }` as the third argument sets `RenderDpi` (300), `FirstPage` and `PageCount` to read part of a file, `Password` for an encrypted PDF, and `TrustExistingOcrLayer` to keep an earlier OCR pass as it is. If you already have a `PdfDocument` open in [OnePDF](https://recursiveai.org/onepdf/), `doc.Ocr(engine)` and `doc.ToText(engine)` do the same.

## Limits

- **It reads; it doesn’t write.** You get the text and the words with their positions, not a new searchable PDF.
- **Printed Latin, Greek and Cyrillic text.** No CJK, Arabic or Indic scripts, and no handwriting, yet.
- **Text drawn as outlines and annotations aren’t read.**

For a single image, see [Extract text from an image](https://recursiveai.org/oneocr/cookbook/extract-text-from-image/). To pull fields out of a scanned invoice, see [Extract data from an invoice](https://recursiveai.org/oneocr/cookbook/invoices/).
