Wie man Async und Multithreading in C# verwendet
Die Migration von Mindeezu IronOCR verlagert die Dokumentenverarbeitung von externen Cloud-Servern auf Ihre eigene Infrastruktur – wodurch die Abrechnung pro Seite, die Datenübertragung durch Dritte und die Netzwerkverfügbarkeit als Laufzeitabhängigkeit entfallen. Die folgenden Abschnitte behandeln den Paketaustausch, Namespace-Aktualisierungen und vier praktische Vorher-Nachher-Code-Szenarien: Extraktion von Rechnungszonen, Verarbeitung mehrseitiger Beleg-PDFs, Vorverarbeitung von Finanzdokumenten und Archivierung durchsuchbarer PDFs.
Warum von Mindeeabwandern?
Mindee löst ein reales Problem auf elegante Weise: Man sendet ein Dokument ein und erhält strukturierte JSON-Felder. Für Teams, bei denen die Übermittlung von Finanzdokumenten an eine externe API akzeptabel ist und das Volumen moderat bleibt, liefert es schnelle Ergebnisse. Der Auslöser für die Migration tritt üblicherweise ein, wenn sich eine von mehreren Bedingungen ändert.
Finanzdaten überschreiten eine Compliance-Grenze. Mindee's ParseAsync<InvoiceV4> lädt das vollständige Dokument auf externe Server hoch. IBAN-Codes, Bankleitzahlen, Lieferanten-EINs und detaillierte Positionsnummern werden über das öffentliche Internet übertragen und auf Hardware verarbeitet, die sich außerhalb Ihrer Kontrolle befindet. Die SOC 2 Typ II Zertifizierung bestätigt, dass Mindeedie Sicherheitsstandards einhält; Es sorgt nicht dafür, dass Ihre Dokumente innerhalb Ihres Sicherheitsbereichs bleiben. Wenn eine Compliance-Prüfung, ein neuer Kundenvertrag oder eine Datenresidenzvorschrift die Grenze für die Cloud-Verarbeitung durch Dritte zieht, wird die Architektur von Mindeeunabhängig von ihrer Extraktionsgenauigkeit disqualifiziert.
Die Kosten pro Seite steigen mit Ihrem Verbrauch. Das Starter-Paket umfasst 1.000 Seiten pro Monat für 49 $/Monat. Der Pro-Tarif bietet 5.000 Seiten pro Monat zum Preis von 499 US-Dollar pro Monat. Bei mehrseitigen PDFs wird jede Seite gezählt. Entwicklungsläufe werden auf das Kontingent angerechnet. Ein Team, das 4.000 Rechnungen pro Monat bearbeitet, zahlt 499 US-Dollar pro Monat – 5.988 US-Dollar pro Jahr –, wobei sich dieser Betrag jedes Jahr neu festlegt und mit jedem Mengenwachstum steigt. Bei 24.000 Seiten pro Monat verhandeln Sie über Enterprise Preise. Die unbefristete Lizenz von IronOCR für 1.499 US-Dollar (Professional -Version) deckt ein unbegrenztes Dokumentenvolumen ab und amortisiert sich im Vergleich zu MindeePro in weniger als vier Monaten.
Asynchrones Polling breitet sich durch Ihren gesamten Stack aus. Jede Mindee-Operation ist asynchron, da jede Operation eine Netzwerkanfrage darstellt. Diese obligatorische asynchrone Kette setzt sich kaskadierend über Controller, Service-Schichten und Worker-Klassen fort. Wenn das Netzwerk nicht verfügbar ist oder der Dienst von Mindeeausfällt, führt die Kaskade zu einem Ausfall ohne lokale Ausweichmöglichkeit.IronOCR verarbeitet synchron — Arbeit mit lokaler CPU — und umhüllt in Task.Run, wo asynchrone Schnittstellen für architektonische Konsistenz erforderlich sind.
Der vorgefertigte API-Katalog hat eine feste Grenze. Mindeedeckt InvoiceV4, ReceiptV5, PassportV1 und einen kleinen Katalog anderer Dokumenttypen ab. Jeder Dokumenttyp außerhalb dieser Liste erfordert ein Enterprise-Plan-Modelltraining: Sammlung von Beispielen, Beschriftung, Trainingszeit und Vorlaufzeit, bevor die API verfügbar ist. Für jeden neuen Dokumententyp, den Ihr Unternehmen benötigt, ist ein separater Auftrag an einen externen Dienstleister erforderlich.IronOCR verarbeitet jeden Dokumenttyp mit dem gleichen IronTesseract().Read() Aufruf; Das Hinzufügen eines neuen Dokumenttyps bedeutet das Schreiben von Extraktionsmustern, nicht das Aushandeln eines Schulungsvertrags.
Die Verwaltung von API-Schlüsseln erhöht die operative Flexibilität. Mindee-Zugangsdaten müssen sicher serverseitig gespeichert, regelmäßig ausgetauscht und vor unbefugtem Zugriff geschützt werden. Die Netzwerkausgangsregeln müssen ausgehende HTTPS-Verbindungen zu Mindee-Endpunkten zulassen. Die Wiederholungslogik muss HttpRequestException und MindeeException von den unvermeidlichen Netzwerkfehlern handhaben. Mit dem Entfernen von Mindeeverschwindet die gesamte operative Oberfläche: keine Anmeldeinformationen, keine Ausgangsregeln, keine Wiederholungsmechanismen für die Netzwerk-E/A.
Ausgeschlossen sind abgeschottete und eingeschränkte Umgebungen. Regierungsauftragnehmer, Unterauftragnehmer der Verteidigungsindustrie, Gesundheitsnetzwerke mit strengen ausgehenden Internetkontrollen und industrielle Systeme, die in Einrichtungen ohne zuverlässige Internetverbindung eingesetzt werden, können Mindeenicht wie vorgesehen nutzen.IronOCR läuft identisch in Docker-Containern ohne ausgehenden Zugriff, in Azure Functions mit Austrittsbeschränkungen und in vollständig abgeschotteten Umgebungen. Es besteht keine Cloud-Abhängigkeit zur Laufzeit. Details zu den Bereitstellungsstufen finden Sie auf der IronOCR -Lizenzseite .
Das grundsätzliche Problem
Jedes von Mindeeverarbeitete Finanzdokument überschreitet eine Netzwerkgrenze, die Sie nicht kontrollieren:
// Mindee: invoice with bank details leaves your infrastructure on this line
var response = await _client.ParseAsync<InvoiceV4>(new LocalInputSource("invoice.pdf"));
// IBAN, routing number, EIN, line items — all transmitted to Mindeecloud
// IronOCR: same invoice, same result, zero data transmission
var result = new IronTesseract().Read("invoice.pdf");
// All processing local — bank details never leave your machine
##IronOCR vs. Mindee: Funktionsvergleich
Die folgende Tabelle erfasst die architektonischen und leistungsbezogenen Unterschiede, die den Migrationsentscheidungen zugrunde liegen.
| Feature | Mindee | IronOCR |
|---|---|---|
| Verarbeitungsort | MindeeCloud-Server | Lokaler Rechner / Ihre Infrastruktur |
| Internetverbindung zur Laufzeit erforderlich | Stets | Niemals |
| Datenübertragung | Vollständiges Dokument wird pro Anruf hochgeladen | None |
| Kosten pro Dokument | Ja (pro Seite, abhängig vom Tarif) | Nein (unbefristete Lizenz) |
| Startpreis | 49 $/Monat (1.000 Seiten) | $999 einmalig (Lite) |
| Offline-/Air-Gap-Unterstützung | Nicht unterstützt | Volle Unterstützung |
| Lokale Bereitstellung | Nicht verfügbar | Einzige Option |
| Rechnungsanalyse | Vorgefertigte strukturierte API (InvoiceV4) | OCR + regionenbasierte oder reguläre Ausdrucksextraktion |
| Beleganalyse | Vorgefertigte strukturierte API (ReceiptV5) | OCR + Extraktionsmuster |
| Beliebige Dokumenttypen | Ohne individuelle Schulung nicht verfügbar. | Vollständige Unterstützung, jedes Dokument |
| Kundenspezifisches Modelltraining | Enterprise + Vorlaufzeit | Nicht erforderlich |
| API-Aufrufmuster | Asynchron obligatorisch (Netzwerk-E/A) | Synchron (asynchron optional) |
| Ratenbegrenzung | Planabhängig | None |
| PDF-Eingabe | Ja | Ja (nativ, keine Konvertierung) |
| Verarbeitung mehrseitiger PDFs | Ja | Ja |
| Durchsuchbare PDF-Ausgabe | Nein | Ja (result.SaveAsSearchablePdf()) |
| Bildvorverarbeitung | Keine exponiert | Entzerren, Rauschen entfernen, Kontrast erhöhen, Binärisierung, Schärfen, Skalieren |
| regionenbasierte Extraktion | Feldkoordinaten als Antwort | CropRectangle bei Eingabe |
| Unterstützung für mehr als 125 Sprachen | Beschränkt | Ja (im Paket enthalten, keine Tessdata-Verwaltung) |
| Barcode-Lesung | Nein | Ja (gleichzeitig mit OCR) |
| Strukturierte Wortkoordinaten | Nein | Ja (Seiten, Absätze, Zeilen, Wörter) |
| Thread-Sicherheit | Nicht verfügbar (Netzwerk-E/A pro Anruf) | Eingebaut |
| Plattformübergreifend | Cloud (plattformunabhängig) | Windows, Linux, macOS, Docker, Azure, AWS |
| .NET -Kompatibilität | .NET Standard 2.0+ | .NET Framework 4.6.2+, .NET 5/6/7/8/9 |
| Kommerzielle Unterstützung | Ja | Ja |
Schnellstart: Migration von Mindeezu IronOCR
Schritt 1: Ersetzen des NuGet-Pakets
Entfernen Sie das Mindee-Paket:
dotnet remove package Mindee
Installieren Sie IronOCR über NuGet :
Schritt 2: Namespaces aktualisieren
Ersetzen Sie den Mindee-Namensraumblock durch den IronOCR Namensraum:
// Before (Mindee)
using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;
using Mindee.Product.Receipt;
using Mindee.Product.FinancialDocument;
// After (IronOCR)
using IronOcr;
Schritt 3: Lizenz initialisieren
Fügen Sie den Lizenzschlüssel beim Start der Anwendung hinzu (vor dem ersten OCR-Aufruf):
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"Beispiele für die Code-Migration
Extraktion von Rechnungsfeldern mithilfe von Dokumentzonen
Mindee gibt vorausgelesene Felder an bekannten Stellen zurück, da das serverseitige Modell weiß, wo Rechnungsnummern, Daten und Summen üblicherweise erscheinen. Das IronOCR-Äquivalent verwendet CropRectangle, um spezifische Zonen des Dokuments zu lesen, was der räumlichen Wahrnehmung von Mindee's Extraktion entspricht, ohne das Dokument zu übertragen.
Mindee-Ansatz:
using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;
public class MindeeZoneExtractor
{
private readonly MindeeClient _client;
public MindeeZoneExtractor(string apiKey)
{
_client = new MindeeClient(apiKey);
}
public async Task<(string invoiceNumber, string supplierName, decimal? total)>
ExtractKeyFieldsAsync(string filePath)
{
// Document transmitted to Mindee— spatial field detection happens server-side
var inputSource = new LocalInputSource(filePath);
var response = await _client.ParseAsync<InvoiceV4>(inputSource);
var prediction = response.Document.Inference.Prediction;
// Fields arrive pre-parsed; no zone configuration required on your end
return (
prediction.InvoiceNumber?.Value,
prediction.SupplierName?.Value,
prediction.TotalAmount?.Value
);
}
}
IronOCR Ansatz:
using IronOcr;
using System.Text.RegularExpressions;
public class IronOcrZoneExtractor
{
private readonly IronTesseract _ocr = new IronTesseract();
public (string invoiceNumber, string supplierName, string total)
ExtractKeyFields(string filePath)
{
// Zone 1: supplier name — top 12% of document, full width
var headerRegion = new CropRectangle(0, 0, 850, 120);
using var headerInput = new OcrInput();
headerInput.LoadImage(filePath, headerRegion);
var supplierResult = _ocr.Read(headerInput);
// Zone 2: invoice number and date — upper-right quadrant
var metaRegion = new CropRectangle(450, 80, 400, 100);
using var metaInput = new OcrInput();
metaInput.LoadImage(filePath, metaRegion);
var metaResult = _ocr.Read(metaInput);
// Zone 3: totals block — bottom-right 20%
var totalsRegion = new CropRectangle(500, 800, 350, 200);
using var totalsInput = new OcrInput();
totalsInput.LoadImage(filePath, totalsRegion);
var totalsResult = _ocr.Read(totalsInput);
var invoiceNumber = Regex.Match(
metaResult.Text,
@"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
RegexOptions.IgnoreCase).Groups[1].Value;
var total = Regex.Match(
totalsResult.Text,
@"Total\s*(?:Due)?\s*:?\s*\$?([\d,]+\.?\d*)",
RegexOptions.IgnoreCase).Groups[1].Value;
// Supplier name is the first substantial text line in the header zone
var supplierName = supplierResult.Text
.Split('\n')
.FirstOrDefault(l => l.Trim().Length > 4)
?.Trim();
return (invoiceNumber, supplierName, total);
}
}
Zonenbasierte OCR entspricht der Intention der räumlichen Felderkennung von Mindee: bestimmte Bereiche des Dokuments lesen, anstatt reguläre Ausdrücke auf die gesamte Seite anzuwenden. CropRectangle(x, y, width, height) nimmt Pixel-Koordinaten an, daher erfordert das Tuning das Abmessen an einer repräsentativen Beispielrechnung. Der regionenbasierte OCR-Leitfaden behandelt Koordinatenmessung und Strategien zur Überlappung von Zonen. Für Rechnungen mit variablen Layouts liefert die Kombination von Zonenauswertung mit Ganzseiten-Regex auf result.Text die zuverlässigsten Ergebnisse.
Verarbeitung mehrseitiger Spesenabrechnungen im PDF-Format
Mindee akzeptiert eine PDF-Datei und verarbeitet jede Seite als separate Dokumenteinheit, wobei pro Seite ein strukturiertes Ergebnis zurückgegeben wird.IronOCR liest mehrseitige PDFs nativ durch OcrInput.LoadPdf(), verarbeitet alle Seiten in einem einzigen Aufruf und liefert result.Pages mit seitenweisem Inhalt und Wortkoordinaten.
Mindee-Ansatz:
using Mindee;
using Mindee.Input;
using Mindee.Product.Receipt;
public class MindeeExpenseReportProcessor
{
private readonly MindeeClient _client;
public MindeeExpenseReportProcessor(string apiKey)
{
_client = new MindeeClient(apiKey);
}
public async Task<List<ExpenseSummary>> ProcessExpenseReportAsync(string pdfPath)
{
var summaries = new List<ExpenseSummary>();
// Mindeeprocesses per-document; each page of a PDF is a separate upload
// For a 10-page expense report: 10 API calls, 10 pages billed
var inputSource = new LocalInputSource(pdfPath);
var response = await _client.ParseAsync<ReceiptV5>(inputSource);
var prediction = response.Document.Inference.Prediction;
summaries.Add(new ExpenseSummary
{
MerchantName = prediction.SupplierName?.Value,
Date = prediction.Date?.Value?.ToString(),
TotalAmount = prediction.TotalAmount?.Value ?? 0m,
Category = prediction.Category?.Value
});
return summaries;
}
}
IronOCR Ansatz:
using IronOcr;
using System.Text.RegularExpressions;
public class IronOcrExpenseReportProcessor
{
private readonly IronTesseract _ocr = new IronTesseract();
public List<ExpenseSummary> ProcessExpenseReport(string pdfPath)
{
// Load entire multi-page PDF in one call — no per-page upload
using var input = new OcrInput();
input.LoadPdf(pdfPath); // all pages loaded locally
var result = _ocr.Read(input);
var summaries = new List<ExpenseSummary>();
// Each page maps to one receipt in the expense report
foreach (var page in result.Pages)
{
var pageText = page.Text;
// Skip pages without receipt content
if (!pageText.Contains("Total", StringComparison.OrdinalIgnoreCase))
continue;
var merchantName = page.Lines
.FirstOrDefault(l => l.Text.Trim().Length > 4)
?.Text.Trim();
var totalMatch = Regex.Match(
pageText,
@"(?:Total|Amount\s+Due|Grand\s+Total)\s*:?\s*\$?([\d,]+\.\d{2})",
RegexOptions.IgnoreCase);
var dateMatch = Regex.Match(
pageText,
@"\b(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})\b");
var categoryMatch = Regex.Match(
pageText,
@"(?:Category|Dept|Department)\s*:?\s*(.+)",
RegexOptions.IgnoreCase);
summaries.Add(new ExpenseSummary
{
PageNumber = page.PageNumber,
MerchantName = merchantName,
Date = dateMatch.Success ? dateMatch.Value : null,
TotalAmount = totalMatch.Success
? decimal.Parse(totalMatch.Groups[1].Value.Replace(",", ""))
: 0m,
Category = categoryMatch.Success
? categoryMatch.Groups[1].Value.Trim()
: null,
Confidence = page.Words.Any()
? page.Words.Average(w => (double)w.Confidence)
: 0
});
}
return summaries;
}
}
public class ExpenseSummary
{
public int PageNumber { get; set; }
public string MerchantName { get; set; }
public string Date { get; set; }
public decimal TotalAmount { get; set; }
public string Category { get; set; }
public double Confidence { get; set; }
}
Die Verarbeitung eines 10-seitigen Spesenabrechnungs-PDFs mit Mindeeerzeugt 10 API-Aufrufe und 10 abgerechnete Seiten.IronOCR verarbeitet dieselbe Datei in einem einzigen lokalen Aufruf ohne Kosten pro Seite und ohne Netzwerk-Roundtrip pro Seite. Die result.Pages Sammlung bietet seitenweises Text-, wortweise Begrenzungsrahmen- und Linienpositionen für layoutbewusste Extraktion. Informationen zum passwortgeschützten Laden von PDFs und zur Auswahl von Seitenbereichen finden Sie im PDF-Eingabeleitfaden , sowie im Leitfaden für strukturierte Leseergebnisse Informationen zur Arbeit mit Wortkoordinaten.
Pipeline zur Vorverarbeitung gescannter Rechnungen
Mindees Cloud-Verarbeitung wendet vor der Feldextraktion eine eigene Bildnormalisierung an. Die Qualität dieser Normalisierung ist undurchsichtig – man hat keine Kontrolle darüber und keinen Einblick in die durchgeführte Vorverarbeitung. Wenn eine gescannte Rechnung Verzerrungen, Schatten oder einen geringen Kontrast aufweist, gibt Mindeeniedrigere Konfidenzwerte zurück, ohne dass es eine Möglichkeit gibt, den Scan vor der Einreichung zu verbessern.IronOCR legt die Vorverarbeitungspipeline explizit offen, sodass Sie genau die Korrekturen anwenden können, die ein bestimmtes Dokument benötigt, bevor die Erkennung ausgeführt wird.
Mindee-Ansatz:
using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;
public class MindeeScanProcessor
{
private readonly MindeeClient _client;
public MindeeScanProcessor(string apiKey)
{
_client = new MindeeClient(apiKey);
}
public async Task<ScanResult> ProcessScannedInvoiceAsync(string scanPath)
{
// Mindeeapplies internal normalization — no developer control over preprocessing
var inputSource = new LocalInputSource(scanPath);
var response = await _client.ParseAsync<InvoiceV4>(inputSource);
var prediction = response.Document.Inference.Prediction;
return new ScanResult
{
InvoiceNumber = prediction.InvoiceNumber?.Value,
Total = prediction.TotalAmount?.Value,
// Per-field confidence: only proxy for scan quality
InvoiceNumberConfidence = prediction.InvoiceNumber?.Confidence,
TotalConfidence = prediction.TotalAmount?.Confidence
};
}
}
IronOCR Ansatz:
using IronOcr;
using System.Text.RegularExpressions;
public class IronOcrScanProcessor
{
private readonly IronTesseract _ocr = new IronTesseract();
public ScanResult ProcessScannedInvoice(string scanPath)
{
// First pass: read without preprocessing
var quickResult = _ocr.Read(scanPath);
OcrResult result;
if (quickResult.Confidence < 75)
{
// Low confidence — apply full preprocessing pipeline
using var input = new OcrInput();
input.LoadImage(scanPath);
input.Deskew(); // correct page rotation up to ±45 degrees
input.DeNoise(); // remove scanner artifacts and speckle
input.Contrast(); // normalize contrast for faded or overexposed scans
input.Sharpen(); // sharpen blurred text edges
result = _ocr.Read(input);
}
else
{
result = quickResult;
}
var invoiceNumber = Regex.Match(
result.Text,
@"Invoice\s*(?:Number|#|No\.?)?\s*:?\s*([A-Z0-9\-]+)",
RegexOptions.IgnoreCase).Groups[1].Value;
var total = Regex.Match(
result.Text,
@"(?:Total|Amount\s+Due)\s*:?\s*\$?([\d,]+\.\d{2})",
RegexOptions.IgnoreCase).Groups[1].Value;
return new ScanResult
{
InvoiceNumber = invoiceNumber,
Total = total,
DocumentConfidence = result.Confidence,
PreprocessingApplied = quickResult.Confidence < 75
};
}
}
public class ScanResult
{
public string InvoiceNumber { get; set; }
public string Total { get; set; }
public double DocumentConfidence { get; set; }
public bool PreprocessingApplied { get; set; }
}
Das zweistufige Verfahren – zuerst schnelles Lesen, dann Vorverarbeitung bei geringer Konfidenz – vermeidet den Aufwand einer vollständigen Vorverarbeitung bei sauberen Scans. Für die häufigsten Szenarien bei Kreditoren (leicht geneigte Flachbettscans, Faxartefakte, fotokopierte Rechnungen) stellen Deskew() und DeNoise() gemeinsam den größten Teil der Erkennungsgenauigkeit wieder her. Der Leitfaden zur Bildqualitätskorrektur dokumentiert alle verfügbaren Filter und gibt Hinweise darauf, welche Kombinationen bei verschiedenen Scanfehlern am besten geeignet sind. Der Leitfaden zur Bildausrichtungskorrektur behandelt die automatische Drehung von Dokumenten, die auf dem Kopf gescannt wurden.
Durchsuchbare PDF-Archivierung für Finanzdokumente
Mindee erzeugt keine PDF-Ausgabe. Die Architektur ist rein eingabebasiert: Man sendet ein Dokument und empfängt JSON-Felder. Teams, die gescannte Rechnungen in einem durchsuchbaren Format archivieren, müssen diese Datenverarbeitungskette getrennt von der Extraktion durch Mindeeverwalten.IronOCR generiert durchsuchbare PDFs direkt aus demselben Erkennungsdurchlauf, der für die Feldextraktion verwendet wird – keine zusätzliche Bibliothek, kein zweiter Verarbeitungsschritt.
Mindee-Ansatz:
using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;
public class MindeeArchiveProcessor
{
private readonly MindeeClient _client;
public MindeeArchiveProcessor(string apiKey)
{
_client = new MindeeClient(apiKey);
}
public async Task ArchiveInvoiceAsync(string scanPath, string archivePath)
{
// Extract fields via Mindee(document transmitted to cloud)
var inputSource = new LocalInputSource(scanPath);
var response = await _client.ParseAsync<InvoiceV4>(inputSource);
var prediction = response.Document.Inference.Prediction;
// Mindeereturns no PDF output — searchable PDF requires a separate library
// (e.g., iTextSharp, PdfSharp, or a separate OCR library)
// The scan at scanPath is the only PDF available for archiving;
// it remains image-only with no embedded text layer
Console.WriteLine($"Fields extracted. Searchable PDF: not available from Mindee.");
Console.WriteLine($"Invoice: {prediction.InvoiceNumber?.Value}");
}
}
IronOCR Ansatz:
using IronOcr;
using System.Text.RegularExpressions;
public class IronOcrArchiveProcessor
{
private readonly IronTesseract _ocr = new IronTesseract();
public ArchiveResult ArchiveInvoice(string scanPath, string archiveOutputPath)
{
// Apply preprocessing before recognition and archiving
using var input = new OcrInput();
input.LoadPdf(scanPath); // works with both PDF scans and image files
input.Deskew();
input.DeNoise();
var result = _ocr.Read(input);
// Extract fields from the same recognition pass
var invoiceNumber = Regex.Match(
result.Text,
@"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
RegexOptions.IgnoreCase).Groups[1].Value;
var vendor = result.Pages.FirstOrDefault()?.Lines
.FirstOrDefault(l => l.Text.Trim().Length > 4)
?.Text.Trim();
var totalMatch = Regex.Match(
result.Text,
@"Total\s*(?:Due)?\s*:?\s*\$?([\d,]+\.\d{2})",
RegexOptions.IgnoreCase);
// Write searchable PDF to archive in one call — no separate library needed
result.SaveAsSearchablePdf(archiveOutputPath);
return new ArchiveResult
{
InvoiceNumber = invoiceNumber,
VendorName = vendor,
Total = totalMatch.Success ? totalMatch.Groups[1].Value : null,
ArchivePath = archiveOutputPath,
DocumentConfidence = result.Confidence,
PageCount = result.Pages.Count()
};
}
}
public class ArchiveResult
{
public string InvoiceNumber { get; set; }
public string VendorName { get; set; }
public string Total { get; set; }
public string ArchivePath { get; set; }
public double DocumentConfidence { get; set; }
public int PageCount { get; set; }
}
result.SaveAsSearchablePdf() bettet die erkannte Textebene direkt in das Ausgabe-PDF ein und erzeugt eine Datei, bei der jedes Wort in jedem PDF-Viewer oder Unternehmensdokumentenverwaltungssystem auswählbar und durchsuchbar ist. Feldextraktion und Archivierung laufen im selben Durchgang — ein _ocr.Read(input) Aufruf liefert sowohl result.Text zum Mustermatching als auch result.SaveAsSearchablePdf() für das Archiv. Der durchsuchbare PDF-Leitfaden behandelt Ausgabeoptionen einschließlich HOCR-Export und die PDF-OCR-Anwendungsseitenseite deckt Produktionsbereitstellungsmuster für Dokumentenarchivierungspipelines ab.
Entfernen des benutzerdefinierten Endpunkts FinancialDocumentV1
Mindee's FinancialDocumentV1 API behandelt sowohl Rechnungen als auch Quittungen durch automatische Erkennung des Dokumenttyps. Teams, die es nutzen, eliminieren die Verzweigungslogik, allerdings auf Kosten einer höheren Cloud-Abhängigkeit – jedes Dokument wird unabhängig vom Typ hochgeladen. Durch den Einsatz von IronOCR werden Positionsdaten auf Wortebene verwendet, um die Dokumentstruktur zu erkennen und die Extraktionslogik ohne Cloud-Aufruf zu steuern.
Mindee-Ansatz:
using Mindee;
using Mindee.Input;
using Mindee.Product.FinancialDocument;
public class MindeeFinancialRouter
{
private readonly MindeeClient _client;
public MindeeFinancialRouter(string apiKey)
{
_client = new MindeeClient(apiKey);
}
public async Task<FinancialSummary> ProcessFinancialDocumentAsync(string filePath)
{
// All financial documents uploaded for auto-detection and parsing
var inputSource = new LocalInputSource(filePath);
var response = await _client.ParseAsync<FinancialDocumentV1>(inputSource);
var prediction = response.Document.Inference.Prediction;
return new FinancialSummary
{
DocumentType = prediction.DocumentType?.Value, // "INVOICE" or "RECEIPT"
InvoiceNumber = prediction.InvoiceNumber?.Value,
Date = prediction.Date?.Value?.ToString(),
TotalAmount = prediction.TotalAmount?.Value,
SupplierName = prediction.SupplierName?.Value,
CustomerName = prediction.CustomerName?.Value
};
}
}
IronOCR Ansatz:
using IronOcr;
using System.Text.RegularExpressions;
public class IronOcrFinancialRouter
{
private readonly IronTesseract _ocr = new IronTesseract();
public FinancialSummary ProcessFinancialDocument(string filePath)
{
var result = _ocr.Read(filePath);
var text = result.Text;
// Detect document type using structural keywords from word data
var isInvoice = DetectInvoice(result);
if (isInvoice)
{
return new FinancialSummary
{
DocumentType = "INVOICE",
InvoiceNumber = Regex.Match(text,
@"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
RegexOptions.IgnoreCase).Groups[1].Value,
Date = Regex.Match(text,
@"(?:Invoice\s+)?Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})",
RegexOptions.IgnoreCase).Groups[1].Value,
TotalAmount = ParseAmount(text,
@"Total\s*(?:Due|Amount)?\s*:?\s*\$?([\d,]+\.\d{2})"),
SupplierName = ExtractTopLine(result),
CustomerName = Regex.Match(text,
@"Bill\s+To\s*:?\s*\n?(.+)",
RegexOptions.IgnoreCase).Groups[1].Value.Trim()
};
}
else
{
// Receipt structure: merchant at top, no "Bill To" section
return new FinancialSummary
{
DocumentType = "RECEIPT",
Date = Regex.Match(text,
@"\b(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})\b").Value,
TotalAmount = ParseAmount(text,
@"(?:Total|Amount\s+Due|Grand\s+Total)\s*:?\s*\$?([\d,]+\.\d{2})"),
SupplierName = ExtractTopLine(result)
};
}
}
private bool DetectInvoice(OcrResult result)
{
// Invoice indicators: "Invoice", "Bill To", "Due Date", line items with quantities
var text = result.Text;
var invoiceSignals = new[] { "Invoice", "Bill To", "Due Date", "Purchase Order" };
return invoiceSignals.Any(s =>
text.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0);
}
private string ExtractTopLine(OcrResult result)
{
return result.Pages
.FirstOrDefault()
?.Lines
.FirstOrDefault(l => l.Text.Trim().Length > 4)
?.Text.Trim();
}
private decimal? ParseAmount(string text, string pattern)
{
var match = Regex.Match(text, pattern, RegexOptions.IgnoreCase);
if (match.Success &&
decimal.TryParse(match.Groups[1].Value.Replace(",", ""), out var val))
return val;
return null;
}
}
public class FinancialSummary
{
public string DocumentType { get; set; }
public string InvoiceNumber { get; set; }
public string Date { get; set; }
public decimal? TotalAmount { get; set; }
public string SupplierName { get; set; }
public string CustomerName { get; set; }
}
Die Dokumenttyperkennungslogik ersetzt Mindee's serverseitiges DocumentType Feld durch einen einfachen Schlüsselwortscan gegen result.Text. Bei der überwiegenden Mehrheit der Finanzdokumente kennzeichnet das Vorhandensein von "Rechnung" oder "Rechnungsempfänger" Rechnungen eindeutig; das Fehlen identifiziert Quittungen. Wortpositionsdaten in result.Pages ermöglichen eine ausgefeiltere, layoutbasierte Erkennung, wenn Ihr Dokumentsatz Randfälle umfasst. Der Ergebnisse lesen Leitfaden erklärt das vollständige Objektmodell einschließlich Words, Lines und Paragraphs mit ihren Begrenzungskoordinaten.
MindeeAPI zu IronOCR Mapping-Referenz
| Mindee | IronOCR-Äquivalent |
|---|---|
new MindeeClient(apiKey) | new IronTesseract() — kein API-Schlüssel erforderlich |
new LocalInputSource(filePath) | new OcrInput() + input.LoadImage(filePath) oder ocr.Read(filePath) |
_client.ParseAsync<InvoiceV4>(input) | _ocr.Read(filePath) + Regex-Extraktion auf result.Text |
_client.ParseAsync<ReceiptV5>(input) | _ocr.Read(filePath) + Quittungsextraktionsmuster |
_client.ParseAsync<PassportV1>(input) | _ocr.Read(filePath) + MRZ-Zonenauswertung über CropRectangle |
_client.ParseAsync<FinancialDocumentV1>(input) | _ocr.Read(filePath) + Dokumenttyperkennung auf result.Text |
response.Document.Inference.Prediction | result.Text, result.Pages, result.Lines, result.Words |
prediction.InvoiceNumber?.Value | Regex.Match(result.Text, @"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)") |
prediction.SupplierName?.Value | Top-Zeile der ersten Seite über result.Pages[0].Lines.First() |
prediction.TotalAmount?.Value | Regex.Match(result.Text, @"Total\s*:?\s*\$?([\d,]+\.\d{2})") |
prediction.LineItems | result.Lines gefiltert nach Zeilenartikelregexmustern |
prediction.SupplierPaymentDetails[].Iban | Regex.Match(result.Text, @"IBAN\s*:?\s*([\w\s]+)") |
prediction.InvoiceDate?.Value | Regex.Match(result.Text, @"Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{4})") |
field.Confidence | result.Confidence (Dokumentenebene) oder word.Confidence (pro Wort) |
catch (MindeeException ex) | Kein Äquivalent – keine Netzwerkfehler bei der Erkennungszeit |
await Task.Delay(100) (Ratenbegrenzung) | Nicht erforderlich – keine Ratenbegrenzungen |
input.LoadPdf(path) | ocrInput.LoadPdf(path) — gleiche Operation, vollständig lokal |
| API-Schlüssel in der Konfiguration | Lizenzschlüssel über IronOcr.License.LicenseKey = "..." — keine Rotation erforderlich |
Gängige Migrationsprobleme und Lösungen
Problem 1: Die Koordinaten des Zuschneiderechtecks stimmen nicht mit dem Dokumentlayout überein
Mindee: Räumliche Feldkoordinaten werden serverseitig verarbeitet. Das Mindee-Modell passt sich ohne Koordinatenkonfiguration durch den Entwickler an unterschiedliche Rechnungslayouts an.
Lösung: Messen Sie die Zonenkoordinaten anhand einer repräsentativen Stichprobe von Dokumenten Ihres Lieferanten. Öffnen Sie eine Beispielrechnung in einem beliebigen Bildeditor, lesen Sie die Pixeldimensionen ab und definieren Sie CropRectangle(x, y, width, height) entsprechend. Bei Rechnungen mit variablem Layout lesen Sie bitte zuerst das gesamte Dokument und verwenden Sie die Wortpositionsdaten, um die Zonen dynamisch zu lokalisieren:
var result = _ocr.Read("invoice.jpg");
var allWords = result.Pages.First().Words;
// Find the word "Total" and read the region 50px to its right
var totalLabel = allWords.FirstOrDefault(w =>
w.Text.Equals("Total", StringComparison.OrdinalIgnoreCase));
if (totalLabel != null)
{
var valueRegion = new CropRectangle(
totalLabel.X + totalLabel.Width + 5,
totalLabel.Y - 5,
200,
totalLabel.Height + 10);
using var valueInput = new OcrInput();
valueInput.LoadImage("invoice.jpg", valueRegion);
var valueResult = _ocr.Read(valueInput);
Console.WriteLine($"Total: {valueResult.Text.Trim()}");
}
Das regionenbasierte OCR-Beispiel zeigt dieses dynamische Zonenmuster in einem vollständig funktionierenden Beispiel.
Problem 2: Asynchrone Aufrufseiten funktionieren nicht mehr nach dem Entfernen von Mindee
Mindee: Die gesamte Mindee-API-Oberfläche ist asynchron, da es sich um Netzwerk-I/O handelt. Controller und Servicemethoden, die auf await _client.ParseAsync<t>() basieren, sind asynchron im gesamten Aufrufkette.
Lösung: IronOCR's Read() Methode ist synchron. Bestehende asynchrone Aufrufstellen arbeiten sofort, indem der synchrone Aufruf in Task.Run umhüllt wird:
// Existing async signature preserved for callers
public async Task<string> ExtractInvoiceNumberAsync(string filePath)
{
return await Task.Run(() =>
{
var result = new IronTesseract().Read(filePath);
return Regex.Match(result.Text,
@"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
RegexOptions.IgnoreCase).Groups[1].Value;
});
}
Für hochdurchsatzstarke ASP.NET-Szenarien lesen Sie den asynchronen OCR-Leitfaden bevor Sie sich zwischen Task.Run Umhüllungen und dem nativen asynchronen Pfad entscheiden.
Problem 3: Die Extraktionsgenauigkeit sinkt bei Scans mit geringer Qualität
Mindee: Die Vorverarbeitung bei Mindeeerfolgt intern und automatisch. Probleme mit der Scanqualität verringern die Zuverlässigkeit der Feldmessungen, und es besteht keine Möglichkeit zum Eingreifen der Entwickler vor der erneuten Einreichung.
Lösung: Wenden Sie die Vorverarbeitungspipeline von IronOCR vor der Erkennung an. Die Kombination von Deskew() und DeNoise() stellt die meiste Genauigkeit bei typischen Flachbettscan-Defekten wieder her, die in Kreditoren-Workflows auftreten:
using var input = new OcrInput();
input.LoadImage("faded-invoice.jpg");
input.Deskew();
input.DeNoise();
input.Contrast(); // for faded or low-contrast thermal paper receipts
input.Binarize(); // convert to clean black-and-white before recognition
var result = new IronTesseract().Read(input);
Bei stark verschlechterten Scans wendet input.DeepCleanBackgroundNoise() einen stärkeren Hintergrundentfernungsdurchgang an. Der Leitfaden zur Bildqualitätskorrektur dokumentiert Schwellenwerte, und der Filterassistent hilft dabei, diejenigen Filter zu identifizieren, die die Genauigkeit bei einem gegebenen Dokumentenmuster verbessern.
Problem 4: API-Schlüssel und Netzwerk-Ausgangskonfiguration entfernt
Mindee: Der API-Schlüssel, der in den App-Einstellungen gespeichert ist, die Netzausgangsregeln, die ausgehendes HTTPS zu api.mindee.net zulassen, und die Wiederholungslogik um HttpRequestException sind alle erforderliche Infrastruktur.
Lösung: Alle drei werden zusammen entfernt. Der Mindee-API-Schlüsseleintrag wurde aus der Konfiguration gelöscht. Die Netzwerkausgangsregel wurde widerrufen. Der try/catch (HttpRequestException) Block wird entfernt. Die einzige verbleibende Zugangsberechtigung ist der IronOCR Lizenzschlüssel, der einmalig beim Start festgelegt wird:
// appsettings.json: remove "Mindee:ApiKey"
// Firewall: revoke egress rule for api.mindee.net
// Startup.cs or Program.cs:
IronOcr.License.LicenseKey = Configuration["IronOcr:LicenseKey"];
//Neinrotation schedule, no secure storage beyond standard config secret management
Ausgabe 5: Abrechnung der Seitenanzahl bei mehrseitigen PDFs
Mindee: Eine 12-seitige Lieferantenabrechnung, die auf Mindeehochgeladen wird, verbraucht 12 Seiten des monatlichen Kontingents. Bei den Tarifen für die Überschreitung des monatlichen Kontingents (Pro-Tarif) fallen für dieses einzelne Dokument zusätzliche Kosten in Höhe von 1,20 US-Dollar an, wenn Sie sich dem Limit nähern.
**Lösung:**IronOCR verarbeitet mehrseitige PDFs ohne Kosten pro Seite. Laden Sie das gesamte Dokument und verarbeiten Sie die Seiten nacheinander:
using var input = new OcrInput();
input.LoadPdf("vendor-statement.pdf"); // 12 pages — no billing unit increment
var result = new IronTesseract().Read(input);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters recognized");
Problem 6: Die Abhängigkeit von FinancialDocumentV1 kann nicht durch ein einzelnes Muster ersetzt werden.
Mindee: FinancialDocumentV1 erkennt den Dokumenttyp automatisch und extrahiert Felder, ohne dass der aufrufende Code beim Dokumenttyp abzweigt.
Lösung: Entwicklung eines leichtgewichtigen Detektors, der auf der Präsenz von Schlüsselwörtern basiert. Finanzdokumente lassen sich klar in Rechnungen (enthalten "Rechnung", "Rechnungsempfänger" oder "Fälligkeitsdatum") und Quittungen (enthalten "Quittung", "Vielen Dank" oder weisen keine Rechnungskennzeichnungen auf) unterteilen. Zwei Extraktionsmethoden Plus ein Drei-Zeilen-Detektor ersetzen den Mindee-API-Aufruf, ohne die Genauigkeit bei wohlgeformten Dokumenten zu beeinträchtigen:
var result = _ocr.Read(filePath);
var summary = result.Text.IndexOf("Invoice", StringComparison.OrdinalIgnoreCase) >= 0
? ExtractInvoiceFields(result)
: ExtractReceiptFields(result);
Checkliste für die Migration von Mindee
Vor der Migration
Überprüfen Sie die gesamte Mindee-Nutzung im gesamten Quellcode:
grep -r "using Mindee" --include="*.cs" .
grep -r "MindeeClient\|ParseAsync\|InvoiceV4\|ReceiptV5\|PassportV1\|FinancialDocumentV1" --include="*.cs" .
grep -r "LocalInputSource\|MindeeException" --include="*.cs" .
grep -r "Mindee:ApiKey\|mindee_api_key\|MINDEE_API_KEY" --include="*.json" --include="*.env" --include="*.yml" .
Ergebnisse der Inventur:
- Zählen Sie einzigartige Aufrufstellen mit
ParseAsync<t> - Notieren Sie sich, welche Dokumenttypen verwendet werden (
InvoiceV4,ReceiptV5,PassportV1,FinancialDocumentV1) - Identifizieren Sie alle asynchronen Methodenketten, die von Mindee-Aufrufen ausgehen.
- API-Schlüsselreferenzen in Konfigurationsdateien und Geheimnisspeichern suchen
- Wiederholungslogik für Mindee-Netzwerkaufrufe identifizieren
- Identifizieren Sie Netzwerkausgangsregeln, die ausgehenden Datenverkehr zu Mindee-Endpunkten zulassen.
Code-Migration
- Entfernen Sie das
MindeeNuGet-Paket aus der Projektdatei - Führen Sie
dotnet add package IronOcraus, um IronOCR zu installieren - Fügen Sie
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"zum Anwendungsstart hinzu - Entfernen Sie alle
using Mindee,using Mindee.Inputundusing Mindee.Product.*Direktiven - Ersetzen Sie
MindeeClientKonstruktor-Injektion durchIronTesseractInstanziierung oder DI-Registrierung - Ersetzen Sie jeden
ParseAsync<InvoiceV4>Aufruf durch_ocr.Read(filePath)plus Rechnungsextraktionsmethoden - Ersetzen Sie jeden
ParseAsync<ReceiptV5>Aufruf durch_ocr.Read(filePath)plus Quittungsextraktionsmethoden - Ersetzen Sie jeden
ParseAsync<PassportV1>Aufruf durch zonenbasierte OCR mitCropRectangleauf dem MRZ-Bereich - Ersetzen Sie jeden
ParseAsync<FinancialDocumentV1>Aufruf durch den Dokumenttyp-Detektor + Weiterleitungsmuster - Entfernen Sie alle
await Task.Delay(...)Ratenbegrenzungs-Leitungen - Entfernen Sie alle
catch (MindeeException)undcatch (HttpRequestException)Blöcke aus OCR-Pfaden - Fügen Sie
OcrInputVorverarbeitungsaufrufe (Deskew,DeNoise,Contrast) für gescannte Dokumentenpfade hinzu - Fügen Sie
result.SaveAsSearchablePdf(archivePath)zu allen Dokumentarchivierungspfaden hinzu - Entfernen Sie den Mindee-API-Schlüssel aus allen Konfigurationsdateien und Geheimnisspeichern.
- Integrationstests so aktualisieren, dass sie synchron und ohne Netzwerk-Mocking ausgeführt werden.
Nach der Migration
- Überprüfen Sie die Genauigkeit der Datenextraktion anhand eines Stichprobensatzes von 20-30 Dokumenten, der jeden Dokumententyp abdeckt.
- Bestätigen Sie
result.ConfidenceWerte über 80 bei repräsentativen sauberen Scans; preprocessing anwenden, falls unten angegeben - Testen Sie die Vorverarbeitungspipeline (
Deskew,DeNoise) an geneigten und verschlechterten Scanbeispielen - Überprüfen Sie, ob mehrseitige PDFs korrektes
result.Pages.Countund seitenweise Inhalte erzeugen - Bestätigen Sie, dass
result.SaveAsSearchablePdf()Ausgabe in Adobe Acrobat und System-PDF-Viewer durchsuchbar ist - Testen Sie alle zonenbasierte Extraktion (
CropRectangle) gegen Dokumentlayout-Variationen in Ihrem Lieferantenset - Führen Sie die Stapelverarbeitung ohne
Task.DelayAufrufe aus und vergewissern Sie sich, dass keine Threading-Probleme auftreten - Prüfen Sie, ob die Anwendung ohne ausgehenden Internetzugang korrekt startet und ausgeführt wird.
- Verifizieren Sie, dass die Lizenzschlüsselinitialisierung vor dem ersten
_ocr.Read()Aufruf in jedem Einstiegspunkt läuft - Prüfen Sie, ob in der Konfiguration, den Umgebungsvariablen oder den Geheimnissen noch Verweise auf Mindee-API-Schlüssel vorhanden sind.
Wichtigste Vorteile der Migration zu IronOCR
Vollständige Datensouveränität über Finanzdokumente. Nach der Migration bleiben Lieferanten-IBANs, Bankleitzahlen, Kunden-EINs und detaillierte Posteninformationen dauerhaft in Ihrer Infrastruktur gespeichert. Der Geltungsbereich der Compliance erstreckt sich ausschließlich auf Ihre Organisation. Prozessorvereinbarungen mit Drittanbietern von KI-Systemen werden aus Ihrem Prüfprotokoll entfernt. Teams, die den GLBA-, CMMC-, FedRAMP- oder Datenresidenz-Anforderungen unterliegen, können Finanzdokumente ohne die für die externe Cloud-Übertragung erforderliche Compliance-Prüfung verarbeiten.
Planbare Kosten unabhängig vom Volumen. Die IronOCR Lite Lizenz bei $999 deckt einen Entwickler mit unbegrenzter Dokumentverarbeitung ab. Die Steigerung von 500 Rechnungen pro Monat auf 50.000 Rechnungen pro Monat verursacht keine zusätzlichen Kosten. Verarbeitungsspitzen zum Jahresende, Stapelkorrekturläufe und Entwicklungstestzyklen erhöhen keinen Abrechnungszähler. Die Gesamtbetriebskosten über drei Jahre für ein Team, das 5.000 Seiten pro Monat verarbeitet, sinken von etwa 17.964 US-Dollar (Mindee Pro) auf 1.499 bis 2.999 US-Dollar (Dauerlizenz für IronOCR). Die vollständigen Informationen zu den Preisstufen finden Sie auf der IronOCR Produktseite .
**Die Extraktionslogik gehört Ihnen dauerhaft.**IronOCR Extraktionsmuster sind einfacher C#-Code in Ihrem Repository. Sie sind versionskontrolliert, überprüfbar, testbar und unabhängig von den Release-Zeitplänen oder API-Versionsentscheidungen externer Anbieter einsetzbar. Wenn MindeeInvoiceV5 veröffentlicht und InvoiceV4 außer Betrieb nimmt, ist das eine Migrationsfrist, die vom Anbieter auferlegt wird. Wenn Sie Extraktionsmuster pflegen, ist die Verbesserung ein git commit.
Vorverarbeitungskontrolle für Scanqualität in der Praxis. Die Kreditorenbuchhaltung erhält Rechnungen von Dutzenden oder Hunderten von Lieferanten, die jeweils mit unterschiedlichen Geräten und Einstellungen gescannt werden. IronOCR's Vorverarbeitungspipeline — Deskew(), DeNoise(), Contrast(), Sharpen(), Binarize() — geht auf die spezifischen Defekte in jeder Scankategorie ein. Ein Thermofoto eines Kassenbons weist andere Mängel auf als eine mit einem Flachbettscanner eingescannte, mehrseitige Rechnung; Sie wenden für jeden Pfad die entsprechenden Filter an. Die Vorverarbeitung von Mindeeist unsichtbar und nicht konfigurierbar. Den vollständigen Filterkatalog finden Sie auf der Seite zu den Vorverarbeitungsfunktionen .
Durchsuchbares PDF-Archivieren in einem Schritt. Jede mit IronOCR verarbeitete Rechnung kann als durchsuchbares PDF mit result.SaveAsSearchablePdf() archiviert werden. Die erkannte Textebene wird in die Ausgabedatei eingebettet, sodass jedes Wort in Dokumentenmanagementsystemen, SharePoint-Bibliotheken und Enterprise -Content-Repositories per Volltextsuche durchsucht werden kann. Mindeebietet überhaupt keine PDF-Ausgabe an; Für die durchsuchbare Archivierung waren bisher eine separate Bibliothek, ein separater Verarbeitungsschritt und zusätzlicher Wartungsaufwand erforderlich. Nach der Migration kollabieren Extraktion und Archivierung zu einem _ocr.Read(input) Aufruf.
**Bereitstellung überall ohne Architekturänderungen.**IronOCR lässt sich unter Windows, Linux, macOS, Docker, Azure App Service, AWS Lambda und Google Cloud Run mit demselben NuGet Paket und derselben Initialisierung bereitstellen. Luftabgeschottete Umgebungen, Produktionsanlagen und gesicherte Regierungseinrichtungen funktionieren alle ohne Modifikation. Der Docker-Bereitstellungsleitfaden , der Azure-Leitfaden und der AWS-Leitfaden beschreiben die umgebungsspezifische Konfiguration für jede Plattform.
