OfficeIMO.Pdf.Ocr 3.4.3

Prefix Reserved
dotnet add package OfficeIMO.Pdf.Ocr --version 3.4.3
                    
NuGet\Install-Package OfficeIMO.Pdf.Ocr -Version 3.4.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OfficeIMO.Pdf.Ocr" Version="3.4.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OfficeIMO.Pdf.Ocr" Version="3.4.3" />
                    
Directory.Packages.props
<PackageReference Include="OfficeIMO.Pdf.Ocr" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OfficeIMO.Pdf.Ocr --version 3.4.3
                    
#r "nuget: OfficeIMO.Pdf.Ocr, 3.4.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OfficeIMO.Pdf.Ocr@3.4.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OfficeIMO.Pdf.Ocr&version=3.4.3
                    
Install as a Cake Addin
#tool nuget:?package=OfficeIMO.Pdf.Ocr&version=3.4.3
                    
Install as a Cake Tool

OfficeIMO.Pdf.Ocr - OCR and searchable PDF integration

nuget version

OfficeIMO.Pdf.Ocr connects any OfficeIMO.Ocr.IOcrEngine to first-party PDF page rendering, native-text overlap filtering, logical reconstruction, and searchable PDF output. OCR is optional and is not part of the base OfficeIMO.Pdf dependency graph.

Install

Install the PDF integration and one provider. For Tesseract:

dotnet add package OfficeIMO.Pdf.Ocr
dotnet add package OfficeIMO.Ocr.Tesseract

Tesseract itself remains a separately installed host dependency. A custom or hosted provider only needs the OfficeIMO.Ocr contract.

Read scanned and mixed PDFs

using OfficeIMO.Ocr.Tesseract;
using OfficeIMO.Pdf;
using OfficeIMO.Pdf.Ocr;

var engine = TesseractOcrEngine.CreateDefault();
PdfDocument pdf = PdfDocument.Load("mixed-report.pdf");

PdfOcrMergeResult result = await pdf.ReadWithOcrAsync(
    engine,
    new PdfOcrMergeOptions {
        Language = "eng+pol",
        Dpi = 180,
        MaxConcurrentPages = 2,
        MinimumConfidence = 0.75,
        ReadOptions = new PdfReadOptions {
            LayoutOptions = new PdfTextLayoutOptions {
                ReadingDirection = PdfReadingDirection.Auto
            }
        }
    });

Console.WriteLine(result.Document.Text);
Console.WriteLine($"Accepted OCR words: {result.AcceptedWordCount}");

Every selected page is rendered to a bounded raster request. Pixel, point, and normalized provider coordinates are projected into the page's cropped and rotated visual point space. Low-confidence spans and spans overlapping native text are rejected before OCR evidence enters the same language-neutral reading-order, region, list, paragraph, heading, and table pipeline as native positioned text.

NativeDocument retains the native-only parse. Document is the canonical native-plus-OCR parse and can be passed directly to the existing PDF-to-Word, Excel, PowerPoint, HTML, RTF, or OpenDocument adapters. Page results retain accepted words, provider/model/language evidence, rejections, and diagnostics.

Reconstruct columns and mixed-direction text

Provider line hierarchy and logical sequence are preserved by default. If a provider joins two columns into one line or supplies an unsuitable page order, enable geometry-based reconstruction:

PdfOcrMergeResult reconstructed = await pdf.ReadWithOcrAsync(engine,
    new PdfOcrMergeOptions {
        ReconstructLayout = true,
        Language = "heb+ara+eng",
        ReadOptions = new PdfReadOptions {
            LayoutOptions = new PdfTextLayoutOptions {
                ReadingDirection = PdfReadingDirection.RightToLeft
            }
        }
    });

The shared PDF stages rebuild OCR lines, columns, and aligned tables from accepted words. Mixed-direction fragments use the same logical-order resolver as native text. Dominant quarter-turn layouts are analyzed in a corrected reading frame; returned words, selection rectangles, and table bounds use the original page geometry. Explicit direction is useful for ambiguous pages; Auto remains the default.

Reconstruction does not repair recognition errors or infer a figure from its caption vocabulary. A full-page scan can retain caption text without exposing a separate figure region or classified caption. Searchable output preserves the visible scan and supports subsequent line and table reconstruction from its invisible selection boxes. See the independent layout corpus for measured coverage and limits.

Prepare uneven or rotated scans

Scan cleanup is opt-in and uses the shared OfficeIMO.Core image processor. It changes the raster sent to OCR; the source PDF and its visible scans are preserved.

using OfficeIMO.Drawing;

PdfSearchableOcrReview review = await pdf.PrepareSearchableOcrAsync(engine,
    new PdfOcrMergeOptions {
        Dpi = 300,
        DetectOrientation = true,
        MinimumOrientationConfidence = 0.75,
        ScanProcessing = new OfficeScanProcessingOptions {
            Deskew = true,
            NormalizeBackground = true,
            ColorMode = OfficeScanColorMode.Grayscale,
            MaximumDimension = 3000,
            MaximumWorkingBytes = 256L * 1024 * 1024
        }
    });

