Read a PDF whose page has both real text and a scanned image: the text layer is used where it exists, the image is read with OCR, and every word says which.
dotnet add package RecursiveAI.OneOcr --version 1.0.0 dotnet add package RecursiveAI.OneOcr.Pdf --version 1.0.0
expense.pdf is a one-page US Letter PDF printed from HTML: a heading and a paragraph as text, and the grainy receipt as an embedded image.
using OneOcr; using OneOcr.Pdf; OcrEngine engine = OcrEngine.LoadBundled(); IReadOnlyList<OcrPage> pages = PdfOcr.Read("expense.pdf", engine); foreach (OcrPage page in pages) { Console.WriteLine($"page {page.Index + 1}: {page.Width:F0} x {page.Height:F0} pt, {page.Words.Count} words"); foreach (var group in page.Words.GroupBy(w => w.Source)) Console.WriteLine($" {group.Key}: {string.Join(" ", group.Take(8).Select(w => w.Text))} ..."); foreach (OcrDiagnostic diagnostic in page.Diagnostics) Console.WriteLine($" {diagnostic.Code}: {diagnostic.Message}"); }
page 1: 612 x 792 pt, 64 words TextLayer: Expense report EX-118 Submitted by Dana Whitfield on ... Ocr: Corner Market 1402 Oak Street 78704 Austin +1 ... OCR301: 1 regions were read from pixels at 300 DPI (47 words).
- Each PDF page is one
OcrPagein PDF points, y down;ToPdfmaps coordinates back to PDF user space. - Image regions the text doesn’t cover are rendered at
PdfOcrOptions.RenderDpi(300 by default) through OneImage.Pdf and read with the local engine;OCR301says how many. - A text layer isn’t trusted blindly: an invisible layer over a scan (an earlier OCR pass) is read again unless you set
TrustExistingOcrLayer, and garbled lines are read again from a render. See PDF pages. - For a
PdfPageorPdfDocumentyou already hold from OnePDF, the extension methodsOcr,ToText,ToMarkdown,ExtractInvoiceandExtractReceiptdo the same. Text drawn as outlined glyphs and annotations aren’t read yet.