Umstellung von Windows.Media.Ocr auf IronOCR
Dieser Leitfaden bietet einen schrittweisen Migrationspfad for .NET-Entwickler, die von Windows.Media.OCR zu IronOCR wechseln. Sie umfasst das Entfernen von Namespaces, Änderungen an Projektdateien, Beispiele für die Codemigration für die bei der Migration am häufigsten auftretenden Muster sowie eine praktische Checkliste zur Validierung der abgeschlossenen Umstellung.
Warum von Windows.Media.OCR (UWP/WinRT OCR) migrieren?
Windows.Media.OCR funktioniert innerhalb seiner Grenzen gut. Diese Grenzen sind eng, und Projekte wachsen regelmäßig über sie hinaus. Die Gründe, aus denen Teams migrieren, lassen sich in vorhersehbare Kategorien einteilen.
Der Windows TFM blockiert jedes nicht-Windows-Ziel. Die Projektdatei muss einen net*-windows* Target Framework Moniker vor der Windows.Media.Ocr Namespace-Auflösung zur Kompilierungszeit deklarieren. Diese Deklaration ist kein Laufzeit-Flag — es ist eine Build-Einschränkung, die sich auf jedes Projekt auswirkt, das Ihr Projekt referenziert. Eine gemeinsam genutzte OCR-Dienstbibliothek, eine Web-API, ein auf Linux bereitgestellter Hintergrund-Worker – sie alle unterliegen dieser Einschränkung. Das Entfernen bedeutet das Entfernen von Windows.Media.OCR.
Die Sprachverfügbarkeit wird zur Laufzeit vom Betriebssystem bestimmt, nicht zur Build-Zeit vom Entwickler. OcrEngine.TryCreateFromLanguage gibt null zurück, wenn das angeforderte Sprachpaket auf dem Host-Rechner nicht vorhanden ist. Der Entwickler kann kein Sprachpaket aus dem Code installieren, eines mit dem Anwendungspaket bündeln oder ein Fallback-Modell bereitstellen. In automatisierten Umgebungen – Build-Agenten, CI-Runner, minimale Cloud-VMs, Container – werden Sprachpakete selten installiert. Produktionsfehler, die durch ein fehlendes Sprachpaket verursacht werden, lassen sich durch Betrachten des Codes nicht reproduzieren; Sie erfordern die Überprüfung der Betriebssystemkonfiguration des Zielrechners.
Keine Vorverarbeitung bedeutet keinen Wiederherstellungspfad für suboptimale Eingaben. Die API akzeptiert einen SoftwareBitmap und erzeugt Text. Die Verbesserung der Bildqualität zwischen diesen beiden Punkten liegt vollständig in der Verantwortung des Entwicklers, der separate Windows Imaging Component-APIs verwendet, die selbst nur unter Windows verfügbar sind. Handyfotos, schief eingescannte Flachbettscans und fotokopierte Dokumente beeinträchtigen die Genauigkeit unbemerkt, da es keinen integrierten Mechanismus gibt, um das Ergebnis zu diagnostizieren oder zu verbessern.
PDF ist das gängigste Dokumentformat in Enterprise-Workflows. Windows.Media.OCR verfügt über keinen PDF-Eingabepfad. Die Verarbeitung eines gescannten PDF-Dokuments erfordert einen externen Renderer, eine seitenweise Rasterisierung und eine manuelle Zusammenstellung der Ergebnisse. Dieser Renderer fügt eine Abhängigkeit, lizenzrechtliche Überlegungen und eine separate Fehlerquelle hinzu – genau die Komplexität, die eine "kostenlose und integrierte" Bibliothek eigentlich vermeiden sollte.
Die serverseitige Bereitstellung wird strukturell nicht unterstützt. Windows.Media.OCR ist für Client-Anwendungen vorgesehen. Für die Ausführung auf Windows Server ist das Feature Pack "Desktop Experience" erforderlich, was die Kosten für virtuelle Maschinen und die Komplexität der Infrastruktur erhöht. Eine Docker-Bereitstellung ist nicht möglich. Azure Functions unter Linux, AWS Lambda und alle Linux-basierten Container-Workloads können einfach nicht auf die API verweisen.
Der WinRT-Async-Stack ist nicht mit Standard-.NET-Mustern kompatibel. Sechs oder mehr verkettete await Aufrufe — StorageFile, Stream, BitmapDecoder, SoftwareBitmap, Null-Überprüfung, RecognizeAsync — sind erforderlich, bevor ein einzelnes Zeichen gelesen wird. Die Integration dieser Kette in einen Hintergrunddienst, eine Parallel.ForEach-Schleife oder einen Standard-ASP.NET-Controller ist umständlich. Die WinRT IAsyncOperation Maschinen befindet sich darunter, und die Interaktion mit dem .NET Task Modell erzeugt subtile Randfälle in Nicht-UI-Kontexten.
Das grundsätzliche Problem
Die Sprachverfügbarkeit in Windows.Media.OCR ist eine Laufzeitunbekannte, die zum Zeitpunkt der Bereitstellung nicht aufgelöst werden kann:
// Windows.Media.Ocr: language availability decided by OS admin, not the developer
// Returns null on any machine without the language pack installed
var engine = OcrEngine.TryCreateFromLanguage(
new Windows.Globalization.Language("ja-JP"));
if (engine == null)
throw new InvalidOperationException(
"Japanese OCR unavailable — install the Japanese language pack in Windows Settings.");
//Neinrecovery path.Neinbundled model.Neinfallback.
// IronOCR: language availability is a NuGet package, not an OS configuration
// dotnet add package IronOcr.Languages.Japanese
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.Japanese;
var result = ocr.Read("invoice.jpg"); // Works on any OS, any machine
Console.WriteLine(result.Text);
##IronOCR vs. Windows.Media.Ocr (UWP/WinRT OCR): Funktionsvergleich
Die folgende Tabelle umfasst den gesamten Funktionsumfang, der für Migrationsentscheidungen relevant ist.
| Feature | Windows.Media.Ocr | IronOCR |
|---|---|---|
| Plattform: Windows 10/11 | Ja | Ja |
| Plattform: Windows Server | Eingeschränkt (Desktop-Erfahrung erforderlich) | Ja |
| Plattform: Linux | Nein | Ja |
| Plattform: macOS | Nein | Ja |
| Plattform: Docker-Container | Nein | Ja |
| Plattform: Azure Functions (Linux) | Nein | Ja |
| Plattform: AWS Lambda | Nein | Ja |
| Anforderungen an das Projekt TFM | net*-windows* erforderlich | Keine (Standard-TFMs) |
| Installation | In Windows integriert (kein NuGet) | Einzelnes NuGet-Paket (IronOcr) |
| Bildeingabe (JPG, PNG, BMP) | Ja (über die WinRT-Pipeline) | Ja |
| PDF-Eingabe | Nein | Ja (Muttersprachler) |
| Mehrseitige TIFF-Eingabe | Nein | Ja |
| Stream- und Byte-Array-Eingabe | Nein (nur StorageFile) | Ja |
| Quellsprache | Vom Betriebssystem installierte Sprachpakete | Über 125 gebündelte NuGet-Pakete |
| Sprachportabilität | Nein (maschinenabhängig) | Ja (mit der Anwendung bereitstellen) |
| Mehrsprachige Simultanübertragung | Nein | Ja |
| Vorverarbeitung: Entzerrung | Nein | Ja (input.Deskew()) |
| Vorverarbeitung: Rauschunterdrückung | Nein | Ja (input.DeNoise()) |
| Vorverarbeitung: Kontrast | Nein | Ja (input.Contrast()) |
| Vorverarbeitung: binarisieren | Nein | Ja (input.Binarize()) |
| Durchsuchbare PDF-Ausgabe | Nein | Ja (result.SaveAsSearchablePdf()) |
| Vertrauenswerte pro Wort | Nein | Ja (word.Confidence) |
| Strukturierte Ausgabe (Absätze, Zeilen, Wörter) | Nur Zeilen | Seiten, Absätze, Zeilen, Wörter, Zeichen |
| BarCode-Erkennung während der OCR | Nein | Ja |
| Regionsbasierte OCR | Nein | Ja (CropRectangle) |
| Synchroner OCR-Pfad | Nein | Ja |
| Thread-sichere parallele Verarbeitung | Beschränkt | Voll |
| Kommerzielle Unterstützung | Nein (Windows-Plattform-Team) | Ja |
| Lizenzmodell | Kostenlos (in Windows integriert) | Unbefristet ($999 Lite, $1.499 Pro, $2.999 Enterprise) |
Schnellstart: Migration von Windows.Media.Ocr (UWP/WinRT OCR) zu IronOCR
Schritt 1: Ersetzen des NuGet-Pakets
Windows.Media.OCR verfügt über kein NuGet-Paket – es ist Teil der Windows Runtime und wird über das Windows TFM aufgelöst. Das Entfernen bedeutet, die Windows-spezifischen Namespace-Referenzen und, soweit möglich, das Windows TFM aus der Projektdatei zu entfernen.
Entfernen Sie die Windows.Media.OCR-Namespaces aus allen Quelldateien:
# Audit all files referencing Windows OCR namespaces
grep -r "Windows.Media.Ocr\|Windows.Graphics.Imaging\|Windows.Storage" --include="*.cs" .
Installieren Sie IronOCR:
Das IronOCR NuGet Paket zielt auf net6.0, net7.0, net8.0 und net9.0 ohne plattform-spezifische TFM. Nach dem Entfernen der Windows OCR Namespaces aktualisieren Sie den <TargetFramework> in der Projektdatei von net8.0-windows10.0.19041.0 zu net8.0 (oder der entsprechenden Version), sofern keine anderen WinRT-APIs im Projekt verbleiben.
Schritt 2: Namespaces aktualisieren
Ersetzen Sie die drei Windows-OCR-Namespaces durch einen einzigen IronOCR-Namespace:
// Before (Windows.Media.Ocr)
using Windows.Media.Ocr;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Globalization;
// After (IronOCR)
using IronOcr;
Schritt 3: Lizenz initialisieren
Fügen Sie den Lizenzinitialisierungsaufruf einmal beim Start der Anwendung ein — in Program.cs, Startup.cs oder dem Application Host Builder:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"Ein kostenloser Testschlüssel ist auf der IronOCR-Lizenzierungsseite verfügbar und entfernt das Testwasserzeichen zu Evaluierungszwecken.
Beispiele für die Code-Migration
Ersetzen der WinRT-Async-Kette in einem Hintergrunddienst
Windows.Media.OCR erfordert mindestens sechs verkettete asynchrone Operationen, bevor die Erkennung beginnt. In einem Hintergrunddienst, der eine Dokumentenwarteschlange verarbeitet, läuft diese Kette innerhalb einer Schleife — und die SoftwareBitmap Entsorgung, Null-Überprüfung und WinRT IAsyncOperation Interoperation verursachen bei jeder Iteration Reibung.
Windows.Media.OCR-Ansatz:
// Windows.Media.Ocr: full async chain required per document
// Requires net8.0-windows10.0.19041.0 TFM — cannot deploy to Linux workers
public async Task<List<string>> ProcessQueueAsync(IEnumerable<string> imagePaths)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language pack installed on this machine.");
var results = new List<string>();
foreach (var path in imagePaths)
{
// Each document: 4 async steps before RecognizeAsync
var file = await StorageFile.GetFileFromPathAsync(path);
using var stream = await file.OpenAsync(FileAccessMode.Read);
var decoder = await BitmapDecoder.CreateAsync(stream);
var bitmap = await decoder.GetSoftwareBitmapAsync();
var ocrResult = await engine.RecognizeAsync(bitmap);
results.Add(ocrResult.Text);
bitmap.Dispose();
}
return results;
}
IronOCR Ansatz:
// IronOCR: one call per document, no WinRT, no SoftwareBitmap, no null checks
// Runs on Windows, Linux, macOS, Docker — same binary, no TFM change
public List<string> ProcessQueue(IEnumerable<string> imagePaths)
{
var results = new List<string>();
foreach (var path in imagePaths)
{
var result = new IronTesseract().Read(path);
results.Add(result.Text);
}
return results;
}
Die IronOCR-Version eliminiert den StorageFile Round-Trip, die BitmapDecoder, den SoftwareBitmap Lebenszyklus und die Null-Überprüfungsfunktion. Für asynchron-native Dienste bietet IronOCR einen asynchronen Pfad, der sich sauber in Task-basierte Pipelines integriert, ohne den WinRT-Interop-Overhead. Das IronTesseract-Einrichtungshandbuch enthält Empfehlungen zum Instanzlebenszyklus für Szenarien mit Warteschlangen mit hohem Durchsatz.
Wegfall der Software-Bitmap-Konvertierung für Bilddaten im Arbeitsspeicher
Anwendungen, die Bilddaten bereits im Speicher haben — von einem Netzwerk-Download, einem Datenbank-Blob oder einem Kameraaufnahme-Callback — müssen diese Daten in einen SoftwareBitmap umwandeln, bevor Windows.Media.Ocr sie verarbeiten kann. Dieser Konvertierungspfad geht durch BitmapDecoder, die einen Stream erfordert, was bedeutet, dass das Byte-Array in einen MemoryStream kopiert werden muss.IronOCR akzeptiert Byte-Arrays und Streams direkt.
Windows.Media.OCR-Ansatz:
// Windows.Media.Ocr: byte array must travel through WinRT stream → BitmapDecoder → SoftwareBitmap
public async Task<string> RecognizeFromBytesAsync(byte[] imageBytes)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language available.");
// Copy byte array into InMemoryRandomAccessStream (WinRT type)
using var ras = new Windows.Storage.Streams.InMemoryRandomAccessStream();
using var writer = new Windows.Storage.Streams.DataWriter(ras);
writer.WriteBytes(imageBytes);
await writer.StoreAsync();
ras.Seek(0);
var decoder = await BitmapDecoder.CreateAsync(ras);
var bitmap = await decoder.GetSoftwareBitmapAsync();
var result = await engine.RecognizeAsync(bitmap);
bitmap.Dispose();
return result.Text;
}
IronOCR Ansatz:
// IronOCR: byte array loads directly into OcrInput — no conversion, no WinRT types
public string RecognizeFromBytes(byte[] imageBytes)
{
using var input = new OcrInput();
input.LoadImage(imageBytes); // direct byte array load
var result = new IronTesseract().Read(input);
return result.Text;
}
Der Windows.Media.Ocr Pfad erfordert InMemoryRandomAccessStream — ein WinRT-Typ, der außerhalb von Windows nicht instanziiert werden kann — plus DataWriter, BitmapDecoder und SoftwareBitmap. Der IronOCR Pfad verwendet OcrInput.LoadImage(byte[]) und erzeugt das Ergebnis in zwei Zeilen. Siehe den Stream-Eingabe-Leitfaden für Stream-basierte Lade-Muster, die der gleichen Einfachheit wie die Byte-Array-Eingabe folgen.
Mehrsprachige Dokumentenverarbeitung ohne Betriebssystemkoordination
Eine mehrsprachige Rechnungs-Pipeline, die englische, französische und deutsche Texte in einem einzigen Durchlauf erkennen muss, stößt bei Windows.Media.OCR an architektonische Grenzen. Die API erlaubt nur eine Sprache pro Engine-Instanz. Die Verarbeitung eines mehrsprachigen Dokuments erfordert entweder eine Single-Language-Engine, die die bestmögliche Vermutung trifft, oder die dreimalige Durchführung der Erkennung und das Zusammenführen der Ergebnisse – beides liefert jedoch keine zuverlässigen Ergebnisse.
Windows.Media.OCR-Ansatz:
// Windows.Media.Ocr: one language per engine, no simultaneous multi-language support
// Each language requires a separate language pack installed on the machine
public async Task<string> RecognizeMultiLanguageAsync(SoftwareBitmap bitmap)
{
// Must pick ONE language — no simultaneous recognition
var engine = OcrEngine.TryCreateFromLanguage(
new Windows.Globalization.Language("en-US"));
if (engine == null)
throw new InvalidOperationException("English language pack not installed.");
// French and German text on the same document will be misrecognized
var result = await engine.RecognizeAsync(bitmap);
return result.Text;
}
IronOCR Ansatz:
// IronOCR: simultaneous multi-language recognition in a single pass
// Language packs are NuGet packages — no OS coordination required
// dotnet add package IronOcr.Languages.French
// dotnet add package IronOcr.Languages.German
public string RecognizeMultiLanguage(string documentPath)
{
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;
var result = ocr.Read(documentPath);
// Structured output: walk paragraphs with location data
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"[{paragraph.X},{paragraph.Y}] {paragraph.Text}");
}
}
return result.Text;
}
IronOCR kombiniert Sprachmodelle in einem einzigen Erkennungsdurchlauf, sodass nicht mehr erraten werden muss, welche Sprache in einem bestimmten Bereich verwendet wird. Der mehrsprachige OCR-Leitfaden behandelt die Installation von Sprachpaketen und die OcrLanguage-Enum-Werte für alle 125+ unterstützten Sprachen. Der Sprachenindex listet den vollständigen Katalog auf, einschließlich der Schriftfamilien CJK, Arabisch, Hebräisch, Devanagari und Kyrillisch.
Aktivierung von serverseitiger OCR mit paralleler Verarbeitung
Windows.Media.OCR kann nicht in einem Serverkontext unter Linux ausgeführt werden, kann nicht von einem Standard-ASP.NET Core-Controller auf einem plattformübergreifenden Host aufgerufen werden und weist in Serverszenarien ein undefiniertes Verhalten auf, wenn es von Nicht-UI-Threads aufgerufen wird. Ein Team, das einen OCR-Endpunkt von einer reinen Windows-Desktopanwendung auf eine skalierbare Web-API umstellt, erfüllt alle drei Anforderungen gleichzeitig.
Windows.Media.OCR-Ansatz:
// Windows.Media.Ocr: cannot run on Linux, Docker, or Azure Functions on Linux
// UWP/WinRT assumptions about thread context cause failures in ASP.NET pipelines
// The entire approach below is non-deployable outside Windows with Desktop Experience
[HttpPost("ocr")]
public async Task<IActionResult> RecognizeDocument(IFormFile file)
{
// WinRT requires STA thread context in some scenarios — not guaranteed in ASP.NET
// Cannot deploy this controller to a Linux App Service plan
using var stream = file.OpenReadStream();
// InMemoryRandomAccessStream is a WinRT type — does not exist on Linux
// var ras = new InMemoryRandomAccessStream(); // compile error on net8.0 TFM
return StatusCode(503, "Windows-only — cannot deploy cross-platform.");
}
IronOCR Ansatz:
// IronOCR: ASP.NET Core controller running on Linux, Docker, or Windows — same code
[HttpPost("ocr")]
public async Task<IActionResult> RecognizeDocument(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("No file provided.");
using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream);
var imageBytes = memoryStream.ToArray();
using var input = new OcrInput();
input.LoadImage(imageBytes);
input.Deskew(); // straighten uploaded scans automatically
input.DeNoise(); // remove mobile camera noise
var result = new IronTesseract().Read(input);
return Ok(new
{
Text = result.Text,
Confidence = result.Confidence,
Pages = result.Pages.Count
});
}
Dieser Controller lässt sich ohne Änderungen auf Linux App Service, Docker und AWS Lambda bereitstellen. Der Docker-Bereitstellungs-Leitfaden behandelt die einzige apt-get Abhängigkeit, die auf dem Linux-Basisbild erforderlich ist. Der Azure-Bereitstellungsleitfaden und der AWS-Leitfaden führen durch die cloudspezifische Konfiguration.
Erstellen durchsuchbarer PDFs aus gescannten Archiven
Windows.Media.OCR erzeugt reine Textzeichenfolgen. Es hat kein Ausgabeformat über OcrResult.Text und die Liniengeometrie in OcrResult.Lines hinaus. Die Konvertierung eines gescannten Archivs in durchsuchbare PDF-Dokumente – eine häufige Anforderung für Dokumentenmanagementsysteme und Compliance-Workflows – erfordert eine dritte Bibliothek zum Aufbau der PDF-Ausgabeschicht.IronOCR erzeugt nativ durchsuchbare PDF-Dateien.
Windows.Media.OCR-Ansatz:
// Windows.Media.Ocr: plain text output only
// Searchable PDF requires external PDF library + manual text layer construction
public async Task<string> GetTextOnlyAsync(SoftwareBitmap bitmap)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language available.");
var result = await engine.RecognizeAsync(bitmap);
// result.Text is all you get
// Producing a searchable PDF requires an entirely separate library
return result.Text;
}
IronOCR Ansatz:
// IronOCR: searchable PDF output is one method call on OcrResult
public void ProcessScannedArchive(IEnumerable<string> pdfPaths, string outputDirectory)
{
foreach (var sourcePdf in pdfPaths)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(sourcePdf); // native PDF input — no external renderer
input.Deskew(); // correct scan misalignment per page
input.DeNoise(); // remove scanner speckle
var result = ocr.Read(input);
var outputFileName = Path.Combine(
outputDirectory,
Path.GetFileNameWithoutExtension(sourcePdf) + "-searchable.pdf");
result.SaveAsSearchablePdf(outputFileName);
Console.WriteLine($"Processed: {sourcePdf} → {outputFileName} " +
$"({result.Pages.Count} pages, {result.Confidence:F1}% confidence)");
}
}
Der SaveAsSearchablePdf Aufruf bettet eine Textebene über das ursprüngliche gescannte Bild ein, behält die visuelle Treue bei und ermöglicht die Volltextsuche und Ctrl+F in jedem PDF-Viewer. Das durchsuchbare PDF-Handbuch behandelt Optionen für die Einbettung von Schriftarten, die Positionierung von Textebenen und die mehrseitige Ausgabe. Die Anleitung zur PDF-Eingabe behandelt passwortgeschützte PDF-Dateien und die Auswahl von Seitenbereichen bei großen Archiven.
Extrahieren strukturierter Daten mit Koordinaten auf WORD-Ebene
Windows.Media.Ocr stellt OcrResult.Lines mit Zeilenebene Text und Begrenzungsrechtecken bereit. Pro-Wort-Geometrie existiert in OcrLine.Words mit OcrWord.BoundingRect, aber es gibt keine Absätze, keine Vertrauenswerte und keine Zeichenebene-Daten. Für die Extraktion von Formularfeldern oder das Parsen von Rechnungspositionen reicht die Zeilengeometrie nicht aus – es sind Absatzgrenzen und Wort-Konfidenzwerte erforderlich, um strukturierte Felder vom umgebenden Text zu unterscheiden.
Windows.Media.OCR-Ansatz:
// Windows.Media.Ocr: line-level geometry, no paragraph grouping, no confidence scores
public async Task<List<string>> ExtractLineTextAsync(SoftwareBitmap bitmap)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language available.");
var result = await engine.RecognizeAsync(bitmap);
var lineTexts = new List<string>();
foreach (var line in result.Lines)
{
// Line text + word bounding rects — no paragraph grouping, no confidence
lineTexts.Add(line.Text);
}
return lineTexts;
}
IronOCR Ansatz:
// IronOCR: full hierarchy — pages, paragraphs, lines, words, characters
// Each element carries coordinates and confidence for downstream validation
public void ExtractStructuredData(string documentPath)
{
var result = new IronTesseract().Read(documentPath);
Console.WriteLine($"Overall confidence: {result.Confidence:F1}%");
foreach (var page in result.Pages)
{
Console.WriteLine($"\n--- Page {page.PageNumber} ---");
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Paragraph at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");
// Filter words below confidence threshold for validation workflows
var lowConfidence = paragraph.Words
.Where(w => w.Confidence < 70)
.ToList();
if (lowConfidence.Any())
{
Console.WriteLine($" Low-confidence words: " +
string.Join(", ", lowConfidence.Select(w => $"'{w.Text}' ({w.Confidence:F0}%)")));
}
}
}
}
Das strukturierte Ergebnismodell — Pages, Paragraphs, Lines, Words, Characters — liefert die Koordinaten- und Vertrauensdaten, die für die Formularfeldauswertung, die Rechnungsparsing und die Dokumentenlayoutanalyse erforderlich sind. Der Ergebnis-Lese-Leitfaden dokumentiert den vollständigen OcrResult Objektgraph. Der Leitfaden zur Konfidenzbewertung erklärt, wie man Wort-für-Wort-Konfidenzwerte verwendet, um unsichere Extraktionen zur manuellen Überprüfung zu kennzeichnen.
Referenz zur Zuordnung der Windows.Media.OCR-API zu IronOCR
| Windows.Media.Ocr | IronOCR |
|---|---|
OcrEngine.TryCreateFromLanguage(lang) | new IronTesseract() + ocr.Language = OcrLanguage.X |
OcrEngine.TryCreateFromUserProfileLanguages() | new IronTesseract() (Englisch Standard; (keine Null-Rückgabe) |
engine.RecognizeAsync(softwareBitmap) | ocr.Read("image.jpg") oder ocr.Read(ocrInput) |
StorageFile.GetFileFromPathAsync(path) | ocr.Read("path") direkt (keine Dateihandhabe erforderlich) |
file.OpenAsync(FileAccessMode.Read) | Eliminiert — OcrInput lädt direkt |
BitmapDecoder.CreateAsync(stream) | input.LoadImage(stream) über OcrInput |
decoder.GetSoftwareBitmapAsync() | Eliminiert — kein SoftwareBitmap in IronOCR |
SoftwareBitmap (WinRT-Typ) | Eliminiert — OcrInput akzeptiert Bytes, Streams, Dateipfade |
InMemoryRandomAccessStream (WinRT-Typ) | new MemoryStream() + input.LoadImage(stream) |
OcrResult.Text | OcrResult.Text |
OcrResult.Lines | OcrResult.Lines (auch Pages, Paragraphs, Words, Characters) |
OcrLine.Text | OcrResult.Lines[i].Text |
OcrLine.Words | OcrResult.Words oder page.Paragraphs[i].Words |
OcrWord.BoundingRect | word.X, word.Y, word.Width, word.Height |
| Kein Äquivalent | result.Confidence (insgesamt) / word.Confidence (pro Wort) |
| Kein Äquivalent | result.SaveAsSearchablePdf("output.pdf") |
| Kein Äquivalent | input.LoadPdf("document.pdf") |
| Kein Äquivalent | input.Deskew(), input.DeNoise(), input.Contrast() |
| Kein Äquivalent | ocr.Language = OcrLanguage.A + OcrLanguage.B (gleichzeitig) |
| Kein Äquivalent | ocr.Configuration.ReadBarCodes = true |
| Kein Äquivalent | input.LoadImage(byteArray) |
Gängige Migrationsprobleme und Lösungen
Problem 1: Projektdatei benötigt nach der Migration weiterhin Windows TFM
Windows.Media.Ocr: Die <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> Deklaration ist erforderlich, damit die WinRT-Typen aufgelöst werden können. Das Entfernen von Windows.Media.OCR-Referenzen ohne Überprüfung auf andere WinRT-Abhängigkeiten im selben Projekt kann dazu führen, dass die TFM erhalten bleibt, was plattformübergreifende Builds verhindert.
Lösung: Entfernen Sie zunächst alle Verweise auf den Windows-OCR-Namespace und suchen Sie anschließend im Projekt nach verbleibenden WinRT-API-Verwendungen, bevor Sie die TFM ändern:
# Find remaining WinRT API usage before removing the Windows TFM
grep -r "Windows\." --include="*.cs" .
grep -r "WinRT\|IAsyncOperation\|StorageFile\|SoftwareBitmap" --include="*.cs" .
Falls keine WinRT-Referenzen mehr vorhanden sind, aktualisieren Sie die Projektdatei:
<!-- Before -->
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<!-- After -->
<TargetFramework>net8.0</TargetFramework>
Falls andere WinRT-Funktionen (Windows-Benachrichtigungen, Shell-Integration, XAML) weiterhin verwendet werden, abstrahieren Sie den OCR-Aufruf hinter einer Schnittstelle und stellen Sie plattformspezifische Implementierungen bereit, anstatt das TFM projektweit zu entfernen.
Problem 2: Null-Engine-Prüfungen haben kein IronOCR-Äquivalent
Windows.Media.Ocr: Jeder Aufruf von TryCreateFromLanguage und TryCreateFromUserProfileLanguages kann null zurückgeben. Der gesamte vorhandene Code enthält Null-Check-Guard-Klauseln, die bei einer Null-Engine einen Fehler auslösen oder eine Verzweigung ausführen.
**Lösung:**IronOCR löst bei Initialisierungsfehlern strukturierte Ausnahmen aus, anstatt null zurückzugeben. Entfernen Sie die Null-Check-Guard-Klauseln. Verwenden Sie ein Standard-try/catch, wenn Sie Initialisierungsfehler an einen Aufrufer melden müssen:
// Before: null-check pattern
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("OCR unavailable.");
// After: no null — IronTesseract throws if misconfigured
try
{
var result = new IronTesseract().Read("document.jpg");
}
catch (IronOcr.Exceptions.OcrException ex)
{
// structured exception with diagnostic message
logger.LogError("OCR failed: {Message}", ex.Message);
}
Problem 3: SoftwareBitmap-Parameter in bestehenden Methodensignaturen
Windows.Media.Ocr: Utility-Methoden, Dienste und Repository-Klassen können SoftwareBitmap als Parameter-Typ akzeptieren. Diese Methodensignaturen können nicht kompiliert werden, wenn das Windows TFM entfernt wird.
Lösung: Ersetzen Sie SoftwareBitmap Parameter durch byte[] oder Stream. IronOCR's OcrInput akzeptiert beides direkt. Die Aufrufstellen, die zuvor einen SoftwareBitmap konstruiert haben, können stattdessen ihre zugrunde liegenden Daten übergeben:
// Before: SoftwareBitmap parameter — cannot compile cross-platform
public async Task<string> RecognizeAsync(SoftwareBitmap bitmap) { ... }
// After: byte array parameter — compiles on all platforms
public string Recognize(byte[] imageBytes)
{
using var input = new OcrInput();
input.LoadImage(imageBytes);
return new IronTesseract().Read(input).Text;
}
Problem 4: Asynchrone Aufrufer können das synchrone IronOCR nicht direkt verwenden
Windows.Media.Ocr: Jeder Erkennungsaufruf ist async. Anrufer im gesamten Code verwenden await und geben Task<string> zurück. Das Umschalten auf IronOCR's synchronen Read Methode innerhalb einer async Methode funktioniert, kann jedoch blockierende Aufrufe in Kontexten einführen, in denen async architektonisch war.
**Lösung:**IronOCR bietet einen asynchronen Pfad für Aufrufer, die diesen benötigen. Verwenden Sie Task.Run für CPU-gebundenes Wrapping in bestehenden asynchronen Methoden oder verwenden Sie die native asynchrone API:
// Option A: wrap synchronous call in Task.Run for async callers
public async Task<string> RecognizeAsync(string imagePath)
{
return await Task.Run(() => new IronTesseract().Read(imagePath).Text);
}
// Option B:IronOCR async path
// See: https://ironsoftware.com/csharp/ocr/how-to/async/
Der Leitfaden zur asynchronen OCR dokumentiert die integrierte asynchrone API für Kontexte, in denen "Fire-and-Forget"- oder Fortschrittsberichts-Muster erforderlich sind.
Problem 5: Das Windows-Sprach-Tag-Format lässt sich nicht direkt zuordnen
Windows.Media.Ocr: Sprachen werden unter Verwendung von BCP-47-String-Tags angegeben, die an Windows.Globalization.Language("fr-FR") übergeben werden. Diese String-Tags haben in IronOCR keine direkte Entsprechung.
Lösung: Ordnen Sie BCP-47-Sprachtags der OcrLanguage Enum zu. Die Zuordnung ist für gängige Sprachen unkompliziert:
// Before: BCP-47 string tags
var engine = OcrEngine.TryCreateFromLanguage(
new Windows.Globalization.Language("fr-FR"));
// After: OcrLanguage enum
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.French;
// Also: OcrLanguage.German, OcrLanguage.Japanese, OcrLanguage.Arabic, etc.
Die vollständige Zuordnung ist im IronOCR-Sprachkatalog verfügbar. Für Sprachen, die nicht im Haupt-Enum aufgelistet sind, deckt benutzerdefinierte Sprachpaketunterstützung das Laden von .traineddata Dateien direkt ab.
Problem 6: FileAccessMode.Read hat keinen Ersatz
Windows.Media.Ocr: file.OpenAsync(FileAccessMode.Read) ist ein WinRT-spezifisches Dateiöffnungs-Muster. Das FileAccessMode Enum existiert nicht im Standard .NET.
Lösung: Ersetzen Sie es durch ein Standard System.IO.File.ReadAllBytes oder FileStream. OcrInput akzeptiert beides:
// Before: WinRT file access
using var stream = await file.OpenAsync(FileAccessMode.Read);
// After: standard .NET
var imageBytes = File.ReadAllBytes(imagePath);
using var input = new OcrInput();
input.LoadImage(imageBytes);
Windows.Media.OCR (UWP/WinRT OCR) Migrations-Checkliste
Vor der Migration
Überprüfen Sie den Code, bevor Sie Änderungen vornehmen:
# Find all Windows OCR namespace usages
grep -rn "using Windows.Media.Ocr" --include="*.cs" .
grep -rn "using Windows.Graphics.Imaging" --include="*.cs" .
grep -rn "using Windows.Storage" --include="*.cs" .
grep -rn "using Windows.Globalization" --include="*.cs" .
# Find WinRT type usages
grep -rn "OcrEngine\|SoftwareBitmap\|BitmapDecoder\|StorageFile" --include="*.cs" .
grep -rn "TryCreateFromLanguage\|TryCreateFromUserProfileLanguages\|RecognizeAsync" --include="*.cs" .
grep -rn "InMemoryRandomAccessStream\|DataWriter\|FileAccessMode" --include="*.cs" .
# Find project files with Windows TFM
grep -rn "net.*-windows" --include="*.csproj" .
# Count files requiring changes
grep -rl "Windows.Media.Ocr\|Windows.Graphics.Imaging\|SoftwareBitmap" --include="*.cs" . | wc -l
Notieren Sie die Anzahl der betroffenen Dateien, die verwendeten Sprachtags ("en-US", "fr-FR", etc.), und ob WinRT-Typen in öffentlichen Methodensignaturen erscheinen (diese erfordern API-Oberflächenänderungen zusätzlich zu internen Umschreibungen).
Code-Migration
- Installieren Sie das
IronOcrNuGet-Paket:dotnet add package IronOcr - Fügen Sie den Lizenzinitialisierungsaufruf in
Program.csoderStartup.cshinzu:IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; - Entfernen Sie
using Windows.Media.Ocr;aus allen Quelldateien - Entfernen Sie
using Windows.Graphics.Imaging;aus allen Quelldateien - Entfernen Sie
using Windows.Storage;aus allen Quelldateien - Entfernen Sie
using Windows.Globalization;aus allen Quelldateien - Fügen Sie
using IronOcr;zu allen Dateien hinzu, die OCR ausführen - Ersetzen Sie jeden
OcrEngine.TryCreateFromLanguage(new Language("xx-XX"))Aufruf mitnew IronTesseract()und setzen Sieocr.Language = OcrLanguage.X - Ersetzen Sie jeden
OcrEngine.TryCreateFromUserProfileLanguages()Aufruf mitnew IronTesseract() - Entfernen Sie alle Null-Check-Guard-Klauseln bei den Ergebnissen der Engine-Erstellung
- Ersetzen Sie
SoftwareBitmapParameter in Methodensignaturen durchbyte[]oderStream - Ersetzen Sie
StorageFile+BitmapDecoder+SoftwareBitmapKonstruktionsketten durchOcrInput.LoadImage(path),OcrInput.LoadImage(bytes)oderOcrInput.LoadImage(stream) - Ersetzen Sie
engine.RecognizeAsync(bitmap)mitocr.Read(path)oderocr.Read(input) - Ersetzen Sie
InMemoryRandomAccessStreamundDataWriterNutzung mitMemoryStream - Ersetzen Sie Windows BCP-47 Sprachtag-Strings durch
OcrLanguageEnum-Werte; Installieren Sie die erforderlichen NuGet-Sprachpakete - Aktualisieren Sie
<TargetFramework>in.csprojDateien, um den-windowsX.Y.ZSuffix zu entfernen, wobei keine anderen WinRT-APIs verbleiben
Nach der Migration
- Bestätigen Sie, dass das Projekt auf
net8.0(oder Ihre Zielversion) ohne das Windows TFM Suffix kompiliert wird - Bestätigen Sie, dass das Projekt auf einer Linux-Umgebung oder einem Docker-Container mit
mcr.microsoft.com/dotnet/aspnet:8.0kompiliert und ausgeführt wird - Überprüfen Sie, ob der OCR-Ausgabetext für jeden Dokumenttyp in der Suite mit den erwarteten Ergebnissen übereinstimmt
- Überprüfen Sie, ob alle zuvor unterstützten Sprachen mit den IronOCR-Sprach-NuGet-Paketen korrekte Ergebnisse liefern
- Überprüfen Sie, ob mehrsprachige Dokumente in einem einzigen Erkennungsdurchlauf korrekte Ergebnisse liefern
- Bestätigen Sie, dass kein
NullReferenceExceptionoderInvalidOperationExceptionbei der Initialisierung der Engine auf Rechnern ohne installierte Windows-Sprachpakete auftritt - Überprüfen Sie, dass
result.ConfidenceWerte innerhalb der erwarteten Bereiche für saubere und qualitativ minderwertige Eingabedokumente liegen - Wenn die Anwendung Dokumente erstellt, verifizieren Sie, dass
SaveAsSearchablePdfAusgaben korrekt in einem PDF-Viewer geöffnet werden und Textsuche unterstützen - Führen Sie alle vorhandenen parallelen oder multithreaded Verarbeitungspfade aus und überprüfen Sie die Thread-Sicherheit unter Last
- Stellen Sie die Anwendung in der Zielumgebung bereit (Docker, Azure App Service, AWS, Linux-Server) und führen Sie mindestens einen vollständigen End-to-End-OCR-Vorgang durch
Wichtigste Vorteile der Migration zu IronOCR
Die plattformübergreifende Bereitstellung wird zu einer Konfigurationsentscheidung, nicht zu einer Neuprogrammierung. Nach der Migration läuft die OCR-Komponente identisch unter Windows, Linux, macOS, Docker und bei allen großen Cloud-Anbietern. Die Verlagerung einer OCR-Workload von einer Windows-VM in einen Linux-Container zur Senkung der Hosting-Kosten ist ein Bereitstellungsvorgang. Der Linux-Bereitstellungsleitfaden und der Docker-Bereitstellungsleitfaden behandeln das Hinzufügen einer einzigen Zeile für die Abhängigkeiten, das bei Linux-Basis-Images erforderlich ist.
Die Sprachunterstützung wird mit der Anwendungsbinärdatei mitgeliefert. Sprachpakete werden als NuGet-Pakete installiert und sind versionsgebunden an das IronOCR-Paket. Die Sprachen, die Ihre Anwendung erkennen kann, sind in der Projektdatei definiert und auf jedem Rechner identisch – Entwickler-Workstation, CI-Runner, Staging-Server und Produktionshost. Keine Koordination mit dem Betriebssystemadministrator, keine Gruppenrichtlinienausnahme, keine Null-Prüfung zur Laufzeit.
OCR-Genauigkeit verbessert sich ohne externe Werkzeuge. Die Vorverarbeitungspipeline — Deskew, DeNoise, Contrast, Binarize, Sharpen, Scale — läuft innerhalb von IronOCR, bevor die Erkennungs-Engine das Bild sieht. Dokumente, die mit Windows.Media.OCR aufgrund von Scan-Versatz oder Rauschen schlechte Ergebnisse lieferten, werden verbessert, ohne dass externe Bildverarbeitungs-Abhängigkeiten hinzugefügt werden müssen. Der Leitfaden zur Bildqualitätskorrektur und der Filter-Assistent helfen dabei, die richtige Filterkombination für jeden Dokumenttyp zu finden.
PDF-Workflows werden in einer einzigen Bibliothek zusammengefasst. Der externe PDF-Renderer, der zur Verknüpfung von Windows.Media.OCR und PDF-Eingaben erforderlich war, wird nicht mehr benötigt. Gescanntes PDF-Archiv wird durch denselben IronTesseract.Read Aufruf wie Bilder verarbeitet. Die Ausgabe als durchsuchbares PDF ist eine Methode des Ergebnisobjekts. Die Architektur mit zwei Bibliotheken entfällt, ebenso wie die damit verbundene Versionsverwaltung, der Lizenzierungsaufwand und die Bereitstellungsfläche.
Strukturiertes Ergebnis ermöglicht Dokument-Intelligenz-Pipelines. Die OcrResult Hierarchie — Pages, Paragraphs, Lines, Words, Characters — mit Pro-Element-Koordinaten und Vertrauenswerten liefert die benötigten Daten für die Rechnungsfelderfassung, Formularparsing und Dokumentklassifikation. Die zeilenweise Ausgabe von Windows.Media.OCR reicht für diese Arbeitsabläufe nicht aus. Mit IronOCR sind vertrauensgefilterte Wortextraktion, Absatzgrenzenerkennung und koordinatenbasierte Feldzuordnung erstklassige Funktionen, die keine zusätzlichen Bibliotheken erfordern.
Eine unbefristete Lizenz ersetzt eine unbegrenzte Abhängigkeit von der Infrastruktur. Die Kosten für die Wartung der Windows-Sprachpaket-Installation auf einer heterogenen Maschinenflotte, die Lizenzierung der Windows Server Desktop Experience und eine ausschließlich auf Windows basierende CI-Infrastruktur sind real, aber diffus – sie zeigen sich in IT-Tickets und Infrastrukturbudgets, nicht als Einzelposten im OCR-Budget. Eine $999IronOCR Lite Lizenz eliminiert diesen Overhead für ein Einzelentwicklerprojekt. The Professional License for 1.499 $ covers ten developers. Beide sind einmalige Käufe, bei denen ein Jahr lang Updates inbegriffen sind.