foreach (PdfOcrPageMergeResult page in review.Ocr.Pages) {
    Console.WriteLine($"Page {page.PageNumber}: deskew {page.ScanProcessing?.AppliedDeskewDegrees}");
}
PdfSearchableOcrResult searchable = review.ApplyAll();

Orientation detection uses the provider's optional orientation capability and the same timeout, cancellation, and concurrency gate as recognition. Missing or low-confidence evidence retains the source orientation and produces a diagnostic. Tesseract needs its osd trained data. An explicit ClockwiseQuarterTurns value can supply a caller-reviewed correction; it combines with any accepted provider correction.

Deskew searches a bounded range of small angles; StraightenDegrees supplies a manual correction from -15 to 15 degrees. Background normalization estimates local paper brightness. BlackPoint, WhitePoint, and Gamma adjust tonal levels before optional bilevel conversion. Downsampling never enlarges a scan. Blank-page detection reports a suggestion and keeps the page. Curved-page dewarping remains unsupported.

ScanProcessing reports applied and skipped operations, buffer estimates, and forward/inverse pixel transforms. Its pixel, buffer, and analysis-work limits reject optional cleanup with an ocr-scan-limit diagnostic and retain the original OCR raster; cancellation still propagates. Buffer accounting covers the managed image operation, while encoded PDF/raster and provider-process limits remain separate. PdfRecognizedWord.Geometry retains all four corners on the original page, so the invisible text layer follows the original scan's angle after deskew or a quarter-turn. X, Y, Width, and Height remain its enclosing visual bounds.

Review a region and perspective correction

Regions accepts one normalized rectangle per page. A nonempty list sends only those pages and pixels to the OCR provider. Region pages must also belong to ReadOptions.PageSelection when supplied. Perspective specifies four normalized corners relative to the region, or to the full page when no region is selected. Preparation crops first, corrects perspective next, and applies affine scan cleanup last.

var options = new PdfOcrMergeOptions {
    Regions = new[] { new PdfOcrPageRegion(1, 0.1, 0.1, 0.8, 0.7) },
    Perspective = new OfficeScanPerspectiveOptions {
        TopLeft = new(0.02, 0.04), TopRight = new(0.98, 0),
        BottomRight = new(1, 1), BottomLeft = new(0, 0.96)
    },
    ScanProcessing = new OfficeScanProcessingOptions {
        Deskew = false, StraightenDegrees = 2, Gamma = 1.1
    }
};
PdfScanPreview preview = await document.PreviewScanAsync(1, options);
byte[] originalPreview = preview.GetSourcePng();
byte[] preparedPreview = preview.GetPreparedPng();
PdfSearchableOcrReview review = await document.PrepareSearchableOcrAsync(engine, options);

Preview uses the same preparation code without calling an OCR provider. OCR geometry maps back through all transforms to the original visible page. preview.CreateImagePdf() instead creates a separate raster-only PDF of the prepared pixels: native text, forms, links, signatures, and attachments are omitted. Invalid region or perspective settings stop preparation; they do not silently select a different area. ScanProcessing describes the affine cleanup relative to the prepared region; its matrix alone does not describe the earlier crop and perspective mapping.

Discover scanned redaction candidates

Use the same OCR geometry and native-overlap owner to map literal or bounded-regex matches into PDF user-space areas:

var search = new PdfRedactionSearchOptions()
    .AddLiteral("Account Secret")
    .AddRegex(@"\b\d{3}-\d{2}-\d{4}\b");

PdfOcrRedactionSearchResult candidates = await pdf
    .SearchRedactionCandidatesWithOcrAsync(engine, search);

foreach (PdfOcrRedactionCandidate candidate in candidates.Candidates) {
    Console.WriteLine($"Page {candidate.Area.PageNumber}: {candidate.Criterion}, confidence {candidate.MinimumConfidence:0.00}");
}

Candidate results intentionally omit recognized matched text. They retain the criterion index, geometry, minimum confidence, and provider/model/language evidence needed by a review workflow. Literal and regex search is isolated to provider-declared lines, with bounded geometric line inference only when hierarchy identifiers are unavailable, so candidates are not assembled across unrelated lines or columns. OfficeIMO.Workflows can combine these candidates with native matches, persist source-bound decisions, re-run the same provider after destructive application, and publish privacy-safe evidence.

Add a searchable text layer

PdfSearchableOcrResult searchable = await pdf.MakeSearchableAsync(engine);
await searchable.Document.SaveAsync("mixed-report-searchable.pdf");

Console.WriteLine($"Modified pages: {string.Join(", ", searchable.ModifiedPages)}");
Console.WriteLine($"Added words: {searchable.AddedWordCount}");

