So führen Sie OCR auf Nummernschildern in C# aus
Dieser Leitfaden richtet sich an .NET Entwickler, die OCR-Workloads vom Kofax OmniPageCapture SDK (jetzt unter dem Namen Tungsten Automation vermarktet) auf IronOCR migrieren. Es umfasst den gesamten Migrationsprozess: von der Beseitigung der Abhängigkeit vom SDK-Installer über die Eliminierung der Engine-Lebenszykluszeremonie bis hin zum Ersatz zonenbasierter Erkennungsmuster und der Modernisierung der Fehlerbehandlung. Das vorherige Lesen des Vergleichsartikels ist nicht erforderlich.
Warum von Kofax OmniPage(Tungsten) migrieren?
Das OmniPage Capture SDK wurde für die Dokumentenmanagement-Infrastruktur von Enterprise in einer Ära vor NuGet, Docker und CI/CD-Pipelines entwickelt. Jede architektonische Entscheidung, die im Jahr 2005 sinnvoll erschien, führt im Jahr 2026 zu Reibungsverlusten.
Der SDK-Installer hat in einer NuGet Umgebung nichts zu suchen. Jeder Entwicklungsrechner, Build-Agent und Produktionsserver, der OmniPage-Code ausführt, benötigt den Tungsten SDK-Installer, der vor der Kompilierung ausgeführt werden muss. Es gibt keinen .csproj Paketbezug zur Wiederherstellung. Die Aktualisierung der SDK-Version erfordert die erneute Ausführung des Installationsprogramms auf der gesamten Flotte. Ein neuer Entwickler kann das Projekt nicht ausführen, ohne sich an denjenigen zu wenden, der die SDK-Lizenz verwaltet, und auf den Zugriff auf das Installationsprogramm zu warten.
Die Lizenzdatei ist eine betriebliche Haftung. Eine .lic Datei muss an einem bestimmten Pfad auf jedem Computer, der engine.Initialize() aufruft, vorhanden sein. Wenn Sie die Anwendung auf einem neuen Server bereitstellen und die Datei vergessen, schlägt jeder OCR-Aufruf mit einer Lizenzausnahme fehl – nicht mit einem OCR-Fehler. Verwenden Sie Floating-Lizenzen und eine Netzwerkpartition zwischen Ihrem Anwendungsserver und dem Lizenzserver bedeutet, dass jeder Initialize() Aufruf fehlschlägt, bis die Konnektivität wiederhergestellt ist, unabhängig davon, ob dieser Computer seine Lizenz gestern erfolgreich validiert hat.
Die Verwaltung des Lebenszyklus des Engines verliert Ressourcen auf Fehlerpfaden. OmniPageEngine.Shutdown() muss in jedem möglichen Codepfad aufgerufen werden – einschließlich Ausnahmehandlern, frühen Rückgaben und Zeitüberschreitungen – oder ein platzmäßig begrenzter Lizenplatz bleibt gesperrt, bis der Checkout-Timeout des Lizenzservers abläuft. Verteidigungsfähig um diesen Zwang zu schreiben bedeutet, jeden Integrationspunkt in IDisposable Muster zu wickeln, die ausschließlich zum Schutz vor dem Überspringen des Engine-Shutdowns existieren.
Hardware-Fingerprinting ist mit modernen Bereitstellungsmodellen nicht kompatibel. Die OmniPage-Aktivierung ist an die Hardware gebunden. Neustarts von Containern, VM-Migrationen und Cloud-Autoscaling beinhalten allesamt Hardware-Identitätsänderungen, die Reaktivierungsanforderungen auslösen. Ein Bereitstellungsmodell, das mit Autoscaling nicht kompatibel ist, ist ein Bereitstellungsmodell, das mit Cloud-Infrastruktur nicht kompatibel ist.
Die Preisgestaltung pro Seite ist bei großem Umfang unvorhersehbar. Eine plötzliche Spitzenbelastung bei der Dokumentenverarbeitung – beispielsweise durch die Aufnahme eines neuen Kunden oder die Einreichung eines Rückstands – führt zu einer Rechnung, die den vereinbarten Kostenrahmen überschreitet.IronOCR ist innerhalb der Lizenzstufe unbefristet und unbegrenzt nutzbar: keine Abrechnung pro Seite, kein Kontingent, keine Rechnungen für Mehrkosten.
Der Beschaffungsprozess blockiert den Versand. Das OmniPage SDK ist verkaufsbeschränkt. Für den Zugang zur Evaluierung, die Preisgestaltung und die Vertragsbedingungen ist ein Vertriebsgespräch erforderlich, das 4 bis 12 Wochen dauert. Teams, die OCR-Funktionen unter Zeitdruck entwickeln, können nicht auf einen Enterprise Beschaffungszyklus warten. dotnet add package IronOcr löst in 30 Sekunden auf. Siehe die IronOCR Lizenzseite für veröffentlichte, selbstbedienbare Preise – $999 Lite bis $2.999 Enterprise, alle unbefristet.
Das grundsätzliche Problem
OmniPage erfordert eine vollständige Initialisierungszeremonie, bevor das erste Byte gelesen wird, und eine Abschaltzeremonie nach dem letzten Byte – jede Aufrufstelle muss beides verwalten:
// OmniPage: Ceremony required on EVERY entry point — init, process, shutdown
using var engine = new OmniPageEngine();
engine.SetLicenseFile(@"C:\Program Files\OmniPage\license.lic"); // File must exist here
engine.Initialize(); // Network call to license server — can fail for license reasons, not OCR reasons
var document = engine.CreateDocument();
document.AddPage("invoice.jpg");
document.Recognize(new RecognitionSettings { Language = "English" });
string text = document.GetText();
document.Dispose(); // Must not be skipped
engine.Shutdown(); // Must not be skipped — omitting this locks a floating seat
// IronOCR: One NuGet package, one line at startup, one call to read
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; // At app startup — once, ever
var text = new IronTesseract().Read("invoice.jpg").Text;
Die OmniPage-Version besteht aus acht verschiedenen Schritten, zwei obligatorischen Aufräumaufrufen, einer Netzwerkabhängigkeit und einer Dateisystemabhängigkeit. Die IronOCR Version hat zwei.
##IronOCR vs. Kofax OmniPage(Tungsten): Funktionsvergleich
Die folgende Tabelle beschreibt die wichtigsten Funktionen für Teams, die diese Migration bewerten.
| Feature | Kofax OmniPageSDK | IronOCR |
|---|---|---|
| Installationsmethode | Benutzerdefinierter SDK-Installer (ohne NuGet) | dotnet add package IronOcr |
| Zeit für den ersten OCR-Anruf | 4–12 Wochen (Beschaffung) + Stunden (Einrichtung) | 30 Sekunden |
| Lizenzmechanismus | .lic Datei auf Festplatte + optionaler Lizenzserver | Schlüsselzeichenkette beim App-Start |
| Hardware-Fingerprinting | Ja (Reaktivierung bei VM-Migration) | Nein |
| Lizenzserver erforderlich | Ja (für Floating-Lizenzen) | Nein |
| Laufzeitabrechnung pro Seite | Verfügbar (variabel) | Nein |
| Veröffentlichte Preise | Nein (bitte wenden Sie sich an den Vertrieb) | Ja ($999 / $1.499 / $2.999 unbefristet) |
| Jährliche Wartungsgebühren | 18–25 % der Lizenzkosten | Optional |
| Lebenszyklusmanagement von Motoren | Erforderlich (Initialize / Shutdown) | Nicht erforderlich |
| Windows x64 | Ja | Ja |
| Linux | Ja (hinzugefügt im Januar 2026) | Ja (alle Versionen) |
| macOS | Nein | Ja |
| Docker / Kubernetes | Schwierig (Installationsprogramm + Lizenzdatei im Image) | Unkompliziert (nur NuGet Paket) |
| Azure / AWS Lambda | Komplex (Erreichbarkeit des Lizenzservers) | Unkompliziert |
| Bildeingabeformate | Ja | JPG, PNG, BMP, TIFF, GIF und mehr |
| Native PDF-Eingabe | Ja (möglicherweise ist eine Modullizenz erforderlich) | Ja (integriert, keine zusätzliche Lizenz erforderlich) |
| Mehrseitiges TIFF | Ja | Ja |
| Durchsuchbare PDF-Ausgabe | Ja | Ja (result.SaveAsSearchablePdf()) |
| Automatische Vorverarbeitung | Konfiguration des Einstellungsobjekts | Integrierte + explizite Pipeline-API |
| Unterstützte Sprachen | 120+ | 125+ (separate NuGet Pakete) |
| Ausgabe strukturierter Daten | Ja (Wortkoordinaten) | Seiten, Absätze, Zeilen, Wörter, Zeichen mit Koordinaten |
| Konfidenzbewertung | Ja | Ja (result.Confidence, pro Wort) |
| Barcode-Lesung | Zusatzmodul (separate Lizenz) | Eingebaut (ocr.Configuration.ReadBarCodes = true) |
| Thread-Sicherheit | Komplexe (Triebwerks-Sharing-Beschränkungen) | Voll (eine IronTesseract pro Thread) |
| CI/CD-Pipeline-Unterstützung | Erfordert einen Installer auf jedem Agenten | Standard dotnet restore |
Schnellstart: Migration von Kofax OmniPagezu IronOCR
Schritt 1: Ersetzen Sie das SDK durch ein NuGet -Paket
OmniPage hat kein NuGet Paket, das entfernt werden muss. Entfernen Sie die manuellen DLL-Referenzen aus der .csproj Datei und deinstallieren Sie das SDK von Entwicklermaschinen, wenn die Migration abgeschlossen ist. Installieren Sie anschließend IronOCR:
Das IronOCR NuGet Paket bündelt die OCR-Engine, Vorverarbeitungsfilter und Laufzeitkomponenten. Kein separates Installationsprogramm, keine native DLL-Verwaltung, keine Komponentenregistrierung.
Schritt 2: Namespaces aktualisieren
// Before (Kofax OmniPage)
using Kofax.OmniPage.CSDK;
using Kofax.OmniPageCSDK;
using CSDK;
// After (IronOCR)
using IronOcr;
Schritt 3: Lizenz initialisieren
Fügen Sie beim Start der Anwendung eine Zeile hinzu. Dies ersetzt den .lic Dateipfad, die Lizenzserverkonfiguration und den engine.Initialize() Aufruf:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"Speichern Sie den Schlüssel in einer Umgebung Variable (IRONOCR_LICENSE_KEY) oder appsettings.json anstatt im Quellcode. Der Schlüssel wird offline gelesen – es findet kein Netzwerkaufruf zur Laufzeit statt.
Beispiele für die Code-Migration
Pfadersetzung für Engine-Initialisierungsfehler
Der gefährlichste Aspekt des Lebenszyklusmodells von OmniPage ist nicht der positive Verlauf – sondern der Fehlerverlauf. Jede Ausnahme, die zwischen engine.Initialize() und engine.Shutdown() geworfen wird, kann einen Floating- Lizenzplatz gesperrt lassen, wenn Shutdown() nicht erreicht wird. Im Produktionscode sind try/finally-Blöcke um jeden Aufruf der Dokumentenverarbeitung erforderlich:
Kofax OmniPage-Ansatz:
// OmniPage: try/finally required everywhere to protect license seat release
public string ProcessInvoice(string imagePath)
{
var engine = new OmniPageEngine();
engine.SetLicenseFile(@"C:\Program Files\OmniPage\license.lic");
try
{
engine.Initialize(); // Contacts license server — failure here locks nothing
var document = engine.CreateDocument();
try
{
document.AddPage(imagePath);
document.Recognize(new RecognitionSettings { Language = "English" });
return document.GetText();
}
catch (RecognitionException ex)
{
// Log, rethrow — but Shutdown must still be called
throw new OcrProcessingException("Recognition failed", ex);
}
finally
{
document.Dispose(); // Inner finally: release document
}
}
catch (LicenseValidationException ex)
{
throw new OcrProcessingException("License validation failed", ex);
}
finally
{
engine.Shutdown(); // Outer finally: release license seat — MUST execute
}
}
IronOCR Ansatz:
// IronOCR:Neinlicense seat to release, no engine to shut down
public string ProcessInvoice(string imagePath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
var ocr = new IronTesseract();
var result = ocr.Read(input);
return result.Text;
// OcrInput disposal is automatic — no license implications on any code path
}
Der using Block auf OcrInput verarbeitet die Speicherbereinigung für die geladenen Bilddaten. Es gibt keinen try/finally um einen Lizenzplatz zu schützen. Eine Ausnahme an beliebiger Stelle in dieser Methode hat keine Nebenwirkungen außerhalb des eigenen Gültigkeitsbereichs der Methode. Informationen zu Konfigurationsoptionen, einschließlich Thread-lokaler Instanzen, finden Sie im IronTesseract-Setup-Leitfaden .
Migration zur zonenbasierten Erkennung
Der primäre Mechanismus zur strukturierten Extraktion von OmniPage ist die Zonendefinition: Dokumentbereiche werden mit Koordinatengrenzen und Erkennungstyp pro Zone (OCR, ICR, OMR, Barcode) deklariert. Entwickler definieren FormZone Objekte pro Dokumentvorlage und übergeben diese an die Erkennungsengine.IronOCR verwendet CropRectangle, um die gleiche gezielte Extraktion ohne Vorlagenverwaltung oder Zonentyperklärungen zu erreichen:
Kofax OmniPage-Ansatz:
// OmniPage: Zone-based form extraction with template management
public Dictionary<string, string> ExtractInvoiceFields(string invoicePath)
{
using var engine = new OmniPageEngine();
engine.SetLicenseFile(licensePath);
engine.Initialize();
// Define zones per document template
var zones = new List<FormZone>
{
new FormZone { Name = "InvoiceNumber", Type = "OCR",
X = 520, Y = 80, Width = 200, Height = 30 },
new FormZone { Name = "InvoiceDate", Type = "OCR",
X = 520, Y = 120, Width = 200, Height = 30 },
new FormZone { Name = "TotalAmount", Type = "OCR",
X = 520, Y = 580, Width = 200, Height = 30 },
new FormZone { Name = "VendorName", Type = "OCR",
X = 50, Y = 80, Width = 300, Height = 40 }
};
var template = new FormTemplate { Name = "StandardInvoice", Zones = zones };
var settings = new RecognitionSettings { Language = "English" };
var document = engine.CreateDocument();
document.AddPage(invoicePath);
document.ApplyTemplate(template);
document.Recognize(settings);
var fields = new Dictionary<string, string>();
foreach (var zone in zones)
fields[zone.Name] = document.GetZoneText(zone.Name);
document.Dispose();
engine.Shutdown();
return fields;
}
IronOCR Ansatz:
// IronOCR: CropRectangle targets specific regions — no template management
public Dictionary<string, string> ExtractInvoiceFields(string invoicePath)
{
var fields = new Dictionary<string, string>();
var ocr = new IronTesseract();
// Extract each field by reading only the target region
var fieldRegions = new Dictionary<string, CropRectangle>
{
["InvoiceNumber"] = new CropRectangle(520, 80, 200, 30),
["InvoiceDate"] = new CropRectangle(520, 120, 200, 30),
["TotalAmount"] = new CropRectangle(520, 580, 200, 30),
["VendorName"] = new CropRectangle(50, 80, 300, 40)
};
foreach (var (fieldName, region) in fieldRegions)
{
using var input = new OcrInput();
input.LoadImage(invoicePath, region);
fields[fieldName] = ocr.Read(input).Text.Trim();
}
return fields;
}
Jeder CropRectangle spezifiziert (x, y, width, height) in Pixeln. Die OCR-Engine verarbeitet nur den ausgewählten Bereich, nicht die gesamte Seite – derselbe Effizienzvorteil, den die zonenbasierte Verarbeitung in OmniPage bietet. Der regionbasierte OCR-Leitfaden deckt Koordinatenauswahlmuster ab, einschließlich wie man mehrere Regionen mit einer einzigen Bildladung extrahiert, indem man die Multi-Region-API von OcrInput verwendet.
Migration der Ausgabe strukturierter Daten
OmniPage stellt die Dokumentstruktur über eine proprietäre Exportpipeline dar: Formateinstellungen werden auf ein erkanntes Dokument angewendet, und die Ausgabe wird in einer Datei in einem bestimmten Format (RTF, XML, CSV, durchsuchbares PDF) geschrieben. Der Zugriff auf Koordinaten auf Wortebene erfordert die Iteration eines Ergebnisiterators mit expliziten Positionsabfragen.IronOCR stellt die gleichen strukturierten Daten direkt im Ergebnisobjekt bereit, ohne dass ein zweiter Exportschritt erforderlich ist:
Kofax OmniPage-Ansatz:
// OmniPage: Structured output requires format configuration and file export
public void ExtractStructuredContent(string imagePath, string outputDir)
{
using var engine = new OmniPageEngine();
engine.SetLicenseFile(licensePath);
engine.Initialize();
var settings = new RecognitionSettings { Language = "English" };
var document = engine.CreateDocument();
document.AddPage(imagePath);
document.Recognize(settings);
// Word-level coordinates through result iterator
var iterator = document.GetResultIterator(ResultIteratorLevel.Word);
while (iterator.MoveNext())
{
string word = iterator.GetText();
var bounds = iterator.GetBoundingBox();
double confidence = iterator.GetConfidence();
Console.WriteLine($"Word: {word} at ({bounds.X},{bounds.Y}) conf:{confidence:F1}%");
}
// Structured export requires separate output format configuration
var outputSettings = new OutputSettings
{
Format = OutputFormat.XML,
IncludeCoordinates = true,
IncludeConfidence = true
};
document.SaveAs(Path.Combine(outputDir, "output.xml"), outputSettings);
document.Dispose();
engine.Shutdown();
}
IronOCR Ansatz:
// IronOCR: Structured data directly on OcrResult — no export step
public void ExtractStructuredContent(string imagePath)
{
var result = new IronTesseract().Read(imagePath);
Console.WriteLine($"Confidence: {result.Confidence:F1}%");
Console.WriteLine($"Pages: {result.Pages.Length}");
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"[Paragraph at ({paragraph.X},{paragraph.Y})]");
Console.WriteLine(paragraph.Text);
foreach (var word in paragraph.Words)
{
// Per-word confidence and coordinates — no iterator needed
Console.WriteLine(
$" Word: '{word.Text}' " +
$"at ({word.X},{word.Y}) " +
$"conf: {word.Confidence:F1}%");
}
}
}
}
Die Hierarchie des OcrResult Objekts — Seiten, Absätze, Linien, Wörter, Zeichen — bietet die gleichen Positionsdaten, die der Resultats-Iterator von OmniPage bereitstellt, aber als navigierbares Objektdiagramm anstelle eines sequentiellen Cursors. Konfidenzwerte sind auf Ergebnis-, Seiten-, Absatz- und Wortebene ohne zusätzliche Konfiguration verfügbar. Der Leitfaden zu den Leseergebnissen umfasst alle Eigenschaften strukturierter Daten, und der Leitfaden zu den Konfidenzwerten umfasst Validierungsmuster pro Wort.
Migration der Verarbeitung mehrseitiger TIFF-Dateien
Der Workflow von OmniPage für mehrseitige TIFF-Dateien erfordert die Extraktion jeder einzelnen Seite aus dem TIFF-Container, wobei für jede Seite ein separater Erkennungsaufruf und eine separate Dokumentenentsorgung erfolgen. Dadurch entstehen sowohl Standardtexte als auch eine Ressourcenverwaltungsoberfläche, die proportional zur Seitenzahl ist.IronOCR lädt TIFF-Dateien mit mehreren Einzelbildern in einem einzigen Aufruf:
Kofax OmniPage-Ansatz:
// OmniPage: Page-by-page TIFF extraction with per-page lifecycle
public List<string> ExtractFromMultiPageTiff(string tiffPath)
{
var pageTexts = new List<string>();
using var engine = new OmniPageEngine();
engine.SetLicenseFile(licensePath);
engine.Initialize();
// Open TIFF and iterate frames
var tiffContainer = engine.OpenTiff(tiffPath);
int pageCount = tiffContainer.GetPageCount();
var settings = new RecognitionSettings { Language = "English" };
for (int i = 0; i < pageCount; i++)
{
var page = tiffContainer.GetPage(i); // Extract frame
var document = engine.CreateDocument();
try
{
document.AddPage(page);
document.Recognize(settings);
pageTexts.Add(document.GetText());
}
finally
{
document.Dispose(); // Dispose per page to manage memory
}
}
tiffContainer.Dispose();
engine.Shutdown();
return pageTexts;
}
IronOCR Ansatz:
// IronOCR: Multi-frame TIFF loaded in one call — all pages in one result
public List<string> ExtractFromMultiPageTiff(string tiffPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // All frames loaded automatically
var result = new IronTesseract().Read(input);
// Each TIFF frame becomes a page in the result
return result.Pages.Select(page => page.Text).ToList();
}
LoadImageFrames liest jedes Frame aus dem TIFF-Container in einem einzigen Aufruf. Das Ergebnis zeigt ein OcrResult.Page pro Frame, wobei die Seitenstruktur ohne manuelle Iterationsschleife oder Seitensäuberung beibehalten wird. Für Produktions-TIFF-Batch-Workflows siehe das TIFF- und GIF-Eingabeleitfaden.
Threadsichere Migration zur parallelen Verarbeitung
Die Engine von OmniPage ist eine gemeinsam genutzte, zustandsbehaftete Ressource. Das Teilen einer OmniPageEngine Instanz über Threads erfordert externe Synchronisation, da mehrere Threads, die gleichzeitig CreateDocument() aufrufen, einen verschachtelten Zustand erzeugen können. Das sichere Muster — eine Engine-Instanz pro Thread — steht im Konflikt mit den schweren Initialisierungskosten der Engine. IronOCR-Instanzen tragen keinen geteilten Zustand: Erstellen Sie eine IronTesseract pro Thread ohne Koordinationsaufwand:
Kofax OmniPage-Ansatz:
// OmniPage: Shared engine with locking to serialize document operations
public ConcurrentDictionary<string, string> ProcessBatchWithEngine(
string[] imagePaths, string licensePath)
{
var results = new ConcurrentDictionary<string, string>();
var engineLock = new object();
// One engine — document operations must be serialized
using var engine = new OmniPageEngine();
engine.SetLicenseFile(licensePath);
engine.Initialize();
var settings = new RecognitionSettings { Language = "English" };
Parallel.ForEach(imagePaths, imagePath =>
{
lock (engineLock) // Serialize: one recognition at a time
{
var document = engine.CreateDocument();
try
{
document.AddPage(imagePath);
document.Recognize(settings);
results[imagePath] = document.GetText();
}
finally
{
document.Dispose();
}
}
});
engine.Shutdown();
return results;
}
IronOCR Ansatz:
// IronOCR: One IronTesseract per thread — no locking, genuine parallelism
public ConcurrentDictionary<string, string> ProcessBatchInParallel(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
Parallel.ForEach(imagePaths, imagePath =>
{
// Each thread creates its own instance — no shared state, no locks
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = ocr.Read(input);
results[imagePath] = result.Text;
});
return results;
}
Die OmniPage-Version serialisiert die gesamte Erkennung durch eine Sperre, wodurch die Parallelität aufgehoben wird. Die IronOCR Version verarbeitet Dokumente gleichzeitig und ohne Koordination. Für Batch-Workloads mit hohem Durchsatz siehe das Beispiel zur Multithreading-Verarbeitung und den Leitfaden zur Geschwindigkeitsoptimierung .
Erstellung durchsuchbarer PDFs aus gescannten Archiven
Die durchsuchbare PDF-Ausgabe von OmniPage erfordert das Zusammensetzen einer Erkennungspipeline mit expliziten OutputSettings und OutputFormat Konfiguration, bevor sie gespeichert wird.IronOCR erzeugt durchsuchbare PDFs mit einem einzigen Methodenaufruf auf dem Ergebnisobjekt:
Kofax OmniPage-Ansatz:
// OmniPage: Searchable PDF requires OutputSettings configuration before save
public void ConvertArchiveToSearchable(string[] scannedPdfPaths, string outputDirectory)
{
using var engine = new OmniPageEngine();
engine.SetLicenseFile(licensePath);
engine.Initialize();
var recognitionSettings = new RecognitionSettings
{
Language = "English",
AccuracyMode = "Maximum",
PreserveLayout = true
};
var outputSettings = new OutputSettings
{
Format = OutputFormat.SearchablePDF,
Compression = PDFCompression.Standard,
ImageQuality = 85,
EmbedFonts = true
};
foreach (var pdfPath in scannedPdfPaths)
{
var document = engine.OpenPDF(pdfPath);
document.RecognizeAll(recognitionSettings);
string outputPath = Path.Combine(
outputDirectory,
Path.GetFileNameWithoutExtension(pdfPath) + "_searchable.pdf");
document.SaveAs(outputPath, outputSettings);
document.Dispose();
}
engine.Shutdown();
}
IronOCR Ansatz:
// IronOCR: Searchable PDF output is one method call on the result
public void ConvertArchiveToSearchable(string[] scannedPdfPaths, string outputDirectory)
{
var ocr = new IronTesseract();
foreach (var pdfPath in scannedPdfPaths)
{
using var input = new OcrInput();
input.LoadPdf(pdfPath); // All pages loaded automatically
var result = ocr.Read(input);
string outputPath = Path.Combine(
outputDirectory,
Path.GetFileNameWithoutExtension(pdfPath) + "_searchable.pdf");
result.SaveAsSearchablePdf(outputPath);
Console.WriteLine($"Processed: {Path.GetFileName(pdfPath)} ({result.Pages.Length} pages)");
}
}
SaveAsSearchablePdf bettet eine Textebene in das PDF ein, wodurch es in Dokumentenmanagementsystemen indizierbar wird, ohne das visuelle Erscheinungsbild des ursprünglichen Scans zu verändern. Der durchsuchbare PDF-Leitfaden behandelt die Optionen für die Textebene, und das PDF-OCR-Beispiel demonstriert die vollständige Verarbeitung gescannter PDFs.
Kofax OmniPageAPI zu IronOCR Mapping-Referenz
| Kofax OmniPage | IronOCR-Äquivalent |
|---|---|
using Kofax.OmniPage.CSDK; | using IronOcr; |
using Kofax.OmniPageCSDK; | using IronOcr; |
using CSDK; | using IronOcr; |
new OmniPageEngine() | Nicht erforderlich – kein Motorobjekt |
engine.SetLicenseFile(path) | IronOcr.License.LicenseKey = "key"; |
engine.Initialize() | Nicht erforderlich |
engine.Shutdown() | Nicht erforderlich |
engine.CreateDocument() | new OcrInput() |
document.AddPage(imagePath) | input.LoadImage(imagePath) |
engine.OpenPDF(pdfPath) | input.LoadPdf(pdfPath) |
engine.OpenTiff(tiffPath) | input.LoadImageFrames(tiffPath) |
document.Recognize(settings) | new IronTesseract().Read(input) |
document.RecognizeAll(settings) | new IronTesseract().Read(input) (alle Seiten auf einmal) |
document.GetText() | result.Text |
document.GetZoneText(zoneName) | input.LoadImage(path, cropRectangle) + result.Text |
document.Dispose() | using var input = new OcrInput() (automatisch) |
iterator.GetText() | result.Pages[n].Words[m].Text |
iterator.GetBoundingBox() | result.Pages[n].Words[m].X / Y / Width / Height |
iterator.GetConfidence() | result.Pages[n].Words[m].Confidence |
engine.LoadLanguageDictionary("German") | dotnet add package IronOcr.Languages.German |
settings.PrimaryLanguage = "English" | ocr.Language = OcrLanguage.English; |
settings.SecondaryLanguages = new[] {"German"} | ocr.Language = OcrLanguage.English + OcrLanguage.German; |
settings.DeskewImage = true | input.Deskew(); |
settings.DespeckleLevel = 2 | input.DeNoise(); |
settings.ContrastEnhancement = true | input.Contrast(); |
settings.AutoRotate = true | input.Deskew(); (einschließlich Rotationskorrektur) |
document.SaveAs(path, outputSettings) | result.SaveAsSearchablePdf(path) |
OutputFormat.SearchablePDF | result.SaveAsSearchablePdf(path) |
OutputFormat.XML (mit Koordinaten) | result.Pages / .Paragraphs / .Words Objektdiagramm |
FormZone mit Koordinatengrenzen | new CropRectangle(x, y, width, height) |
| Lizenzzählung pro Seite | Nicht zutreffend |
.lic Datei-Deployment | Nicht zutreffend |
| Lizenzserverkonfiguration | Nicht zutreffend |
Gängige Migrationsprobleme und Lösungen
Problem 1: Ausnahmen beim Nichtfinden der Lizenzdatei in der Produktion
Kofax OmniPage: Jedes Deployment erfordert, dass die .lic Datei an einem spezifischen Pfad existiert, der für den Anwendungsprozess zugänglich ist. Eine Deployment-Pipeline, die nicht explizit die Lizenzdatei auf den Zielserver kopiert, verursacht FileNotFoundException oder LicenseException bei der Initialisierung des Engines. Sicherheitsteams markieren häufig eingebettete .lic Dateien in Container-Images oder begehen diese in die Versionskontrolle.
**Lösung:**IronOCR liest seine Lizenz aus einer Zeichenkette. Speichern Sie den Schlüssel als Umgebungsvariable und lesen Sie ihn beim Start aus – keine Datei muss bereitgestellt, kein Pfad konfiguriert werden:
// At application startup — reads IRONOCR_LICENSE_KEY from environment
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
?? throw new InvalidOperationException("IronOCR license key not configured.");
In Docker, übergeben Sie --env IRONOCR_LICENSE_KEY=YOUR-KEY. In Azure App Service legen Sie es als Anwendungseinstellung fest. In Kubernetes wird es über ein Secret injiziert. Keine Dateieinbindung, keine Pfadkonfiguration, keine Sicherheitsprüfung für eingebettete Lizenzdateien.
Problem 2: Floating License Seats nach Prozessabsturz gesperrt
Kofax OmniPage: Wenn ein Anwendungsprozess abstürzt, von einem Watchdog beendet wird oder über Environment.FailFast beendet wird, wird engine.Shutdown() nicht ausgeführt. Die Floating-Lizenzplätze bleiben so lange ausgebucht, bis das Timeout des Lizenzservers abläuft – in der Regel 30–60 Minuten. In einer containerisierten Umgebung, in der Pods häufig neu gestartet werden, führt dieses Verhalten zur Erschöpfung des Lizenzpools.
**Lösung:**IronOCR kennt kein Konzept eines ausgecheckten Lizenzplatzes. Ein Prozessabsturz gibt keine Ressourcen frei und blockiert kein externes System. Der nächste Prozess beginnt sofort, ohne Wartezeit auf freie Plätze:
// IronOCR: Process crash has no license implications whatsoever
// Start processing immediately after any failure
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var result = new IronTesseract().Read("document.jpg"); //Neinseat to check out
Informationen zu robusten ASP.NET Core Diensten finden Sie im Leitfaden zur asynchronen OCR für Muster, die sich nahtlos in gehostete Dienste integrieren lassen und ein ordnungsgemäßes Herunterfahren ermöglichen.
Problem 3: Docker-Image-Erstellung schlägt fehl – Installationsprogramm kann nicht nicht-interaktiv ausgeführt werden
Kofax OmniPage: Der OmniPage-SDK-Installer ist ein GUI- oder semi-interaktiver Installer, der nicht sauber in einem docker build Kontext ausgeführt wird. Teams, die versuchen, das SDK in ein Container-Image einzubinden, stoßen bei der Lizenzvereinbarung des Installationsprogramms oder bei der Komponentenauswahl auf Fehler. Workarounds (Optionen für die stille Installation, vorab extrahierte DLL-Kopien) sind undokumentiert und versionsspezifisch.
Lösung: IronOCR's Dockerfile sind drei Zeilen:
FROM mcr.microsoft.com/dotnet/aspnet:8.0
RUN apt-get update && apt-get install -y libgdiplus # Single Linux dependency
COPY --from=build /app/publish /app
WORKDIR /app
ENTRYPOINT ["dotnet", "YourApp.dll"]
libgdiplus ist die einzige Systemabhängigkeit. Das IronOCR NuGet-Paket wird von dotnet restore in der Build-Phase wie jeder andere Paketverweis wiederhergestellt. Der Docker-Bereitstellungsleitfaden behandelt sowohl Debian- als auch Alpine-Basisimages, und der Linux-Bereitstellungsleitfaden behandelt distributionsspezifische Paketnamen.
Problem 4: Reaktivierung nach VM-Migration oder Cloud-Autoscaling erforderlich
Kofax OmniPage: Die OmniPage-Aktivierung ist an die Hardwareidentität gebunden. Cloud-Umgebungen, die VMs zwischen physischen Hosts migrieren, automatisch auf neue Instanzen skalieren oder Container durch neue Images ersetzen, lösen Hardware-Identitätsänderungen aus, die eine Reaktivierung erfordern. Die Kontaktaufnahme mit dem Tungsten-Support zur Reaktivierung während eines laufenden Vorfalls birgt ein zusätzliches operationelles Risiko.
Lösung: Der Lizenzschlüssel von IronOCR ist hardwareunabhängig. Derselbe Schlüssel funktioniert auf jeder Maschine, jedem Container, jeder Cloud-Region und jeder Anzahl automatisch skalierter Instanzen innerhalb der lizenzierten Stufe. Keine Reaktivierung, kein Supportkontakt, keine Ausfallzeiten:
// Identical startup code on any hardware topology
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
bool valid = IronOcr.License.IsLicensed; // Verify without a network call
Problem 5: Das Objekt "RecognitionSettings" hat kein IronOCR Äquivalent.
Kofax OmniPage: OmniPage verwendet ein RecognitionSettings Objekt (oder PreprocessingSettings je nach SDK-Version), um das Verhalten des Engines pro Dokument zu konfigurieren. Teams, die migrieren, erwarten ein paralleles Konfigurationsobjekt in IronOCR.
**Lösung:**IronOCR teilt die Konfiguration auf zwei Oberflächen auf: Vorverarbeitungsoperationen auf OcrInput und Engine-Einstellungen auf IronTesseract. Es ist kein Einstellungsobjekt vorhanden, das instanziiert werden kann:
// OmniPage settings object →IronOCR method calls on OcrInput
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English; // RecognitionSettings.Language
// ocr.Configuration.TesseractVersion = ... // Engine version already optimized
using var input = new OcrInput();
input.LoadImage(imagePath);
input.Deskew(); // settings.DeskewImage = true
input.DeNoise(); // settings.DespeckleLevel = 2
input.Contrast(); // settings.ContrastEnhancement = true
var result = ocr.Read(input);
Der Leitfaden zur Bildqualitätskorrektur listet alle verfügbaren Vorverarbeitungsmethoden auf und gibt Hinweise darauf, welche Filter für welche Dokumentqualitätsprofile geeignet sind.
Problem 6: Zonenvorlagendateien können nicht direkt portiert werden
Kofax OmniPage: OmniPage-Formvorlagen speichern Zonen-Definitionen in proprietären .fdt oder .fpf Vorlagendateien, die Feldpositionen, Erkennungstypen und Validierungsregeln pro Dokumentklasse definieren. Diese Dateien können von IronOCR nicht importiert werden.
Lösung: Extrahieren Sie die Koordinatendaten aus den Vorlagendateien (diese sind XML-basiert) und konvertieren Sie jede Zone in ein CropRectangle. Feldnamen werden zu Wörterbuchschlüsseln; Zonenkoordinaten werden direkt auf (x, y, width, height) Parameter abgebildet:
// Convert OmniPage zone definition to IronOCR CropRectangle
// OmniPage zone: Name="TotalDue" X="490" Y="612" Width="180" Height="28"
//IronOCR equivalent:
var totalDueRegion = new CropRectangle(490, 612, 180, 28);
using var input = new OcrInput();
input.LoadImage(invoicePath, totalDueRegion);
string totalDue = new IronTesseract().Read(input).Text.Trim();
Für Dokumente, bei denen Zonen pro Seite variieren, laden Sie dasselbe Bild mit unterschiedlichen CropRectangle Werten pro Region statt die Datei neu zu laden. Das Region Crop Beispiel zeigt mehrere Lesevorgänge aus einer einzigen Bildquelle.
Kofax OmniPageMigrations-Checkliste
Vor der Migration
Identifizieren Sie alle OmniPage-Integrationspunkte im Quellcode:
# Find all OmniPage namespace references
grep -r "Kofax\|OmniPage\|CSDK" --include="*.cs" --include="*.csproj" .
# Find engine lifecycle calls
grep -r "Initialize\|Shutdown\|SetLicenseFile" --include="*.cs" .
# Find document and zone creation patterns
grep -r "CreateDocument\|AddPage\|FormZone\|RecognitionSettings\|PreprocessingSettings" --include="*.cs" .
# Find output format configuration
grep -r "OutputSettings\|OutputFormat\|SaveAs\|GetText" --include="*.cs" .
# Find license file path references
grep -r "\.lic\|license\.lic\|licensePath" --include="*.cs" --include="*.config" --include="*.json" .
Bestandsaufnahme vor Beginn:
- Zähle die Dateien mit OmniPage-Namespace-Importen
- Listen Sie alle
FormTemplateundFormZoneDefinitionen auf und extrahieren Sie ihre Koordinatendaten - Identifizieren Sie, welche Sprachwörterbücher geladen sind und ordnen Sie diese
IronOcr.Languages.*NuGet-Paketen zu - Beachten Sie, welche Ausgabeformate verwendet werden (durchsuchbares PDF, Klartext, XML) und deren IronOCR Äquivalente.
- Finden Sie alle
.licDateireferenzen in Deployment-Skripten und Konfiguration
Code-Migration
- Entfernen Sie OmniPage DLL-Referenzen aus allen
.csprojDateien - Führen Sie
dotnet add package IronOcrin jedem Projekt aus, das OCR durchführt - Fügen Sie Sprachpakete für jede verwendete Sprache hinzu:
dotnet add package IronOcr.Languages.[Language] - Fügen Sie
IronOcr.License.LicenseKey = ...;an jedem Anwendungseinstiegspunkt hinzu (Program.cs, Startup.cs oder Service-Host) - Ersetzen Sie alle
using Kofax.OmniPage.CSDK;,using CSDK;und verwandte Namensraumimporte durchusing IronOcr; - Entfernen Sie alle
OmniPageEngineKonstruktionen,SetLicenseFileundInitializeAufrufe - Entfernen Sie alle
engine.Shutdown()Aufrufe und dieIDisposableImplementierungen, die ausschließlich existieren, um das Herunterfahren sicherzustellen - Ersetzen Sie
engine.CreateDocument()+document.AddPage()durchnew OcrInput()+input.LoadImage() - Ersetzen Sie
engine.OpenPDF()+ pro Seite Iteration durchinput.LoadPdf()(alle Seiten in einem Aufruf) - Ersetzen Sie
engine.OpenTiff()+ pro Frame Schleifen durchinput.LoadImageFrames() - Ersetzen Sie
document.Recognize(settings)durchnew IronTesseract().Read(input) - Konvertieren Sie
FormZoneKoordinatendaten inCropRectangle(x, y, width, height)Instanzen - Ersetzen Sie
document.GetZoneText()mit pro Regioninput.LoadImage(path, cropRectangle)+result.Text - Ersetzen Sie
document.SaveAs(path, outputSettings)für durchsuchbare PDF durchresult.SaveAsSearchablePdf(path) - Ersetzen Sie Ergebnis-Iterator-Muster durch
result.Pages/.Paragraphs/.WordsEigenschaftswanderung - Entfernen Sie
PreprocessingSettingsObjekte und ersetzen Sie Boolesche Flags durch expliziteinput.Deskew(),input.DeNoise(),input.Contrast()Methodenaufrufe - Lizenzdateipfade aus Bereitstellungsskripten, Konfigurationsdateien und Infrastructure-as-Code-Vorlagen entfernen
Nach der Migration
- Überprüfen Sie die OCR-Genauigkeit anhand einer repräsentativen Stichprobe von über 100 Dokumenten aus dem Live-Korpus – vergleichen Sie die Ergebnisse zeilenweise mit der OmniPage-Ausgabe für Rechnungen, Verträge und Formulare.
- Bestätigen Sie, dass
CropRectangle-basierte Zonenextraktion Text ergibt, der der OmniPageGetZoneText()Ausgabe für jedes gemappte Feld entspricht - Test der Verarbeitung mehrseitiger PDFs: Überprüfung der Seitenanzahl, Seitenreihenfolge und Textkontinuität
- Test der Mehrbild-TIFF-Verarbeitung: Sicherstellen, dass alle Bilder verarbeitet wurden und die Bildreihenfolge erhalten bleibt.
- Überprüfen Sie, ob die durchsuchbare PDF-Ausgabe im verwendeten Dokumentenmanagementsystem (SharePoint, OpenText usw.) indexierbar ist.
- Führen Sie einen Parallelverarbeitungstest mit mehr als 50 gleichzeitig verarbeiteten Dokumenten durch und bestätigen Sie, dass keine Thread-Sicherheitsprobleme auftreten.
- Testen Sie die Sprachpaketabdeckung: Laden Sie jedes zuvor verwendete Sprachwörterbuch über
IronOcr.Languages.*und überprüfen Sie die Erkennungsqualität - Sicherstellen, dass Prozessabstürze und Containerneustarts keine Lizenzwiederherstellungsmaßnahmen erfordern.
- Führen Sie den Docker-Build auf dem CI-Agenten aus – überprüfen Sie
dotnet restorelöst IronOCR ohne Installationsschritte - Die Validierungskonfidenzwerte sind pro Wort verfügbar und entsprechen den Datenqualitätsanforderungen jedes nachgelagerten Validierungsworkflows.
- Überprüfen Sie, dass die Anwendung ohne die
.licDatei in einem beliebigen Pfad sauber startet
Wichtigste Vorteile der Migration zu IronOCR
Die Deployment-Komplexität sinkt von Wochen auf Minuten. Ein Projekt, das zuvor SDK-Installer-Zugriff, .lic Datei-Deployment, Firewall-Konfiguration für den Lizenzserver und Infrastrukturteam-Koordination erforderte, wird jetzt über dotnet restore bereitgestellt. Ein neuer Entwickler klont das Repository und startet das Projekt. Ein neuer Produktionsserver wird über die CI/CD-Pipeline bereitgestellt. Container-Images werden ohne Installationsschritte erstellt.
Lizenzrisiken verschwinden vollständig. Es gibt keine schwebenden Plätze, die aufgebraucht werden müssen, keine Checkout-Zeitüberschreitungen, auf die gewartet werden muss, keine Hardware-Fingerabdrücke, die reaktiviert werden müssen, und keine .lic Dateien, die in Deployment-Pipelines geschützt werden müssen. Ein Anwendungsabsturz um 3 Uhr morgens gibt nichts frei und sperrt nichts. Der diensthabende Techniker startet den Prozess neu; Die OCR-Operation wird sofort wieder aufgenommen. Die IronOCR Produktseite umfasst alle Lizenzstufen.
Die plattformübergreifende Bereitstellung wird zu einem Standard- NuGet Ziel. macOS-Entwicklungsrechner funktionieren ohne Plattformausnahme. Für Linux-Produktionsserver ist keine SDK-Version vom Januar 2026 erforderlich. Docker-Container werden aus einem standardmäßigen mcr.microsoft.com/dotnet/aspnet Basis-Image mit einer Systemabhängigkeit erstellt. Der gleiche IronOcr Paketbezug in .csproj erzeugt einen funktionierenden Build auf Windows, Linux und macOS. Die Azure-Bereitstellungsanleitung und die AWS-Bereitstellungsanleitung enthalten Informationen zur cloudspezifischen Konfiguration.
Der parallele Durchsatz skaliert mit der Hardware. Die gemeinsam genutzte Engine-Architektur von OmniPage erfordert Sperrmechanismen, die die gleichzeitige Erkennung serialisieren. Die zustandslosen IronTesseract Instanzen von IronOCR skalieren linear mit den verfügbaren CPU-Kernen. Durch die Verdopplung der Kernanzahl eines Batchverarbeitungsservers verdoppelt sich der Durchsatz ohne Konfigurationsänderungen oder zusätzliche Lizenzen.
Der Zugang zu strukturierten Daten ist unmittelbar. OcrResult.Pages, Paragraphs, Lines, Words und Characters offenbaren die vollständige Dokumentstruktur als navigierbares .NET-Objektgraph. Konfidenz und Koordinaten pro Wort sind Eigenschaften jedes Wortobjekts. Es gibt keine sekundäre Exportpipeline, keine Formatkonfiguration und keine Dateiausgabe, die für den Zugriff auf Positionsdaten erforderlich ist.
Die Kosten sind fix und vorhersehbar. Die Kombination aus SDK-Lizenz, jährlicher Wartung und Laufzeitgebühren pro Seite bei OmniPage führt zu Kosten, die mit der Nutzung skalieren und jährlich wiederkehren.IronOCR bei $999–$2.999 unbefristet ist ein einmaliger Kauf. Ein Workflow mit einem Volumen von 500.000 Seiten pro Jahr, der Gebühren pro Seite generierte, amortisierte die IronOCR Lizenzkosten innerhalb weniger Wochen. Die IronOCR -Dokumentation und die Tutorials sind ohne Supportvertrag verfügbar.