Only pages with accepted OCR words are rewritten. The invisible text layer follows the canonical semantic order. WrittenWords records what entered the layer, while Ocr retains recognition evidence. Signed or otherwise rewrite-sensitive documents remain subject to the base PDF mutation and preservation rules.

Review before creating the layer

PrepareSearchableOcrAsync captures the source and recognizes its selected pages without changing or saving the PDF. A review interface can display Ocr.Pages, including WordEvidence for accepted words, low-confidence words, and native-text overlaps. RenderPage previews the same source snapshot; GetPageSize and word geometry use cropped, rotated visual PDF points.

PdfSearchableOcrReview review = await pdf.PrepareSearchableOcrAsync(engine);

// Replace this confidence selection with the eligible word instances chosen in a review interface.
var selected = review.Ocr.Pages.SelectMany(page => page.Words)
    .Where(word => word.Confidence >= 0.90).ToArray();
// Text extraction uses logical reading order and does not create or modify a PDF.
string recognizedText = review.ExtractText(selected);
PdfSearchableOcrResult reviewed = review.Apply(selected);
await reviewed.Document.SaveAsync("reviewed-searchable.pdf");

Selections may exclude eligible words but cannot inject words from another review or override a rejection. To change the confidence or overlap policy, prepare a new review with new options. Low-confidence words are rejected before overlap evaluation; invalid geometry remains a diagnostic rather than a selectable word. An empty selection produces an unchanged source copy. AddedWordCount and WrittenWords describe the actual layer after review exclusions.

PdfOcrMergeOptions bounds provider-call duration, rendered pixels, selected pages, inspected spans, accepted OCR words and characters, aggregate raw hierarchy identifiers, provider metadata and diagnostics, native-overlap comparisons, and merged text. Calls use one shared OcrEngineExecution per document, so identity and capabilities are stable across pages and the same non-concurrent engine instance cannot overlap across PDF, Reader, or a future integration. Language is provider configuration only; it is never used to infer captions, lists, paragraphs, tables, or continuations.

Use ApplyCorrections to correct recognized text after reviewing the page. Include only the eligible words to write, paired with their final text:

var corrections = review.Ocr.Pages.SelectMany(page => page.Words)
    .ToDictionary(word => word, word => word.Text);
PdfRecognizedWord selectedWord = review.Ocr.Pages[0].Words[0];
corrections[selectedWord] = "Corrected text";
PdfSearchableOcrResult corrected = review.ApplyCorrections(corrections);
await corrected.Document.SaveAsync("corrected-searchable.pdf");

Corrections preserve the selected word's geometry and reading order. WrittenWords contains the replacement text, CorrectedWordCount counts changed words, and Ocr retains the original provider text and confidence. Replacement text must be nonempty and fit the per-page OCR character budget.

Scan rendering and execution limits

CCITT Group 3 and Group 4 scans use the managed decoder. Packed 1-, 2-, and 4-bit DeviceGray samples pass through the existing decode-array, color, and mask handling. Fax decoding requires a declared row count or image height; uncompressed fax extension mode and damaged-row recovery are outside the supported contract.

Opaque JPEG 2000 images with baseline Gray/sRGB headers or one/three-component codestreams can use PdfOcrMergeOptions.ImageCodec, the shared IOfficeRasterImageCodec interface. The same codec is used by review previews. A missing decoder or an unprojectable scan causes rendering to fail before that page is sent to OCR. JPEG 2000 embedded or external masks, palette/channel remapping, alternate color spaces, and output-intent normalization remain unsupported. Embedded alpha is rejected even when SMaskInData is absent or zero, because those PDF cases require discarding that alpha before rendering. No JPEG 2000 runtime is bundled.

Pages[i].Diagnostics includes render warnings as well as provider and normalization diagnostics. Inspect these before treating a result as complete: font substitution and unsupported drawing features can affect recognition even when a page renders.

MaxConcurrentPages defaults to one. Raise it to overlap page requests for providers that declare concurrent-request support. Non-concurrent providers remain serialized, and result pages retain the requested order. Parsing and rendering use one producer; only a bounded number of provider requests are retained. MaxRenderedBytesPerPage defaults to 64 MiB and limits each encoded PNG. Rendered pages are released as requests complete rather than accumulated for the whole document.

Targets and dependency footprint

  • Targets: netstandard2.0, net8.0, net10.0 (net472 is also included on Windows builds).
  • OfficeIMO dependencies: OfficeIMO.Core, OfficeIMO.Ocr, and OfficeIMO.Pdf.
  • Not dependencies: Reader, Tesseract, process execution, cloud SDKs, or native OCR runtimes.
  • License: MIT.

See the OfficeIMO.Pdf README for native reading and document operations.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on OfficeIMO.Pdf.Ocr:

Package Downloads
OfficeIMO.Workflows

Typed local document workflows that compose first-party OfficeIMO conversion, PDF, and provenance capabilities.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.4.3 154 9/12/2026
3.4.2 174 9/9/2026
3.4.1 189 9/7/2026
3.4.0 128 9/6/2026