Przejdź do treści stopki
FILMY

Jak wykonać OCR tablic rejestracyjnych w języku C#

Ten przewodnik jest przeznaczony dla programistów .NET, którzy przenoszą zadania związane z OCR zKofax OmniPageCapture SDK (obecnie sprzedawanego jako Tungsten Automation) do IronOCR. Obejmuje to pełną ścieżkę migracji: usunięcie zależności od instalatora SDK, wyeliminowanie procedur związanych z cyklem życia silnika, zastąpienie wzorców rozpoznawania opartych na strefach oraz unowocześnienie obsługi błędów. Nie jest wymagana wcześniejsza lektura artykułu porównawczego.

Dlaczego warto przejść zKofax OmniPage(Tungsten)

OmniPage Capture SDK został zaprojektowany z myślą o infrastrukturze zarządzania dokumentami w przedsiębiorstwie w czasach przed pojawieniem się NuGet, Docker i potoków CI/CD. Każdy z wyborów architektonicznych, które miały sens w 2005 roku, powoduje tarcia w 2026 roku.

Instalator SDK nie ma miejsca w świecie NuGet. Każda maszyna programistyczna, agent kompilacji i serwer produkcyjny, na którym działa kod OmniPage, wymaga uruchomienia instalatora Tungsten SDK przed kompilacją. Nie ma .csproj referencji pakietu do przywrócenia. Aktualizacja wersji SDK oznacza ponowne uruchomienie instalatora na całej flocie. Nowy programista nie może uruchomić projektu bez skontaktowania się z osobą zarządzającą licencją SDK i oczekiwania na dostęp do instalatora.

Plik licencyjny jest operacyjną odpowiedzialnością. Plik .lic musi znajdować się na konkretnej ścieżce na każdej maszynie, która wywołuje engine.Initialize(). Wystarczy wdrożyć na nowym serwerze i zapomnieć o pliku, a każde wywołanie OCR zakończy się niepowodzeniem z wyjątkiem licencji — a nie błędem OCR. Użycie licencji pływających i podziały sieci między serwerem aplikacji a serwerem licencji oznacza, że każde wywołanie Initialize() się nie powiedzie, dopóki połączenie nie zostanie przywrócone, niezależnie od tego, czy maszyna pomyślnie zweryfikowała swoją licencję wczoraj.

Zarządzanie cyklem życia silnika powoduje przecieki zasobów na ścieżkach błędów. OmniPageEngine.Shutdown() musi być wywołany na każdej możliwej ścieżce kodu - włącznie z obsługą wyjątków, wczesnymi zwrotami i limitami czasowymi - w przeciwnym razie fotel licencji pływającej pozostanie zablokowany, dopóki nie wygaśnie limit czasowy wypożyczenia serwera licencji. Pisanie obronne wokół tego ograniczenia oznacza otaczanie każdego punktu integracji IDisposable wzorcami istniejącymi wyłącznie w celu ochrony przed pominięciem wyłączenia silnika.

Identyfikacja sprzętowa koliduje z nowoczesnym wdrażaniem. Aktywacja OmniPage jest powiązana ze sprzętem. Ponowne uruchamianie kontenerów, migracje maszyn wirtualnych i automatyczne skalowanie w chmurze wiążą się ze zmianami tożsamości sprzętu, które powodują konieczność ponownej aktywacji. Model wdrożenia niezgodny z autoskalowaniem to model wdrożenia niezgodny z infrastrukturą chmury.

Ceny za stronę są nieprzewidywalne w przypadku dużych projektów. Nagły wzrost liczby przetwarzanych dokumentów — na przykład w wyniku pozyskania nowego klienta lub przesłania partii zaległych zadań — generuje fakturę za przekroczenie limitu, którego nikt nie uwzględnił w budżecie.IronOCR jest bezterminowy i nieograniczony w ramach danego poziomu licencji: bez liczenia stron, bez limitów, bez faktur za przekroczenie limitu.

Proces zamówień blokuje wysyłkę. Pakiet OmniPage SDK jest dostępny wyłącznie w ramach sprzedaży. Dostęp do wersji testowej, ceny i warunki umowy wymagają kontaktu z działem sprzedaży, który trwa od 4 do 12 tygodni. Zespoły tworzące funkcje OCR, które mają termin dostawy produktu, nie mogą czekać na cykl zakupowy w firmie Enterprise. dotnet add package IronOcr rozwiązuje się w 30 sekund. Zobacz stronę licencyjną IronOCR po opublikowane, samoobsługowe ceny — $999 Lite do $2,999 Enterprise, wszystko wieczyste.

Podstawowy problem

OmniPage wymaga pełnej procedury inicjalizacji przed odczytaniem pierwszego bajtu oraz procedury zamknięcia po odczytaniu ostatniego — każde miejsce wywołania musi zarządzać obiema:

// 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
// 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
Imports OmniPage

' OmniPage: Ceremony required on EVERY entry point — init, process, shutdown
Using engine As 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

    Dim document = engine.CreateDocument()
    document.AddPage("invoice.jpg")
    document.Recognize(New RecognitionSettings With {.Language = "English"})
    Dim text As String = document.GetText()
    document.Dispose()    ' Must not be skipped
    engine.Shutdown()     ' Must not be skipped — omitting this locks a floating seat
End Using
$vbLabelText   $csharpLabel
// 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;
// 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;
Imports IronOcr

' IronOCR: One NuGet package, one line at startup, one call to read
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY" ' At app startup — once, ever
Dim text = New IronTesseract().Read("invoice.jpg").Text
$vbLabelText   $csharpLabel

Wersja OmniPage składa się z ośmiu odrębnych etapów, dwóch obowiązkowych wywołań czyszczących, zależności sieciowej oraz zależności od systemu plików. Wersja IronOCR ma dwie.

IronOCR aKofax OmniPage(Tungsten): porównanie funkcji

Poniższa tabela przedstawia funkcje najbardziej istotne dla zespołów rozważających tę migrację.

Funkcja Kofax OmniPage SDK IronOCR
Sposób instalacji Niestandardowy instalator SDK (bez NuGet) dotnet add package IronOcr
Czas do pierwszego wywołania OCR 4–12 tygodni (zamówienie) + godziny (konfiguracja) 30 sekund
Mechanizm licencji Plik .lic na dysku + opcjonalny serwer licencji Klucz ciągu znaków przy uruchomieniu aplikacji
Identyfikacja sprzętu Tak (reaktywacja po migracji maszyny wirtualnej) Nie
Wymagany serwer licencji Tak (w przypadku licencji pływających) Nie
Rozliczenie według czasu pracy na stronę Dostępne (zmienne) Nie
Opublikowane ceny Nie (skontaktuj się z działem sprzedaży) Tak ($999 / $1,499 / $2,999 wieczyste)
Roczne opłaty za utrzymanie 18–25% kosztu licencji Opcjonalnie
Zarządzanie cyklem życia silnika Wymagane (Initialize / Shutdown) Nie jest wymagane
Windows x64 Tak Tak
Linux Tak (dodano w styczniu 2026 r.) Tak (wszystkie wersje)
macOS Nie Tak
Docker / Kubernetes Trudne (instalator + plik licencji na obrazku) Proste (tylko pakiet NuGet)
Azure / AWS Lambda Złożone (dostępność serwera licencji) Proste
Formaty obrazów Tak JPG, PNG, BMP, TIFF, GIF i inne
Natywne wprowadzanie plików PDF Tak (może wymagać licencji modułowej) Tak (wbudowane, bez dodatkowej licencji)
Wielostronicowy plik TIFF Tak Tak
Wynik w formacie PDF z możliwością wyszukiwania Tak Tak (result.SaveAsSearchablePdf())
Automatyczne przetwarzanie wstępne Konfiguracja obiektu Settings Wbudowany + jawny interfejs API potoku
Obsługiwane języki 120+ Ponad 125 (oddzielne pakiety NuGet)
Wyjście danych ustrukturyzowanych Tak (koordynaty słów) Strony, akapity, wiersze, słowa, znaki z współrzędnymi
Ocena pewności Tak Tak (result.Confidence, na słowo)
Odczytywanie BarCode Moduł dodatkowy (oddzielna licencja) Wbudowane (ocr.Configuration.ReadBarCodes = true)
Bezpieczeństwo wątków Złożone (ograniczenia związane z współdzieleniem silnika) Pełne (jeden IronTesseract na wątek)
Obsługa potoku CI/CD Wymaga instalatora na każdym agencie Standardowy dotnet restore

Szybki start: Migracja zKofax OmniPagedo IronOCR

Krok 1: Zastąp SDK pakietem NuGet

OmniPage nie posiada pakietu NuGet, który można by usunąć. Usuń ręczne referencje DLL z pliku .csproj i odinstaluj SDK z maszyn deweloperskich po zakończeniu migracji. Następnie zainstaluj IronOCR:

dotnet add package IronOcr

Pakiet IronOCR NuGet zawiera silnik OCR, filtry przetwarzania wstępnego oraz komponenty środowiska uruchomieniowego. Bez oddzielnego instalatora, bez natywnego zarządzania bibliotekami DLL, bez rejestracji komponentów.

Krok 2: Aktualizacja przestrzeni nazw

// Before (Kofax OmniPage)
using Kofax.OmniPage.CSDK;
using Kofax.OmniPageCSDK;
using CSDK;

// After (IronOCR)
using IronOcr;
// Before (Kofax OmniPage)
using Kofax.OmniPage.CSDK;
using Kofax.OmniPageCSDK;
using CSDK;

// After (IronOCR)
using IronOcr;
Imports IronOcr
$vbLabelText   $csharpLabel

Krok 3: Inicjalizacja licencji

Dodaj jedną linię podczas uruchamiania aplikacji. Zastępuje to ścieżkę pliku .lic, konfigurację serwera licencji i wywołanie engine.Initialize():

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Przechowuj klucz w zmiennej środowiskowej (IRONOCR_LICENSE_KEY) lub appsettings.json zamiast w kodzie źródłowym. Klucz jest odczytywany w trybie offline — w czasie wykonywania nie następuje żadne połączenie sieciowe.

Przykłady migracji kodu

Błąd inicjalizacji silnika Zastąpienie ścieżki

Najbardziej niebezpiecznym aspektem modelu cyklu życia OmniPage nie jest ścieżka pomyślna — jest to ścieżka błędów. Każdy wyjątek rzucony między engine.Initialize() a engine.Shutdown() może pozostawić zablokowane miejsce licencji pływającej, jeśli Shutdown() nie zostanie osiągnięty. Kod produkcyjny wymaga bloków try/finally wokół każdego wywołania przetwarzania dokumentu:

Podejście Kofax OmniPage:

// 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
    }
}
// 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
    }
}
Imports System

' OmniPage: try/finally required everywhere to protect license seat release
Public Function ProcessInvoice(imagePath As String) As String
    Dim engine As New OmniPageEngine()
    engine.SetLicenseFile("C:\Program Files\OmniPage\license.lic")

    Try
        engine.Initialize() ' Contacts license server — failure here locks nothing
        Dim document = engine.CreateDocument()

        Try
            document.AddPage(imagePath)
            document.Recognize(New RecognitionSettings With {.Language = "English"})
            Return document.GetText()
        Catch ex As RecognitionException
            ' Log, rethrow — but Shutdown must still be called
            Throw New OcrProcessingException("Recognition failed", ex)
        Finally
            document.Dispose() ' Inner finally: release document
        End Try
    Catch ex As LicenseValidationException
        Throw New OcrProcessingException("License validation failed", ex)
    Finally
        engine.Shutdown() ' Outer finally: release license seat — MUST execute
    End Try
End Function
$vbLabelText   $csharpLabel

Podejście IronOCR:

// IronOCR: Nie license 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
}
// IronOCR: Nie license 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
}
Imports IronOcr

Public Function ProcessInvoice(imagePath As String) As String
    Using input As New OcrInput()
        input.LoadImage(imagePath)

        Dim ocr As New IronTesseract()
        Dim result = ocr.Read(input)
        Return result.Text
    End Using
    ' OcrInput disposal is automatic — no license implications on any code path
End Function
$vbLabelText   $csharpLabel

Blok using na OcrInput obsługuje oczyszczanie pamięci dla załadowanych danych obrazowych. Nie istnieje try/finally, aby chronić miejsce licencji. Wyjątek w dowolnym miejscu tej metody nie ma skutków ubocznych poza zakresem samej metody. Opcje konfiguracyjne, w tym instancje lokalne dla wątków, można znaleźć w przewodniku konfiguracji IronTesseract.

Migracja oparta na rozpoznawaniu stref

Głównym mechanizmem ekstrakcji ustrukturyzowanych danych w OmniPage jest definiowanie stref: obszary dokumentu są deklarowane za pomocą granic współrzędnych i typu rozpoznawania dla każdej strefy (OCR, ICR, OMR, BarCode). Deweloperzy definiują obiekty FormZone na dokument szablonu i przekazują je do maszyny rozpoznawania.IronOCR używa CropRectangle, aby osiągnąć tę samą docelową ekstrakcję bez zarządzania szablonami lub deklaracji typów stref:

Podejście Kofax OmniPage:

// 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;
}
// 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;
}
Imports System
Imports System.Collections.Generic

' OmniPage: Zone-based form extraction with template management
Public Function ExtractInvoiceFields(invoicePath As String) As Dictionary(Of String, String)
    Using engine As New OmniPageEngine()
        engine.SetLicenseFile(licensePath)
        engine.Initialize()

        ' Define zones per document template
        Dim zones As New List(Of FormZone) From {
            New FormZone With {.Name = "InvoiceNumber", .Type = "OCR", .X = 520, .Y = 80, .Width = 200, .Height = 30},
            New FormZone With {.Name = "InvoiceDate", .Type = "OCR", .X = 520, .Y = 120, .Width = 200, .Height = 30},
            New FormZone With {.Name = "TotalAmount", .Type = "OCR", .X = 520, .Y = 580, .Width = 200, .Height = 30},
            New FormZone With {.Name = "VendorName", .Type = "OCR", .X = 50, .Y = 80, .Width = 300, .Height = 40}
        }

        Dim template As New FormTemplate With {.Name = "StandardInvoice", .Zones = zones}
        Dim settings As New RecognitionSettings With {.Language = "English"}

        Dim document = engine.CreateDocument()
        document.AddPage(invoicePath)
        document.ApplyTemplate(template)
        document.Recognize(settings)

        Dim fields As New Dictionary(Of String, String)()
        For Each zone In zones
            fields(zone.Name) = document.GetZoneText(zone.Name)
        Next

        document.Dispose()
        engine.Shutdown()
        Return fields
    End Using
End Function
$vbLabelText   $csharpLabel

Podejście IronOCR:

// 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;
}
// 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;
}
Imports System.Collections.Generic

' IronOCR: CropRectangle targets specific regions — no template management
Public Function ExtractInvoiceFields(invoicePath As String) As Dictionary(Of String, String)
    Dim fields As New Dictionary(Of String, String)()
    Dim ocr As New IronTesseract()

    ' Extract each field by reading only the target region
    Dim fieldRegions As New Dictionary(Of String, CropRectangle) From {
        {"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)}
    }

    For Each kvp In fieldRegions
        Dim fieldName = kvp.Key
        Dim region = kvp.Value
        Using input As New OcrInput()
            input.LoadImage(invoicePath, region)
            fields(fieldName) = ocr.Read(input).Text.Trim()
        End Using
    Next

    Return fields
End Function
$vbLabelText   $csharpLabel

Każdy CropRectangle określa (x, y, width, height) w pikselach. Silnik OCR przetwarza tylko wyznaczony obszar, a nie całą stronę — zapewnia to taką samą wydajność, jaką zapewnia przetwarzanie strefowe w programie OmniPage. Przewodnik po OCR oparty na regionach obejmuje wzorce wyboru współrzędnych, w tym jak wyodrębnić wiele regionów z jednego załadunku obrazu, korzystając z API wielu regionów OcrInput.

Migracja danych strukturalnych

OmniPage udostępnia strukturę dokumentu poprzez własny proces eksportu: ustawienia formatu są stosowane do rozpoznanego dokumentu, a wynik jest zapisywany do pliku w określonym formacie (RTF, XML, CSV, PDF z możliwością wyszukiwania). Dostęp do współrzędnych na poziomie WORD wymaga iteracji iteratora wyników z jawnymi zapytaniami o pozycję.IronOCR udostępnia te same dane strukturalne bezpośrednio w obiekcie wynikowym bez konieczności dodatkowego eksportu:

Podejście Kofax OmniPage:

// 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();
}
// 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();
}
Imports System
Imports System.IO

Public Sub ExtractStructuredContent(imagePath As String, outputDir As String)
    Using engine As New OmniPageEngine()
        engine.SetLicenseFile(licensePath)
        engine.Initialize()

        Dim settings As New RecognitionSettings With {.Language = "English"}
        Dim document = engine.CreateDocument()
        document.AddPage(imagePath)
        document.Recognize(settings)

        ' Word-level coordinates through result iterator
        Dim iterator = document.GetResultIterator(ResultIteratorLevel.Word)
        While iterator.MoveNext()
            Dim word As String = iterator.GetText()
            Dim bounds = iterator.GetBoundingBox()
            Dim confidence As Double = iterator.GetConfidence()
            Console.WriteLine($"Word: {word} at ({bounds.X},{bounds.Y}) conf:{confidence:F1}%")
        End While

        ' Structured export requires separate output format configuration
        Dim outputSettings As New OutputSettings With {
            .Format = OutputFormat.XML,
            .IncludeCoordinates = True,
            .IncludeConfidence = True
        }
        document.SaveAs(Path.Combine(outputDir, "output.xml"), outputSettings)

        document.Dispose()
        engine.Shutdown()
    End Using
End Sub
$vbLabelText   $csharpLabel

Podejście IronOCR:

// 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}%");
            }
        }
    }
}
// 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}%");
            }
        }
    }
}
Public Sub ExtractStructuredContent(imagePath As String)
    Dim result = New IronTesseract().Read(imagePath)

    Console.WriteLine($"Confidence: {result.Confidence:F1}%")
    Console.WriteLine($"Pages: {result.Pages.Length}")

    For Each page In result.Pages
        For Each paragraph In page.Paragraphs
            Console.WriteLine($"[Paragraph at ({paragraph.X},{paragraph.Y})]")
            Console.WriteLine(paragraph.Text)

            For Each 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}%")
            Next
        Next
    Next
End Sub
$vbLabelText   $csharpLabel

Hierarchia obiektu OcrResult — Strony, Akapity, Linie, Słowa, Znaki — dostarcza te same dane pozycyjne, które iteracja wyników OmniPage ujawnia, ale jako nawigowalną strukturę obiektów zamiast sekwencyjnego kursora. Wyniki oceny pewności są dostępne na poziomie wyników, stron, akapitów i słów bez dodatkowej konfiguracji. Przewodnik po wynikach odczytu obejmuje wszystkie właściwości danych strukturalnych, a przewodnik po wynikach pewności obejmuje wzorce walidacji dla poszczególnych WORDów.

Migracja przetwarzania wielostronicowych plików TIFF

Wielostronicowy przepływ pracy OmniPage z plikami TIFF wymaga wyodrębniania stron pojedynczo z kontenera TIFF, z oddzielnym wywołaniem funkcji rozpoznawania i usuwaniem dokumentu dla każdej strony. Powoduje to powstanie zarówno szablonów, jak i obszaru zarządzania zasobami proporcjonalnego do liczby stron.IronOCRładuje wielo-ramkowe pliki TIFF za pomocą jednego wywołania:

Podejście Kofax OmniPage:

// 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;
}
// 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;
}
Imports System.Collections.Generic

' OmniPage: Page-by-page TIFF extraction with per-page lifecycle
Public Function ExtractFromMultiPageTiff(tiffPath As String) As List(Of String)
    Dim pageTexts As New List(Of String)()

    Using engine As New OmniPageEngine()
        engine.SetLicenseFile(licensePath)
        engine.Initialize()

        ' Open TIFF and iterate frames
        Dim tiffContainer = engine.OpenTiff(tiffPath)
        Dim pageCount As Integer = tiffContainer.GetPageCount()

        Dim settings As New RecognitionSettings With {.Language = "English"}

        For i As Integer = 0 To pageCount - 1
            Dim page = tiffContainer.GetPage(i) ' Extract frame
            Dim document = engine.CreateDocument()

            Try
                document.AddPage(page)
                document.Recognize(settings)
                pageTexts.Add(document.GetText())
            Finally
                document.Dispose() ' Dispose per page to manage memory
            End Try
        Next

        tiffContainer.Dispose()
        engine.Shutdown()
    End Using

    Return pageTexts
End Function
$vbLabelText   $csharpLabel

Podejście IronOCR:

// 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();
}
// 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();
}
Imports System.Collections.Generic
Imports IronOcr

' IronOCR: Multi-frame TIFF loaded in one call — all pages in one result
Public Function ExtractFromMultiPageTiff(tiffPath As String) As List(Of String)
    Using input As New OcrInput()
        input.LoadImageFrames(tiffPath) ' All frames loaded automatically

        Dim result = New IronTesseract().Read(input)

        ' Each TIFF frame becomes a page in the result
        Return result.Pages.Select(Function(page) page.Text).ToList()
    End Using
End Function
$vbLabelText   $csharpLabel

LoadImageFrames odczytuje każdą klatkę z pojemnika TIFF w jednym wywołaniu. Wynik ujawnia jeden OcrResult.Page na klatkę, zachowując strukturę strona po stronie bez konieczności ręcznego pętlenia iteracyjnego lub oczyszczania na stronę. Dla produkcyjnych przepływów pracy wsadowych TIFF zobacz przewodnik po wejściu TIFF i GIF.

Migracja przetwarzania równoległego bezpiecznego dla wątków

Silnik OmniPage jest współdzielonym zasobem ze stanem. Dzielenie jednej instancji OmniPageEngine przez wątki wymaga zewnętrznej synchronizacji, ponieważ wiele wątków wywołujących CreateDocument() równocześnie może wywołać splątany stan. Bezpieczny wzorzec — jedna instancja silnika na wątek — stoi w konflikcie z dużym kosztem inicjalizacji silnika. Instancje IronOCR nie posiadają współdzielonego stanu: twórz jedną IronTesseract na wątek bez zera nakładu na koordynację:

Podejście Kofax OmniPage:

// 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;
}
// 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;
}
Imports System.Collections.Concurrent
Imports System.Threading.Tasks

' OmniPage: Shared engine with locking to serialize document operations
Public Function ProcessBatchWithEngine(imagePaths As String(), licensePath As String) As ConcurrentDictionary(Of String, String)
    Dim results As New ConcurrentDictionary(Of String, String)()
    Dim engineLock As New Object()

    ' One engine — document operations must be serialized
    Using engine As New OmniPageEngine()
        engine.SetLicenseFile(licensePath)
        engine.Initialize()

        Dim settings As New RecognitionSettings With {.Language = "English"}

        Parallel.ForEach(imagePaths, Sub(imagePath)
                                        SyncLock engineLock ' Serialize: one recognition at a time
                                            Dim document = engine.CreateDocument()
                                            Try
                                                document.AddPage(imagePath)
                                                document.Recognize(settings)
                                                results(imagePath) = document.GetText()
                                            Finally
                                                document.Dispose()
                                            End Try
                                        End SyncLock
                                    End Sub)
        engine.Shutdown()
    End Using

    Return results
End Function
$vbLabelText   $csharpLabel

Podejście IronOCR:

// 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;
}
// 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;
}
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Imports IronOcr

' IronOCR: One IronTesseract per thread — no locking, genuine parallelism
Public Function ProcessBatchInParallel(imagePaths As String()) As ConcurrentDictionary(Of String, String)
    Dim results As New ConcurrentDictionary(Of String, String)()

    Parallel.ForEach(imagePaths, Sub(imagePath)
        ' Each thread creates its own instance — no shared state, no locks
        Dim ocr As New IronTesseract()
        Using input As New OcrInput()
            input.LoadImage(imagePath)

            Dim result = ocr.Read(input)
            results(imagePath) = result.Text
        End Using
    End Sub)

    Return results
End Function
$vbLabelText   $csharpLabel

Wersja OmniPage serializuje całe rozpoznawanie za pomocą blokady, co uniemożliwia równoległość. Wersja IronOCR przetwarza dokumenty równolegle, bez konieczności koordynacji. W przypadku obciążeń wsadowych o dużej przepustowości zapoznaj się z przykładem wielowątkowości oraz przewodnikiem po optymalizacji szybkości.

Generowanie plików PDF z możliwością wyszukiwania na podstawie zeskanowanego archiwum

Wyjście PDF wyszukiwalnego OmniPage wymaga złożenia potoku rozpoznawania z wyraźną konfiguracją OutputSettings i OutputFormat przed zapisaniem.IronOCR tworzy pliki PDF z możliwością wyszukiwania na podstawie pojedynczego wywołania metody na obiekcie wynikowym:

Podejście Kofax OmniPage:

// 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();
}
// 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();
}
Imports System.IO

' OmniPage: Searchable PDF requires OutputSettings configuration before save
Public Sub ConvertArchiveToSearchable(scannedPdfPaths As String(), outputDirectory As String)
    Using engine As New OmniPageEngine()
        engine.SetLicenseFile(licensePath)
        engine.Initialize()

        Dim recognitionSettings As New RecognitionSettings With {
            .Language = "English",
            .AccuracyMode = "Maximum",
            .PreserveLayout = True
        }

        Dim outputSettings As New OutputSettings With {
            .Format = OutputFormat.SearchablePDF,
            .Compression = PDFCompression.Standard,
            .ImageQuality = 85,
            .EmbedFonts = True
        }

        For Each pdfPath As String In scannedPdfPaths
            Dim document = engine.OpenPDF(pdfPath)
            document.RecognizeAll(recognitionSettings)

            Dim outputPath As String = Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(pdfPath) & "_searchable.pdf")

            document.SaveAs(outputPath, outputSettings)
            document.Dispose()
        Next
    End Using

    engine.Shutdown()
End Sub
$vbLabelText   $csharpLabel

Podejście IronOCR:

// 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)");
    }
}
// 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)");
    }
}
Imports System.IO
Imports IronOcr

Public Sub ConvertArchiveToSearchable(scannedPdfPaths As String(), outputDirectory As String)
    Dim ocr As New IronTesseract()

    For Each pdfPath As String In scannedPdfPaths
        Using input As New OcrInput()
            input.LoadPdf(pdfPath) ' All pages loaded automatically

            Dim result = ocr.Read(input)

            Dim outputPath As String = Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(pdfPath) & "_searchable.pdf")

            result.SaveAsSearchablePdf(outputPath)
            Console.WriteLine($"Processed: {Path.GetFileName(pdfPath)} ({result.Pages.Length} pages)")
        End Using
    Next
End Sub
$vbLabelText   $csharpLabel

SaveAsSearchablePdf osadza warstwę tekstową w PDF, czyniąc ją indeksowalną w systemach zarządzania dokumentami, bez zmiany wyglądu oryginalnego skanu. Przewodnik w formacie PDF z funkcją wyszukiwania obejmuje opcje warstw tekstowych, a przykład OCR dla plików PDF ilustruje kompleksowe przetwarzanie zeskanowanych plików PDF.

Dokumentacja APIKofax OmniPagedo IronOCR

Kofax OmniPage Odpowiednik IronOCR
using Kofax.OmniPage.CSDK; using IronOcr;
using Kofax.OmniPageCSDK; using IronOcr;
using CSDK; using IronOcr;
new OmniPageEngine() Nie jest wymagane — brak obiektu silnika
engine.SetLicenseFile(path) IronOcr.License.LicenseKey = "key";
engine.Initialize() Nie jest wymagane
engine.Shutdown() Nie jest wymagane
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) (wszystkie strony na raz)
document.GetText() result.Text
document.GetZoneText(zoneName) input.LoadImage(path, cropRectangle) + result.Text
document.Dispose() using var input = new OcrInput() (automatycznie)
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(); (obejmuje korekcję obrotową)
document.SaveAs(path, outputSettings) result.SaveAsSearchablePdf(path)
OutputFormat.SearchablePDF result.SaveAsSearchablePdf(path)
OutputFormat.XML (ze współrzędnymi) result.Pages / .Paragraphs / .Words struktura obiektowa
FormZone z granicami współrzędnych new CropRectangle(x, y, width, height)
Licencjonowanie na stronę Nie dotyczy
.lic wdrożenie pliku Nie dotyczy
Konfiguracja serwera licencji Nie dotyczy

Typowe problemy związane z migracją i ich rozwiązania

Problem 1: Wyjątki związane z brakiem pliku licencji w środowisku produkcyjnym

Kofax OmniPage: Każde wdrożenie wymaga, aby plik .lic istniał na konkretnej ścieżce dostępnej dla procesu aplikacji. Pipeline wdrożeniowy, który nie kopiuje wyraźnie pliku licencji na serwer docelowy, powoduje FileNotFoundException lub LicenseException podczas inicjalizacji silnika. Zespoły ds. bezpieczeństwa często zaznaczają osadzanie plików .lic w obrazach kontenerów lub ich commitowanie w kontrolę źródła.

Rozwiązanie:IronOCR odczytuje swoją licencję z ciągu znaków. Zapisz klucz jako zmienną środowiskową i odczytaj go podczas uruchamiania — bez konieczności wdrażania pliku ani konfigurowania ścieżki:

// 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.");
// 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.");
Imports System

' At application startup — reads IRONOCR_LICENSE_KEY from environment
IronOcr.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY"), Throw New InvalidOperationException("IronOCR license key not configured."))
$vbLabelText   $csharpLabel

W Dockerze przekaż --env IRONOCR_LICENSE_KEY=YOUR-KEY. W usłudze Azure App Service należy ustawić to jako ustawienie aplikacji. W Kubernetes należy wprowadzić to za pomocą Secret. Brak montowania plików, brak konfiguracji ścieżek, brak weryfikacji bezpieczeństwa wbudowanych plików licencyjnych.

Problem 2: Blokada licencji typu floating po awarii procesu

Kofax OmniPage: Kiedy proces aplikacji ulega awarii, jest zabijany przez watchdog, lub kończy się przez Environment.FailFast, engine.Shutdown() nie wykonuje się. Licencje typu floating pozostają wypożyczone do momentu wygaśnięcia limitu czasu serwera licencji — zazwyczaj 30–60 minut. W środowisku kontenerowym, gdzie pody często się restartują, takie zachowanie wyczerpuje pulę licencji.

Rozwiązanie:IronOCR nie obsługuje koncepcji wypożyczonych licencji. Awaria procesu nie zwalnia żadnych zasobów i nie blokuje żadnego systemu zewnętrznego. Kolejny proces rozpoczyna się natychmiast, bez czekania na dostępność miejsc:

// 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"); // Nie seat to check out
// 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"); // Nie seat to check out
' IronOCR: Process crash has no license implications whatsoever
' Start processing immediately after any failure
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim result = New IronTesseract().Read("document.jpg") ' Nie seat to check out
$vbLabelText   $csharpLabel

Aby uzyskać informacje na temat odpornych usług .NET Core, zapoznaj się z przewodnikiem dotyczącym asynchronicznego OCR, w którym opisano wzorce umożliwiające płynną integrację z usługami hostowanymi oraz płynne wyłączanie.

Problem 3: Błąd tworzenia obrazu Docker — instalator nie może działać w trybie nieinteraktywnym

Kofax OmniPage: Instalator OmniPage SDK jest interaktywnym lub półinteraktywnym instalatorem, który nie działa poprawnie w kontekście docker build. Zespoły próbujące wbudować SDK w obraz kontenera napotykają błędy w umowie licencyjnej instalatora lub na etapach wyboru komponentów. Rozwiązania alternatywne (parametry cichej instalacji, wstępnie wyodrębnione kopie bibliotek DLL) nie są udokumentowane i zależą od konkretnej wersji.

Rozwiązanie: Dockerfile z IronOCR to trzy linie:

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 jest jedyną zależnością systemową. Pakiet NuGet IronOCR jest przywracany przez dotnet restore wewnątrz etapu budowy jak każda inna referencja pakietu. Przewodnik wdrażania Docker obejmuje zarówno obrazy bazowe Debian, jak i Alpine, a przewodnik wdrażania Linux obejmuje nazwy pakietów specyficzne dla danej dystrybucji.

Problem 4: Konieczna reaktywacja po migracji maszyny wirtualnej lub automatycznym skalowaniu w chmurze

Kofax OmniPage: Aktywacja OmniPage jest powiązana z identyfikatorem sprzętu. Środowiska chmurowe, które migrują maszyny wirtualne między hostami fizycznymi, automatycznie skalują się do nowych instancji lub zastępują kontenery nowymi obrazami, powodują zmiany tożsamości sprzętu, które wymagają ponownej aktywacji. Kontaktowanie się z pomocą techniczną Tungsten w celu ponownej aktywacji w trakcie zdarzenia zwiększa ryzyko operacyjne.

Rozwiązanie: Klucz licencyjny IronOCR jest niezależny od sprzętu. Ten sam klucz działa na dowolnej maszynie, w dowolnym kontenerze, w dowolnym regionie chmury oraz dla dowolnej liczby instancji skalowanych automatycznie w ramach licencjonowanego poziomu. Bez ponownej aktywacji, bez kontaktowania się z pomocą techniczną, bez przestojów:

// Identical startup code on any hardware topology
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
bool valid = IronOcr.License.IsLicensed; // Verify without a network call
// Identical startup code on any hardware topology
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
bool valid = IronOcr.License.IsLicensed; // Verify without a network call
' Identical startup code on any hardware topology
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim valid As Boolean = IronOcr.License.IsLicensed ' Verify without a network call
$vbLabelText   $csharpLabel

Problem 5: Obiekt RecognitionSettings nie ma odpowiednika w IronOCR

Kofax OmniPage: OmniPage używa obiektu RecognitionSettings (lub PreprocessingSettings w zależności od wersji SDK) do konfiguracji zachowania silnika na dokument. Zespoły migrujące oczekują obiektu konfiguracyjnego typu równoległego w IronOCR.

Rozwiązanie:IronOCR dzieli konfigurację na dwie powierzchnie: operacje wstępne na OcrInput i ustawienia silnika na IronTesseract. Nie ma obiektu ustawień do instancjonowania:

// 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);
// 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);
Imports IronOcr

' OmniPage settings object → IronOCR method calls on OcrInput
Dim ocr As New IronTesseract()
ocr.Language = OcrLanguage.English ' RecognitionSettings.Language
' ocr.Configuration.TesseractVersion = ... ' Engine version already optimized

Using input As New OcrInput()
    input.LoadImage(imagePath)
    input.Deskew() ' settings.DeskewImage = true
    input.DeNoise() ' settings.DespeckleLevel = 2
    input.Contrast() ' settings.ContrastEnhancement = true

    Dim result = ocr.Read(input)
End Using
$vbLabelText   $csharpLabel

W przewodniku po korekcji jakości obrazu wymieniono wszystkie dostępne metody przetwarzania wstępnego wraz z wskazówkami dotyczącymi tego, które filtry mają zastosowanie do poszczególnych profili jakości dokumentów.

Problem 6: Pliki szablonów stref nie mogą być przenoszone bezpośrednio

Kofax OmniPage: Szablony formularzy OmniPage przechowują definicje stref w zastrzeżonych plikach szablonów .fdt lub .fpf, które definiują pozycje pól, typy rozpoznawania i zasady walidacji dla klasy dokumentu. Pliki te nie mogą być importowane przez IronOCR.

Rozwiązanie: Wyodrębnij dane współrzędnych z plików szablonów (są oparte na XML) i przekształć każdą strefę na CropRectangle. Nazwy pól stają się kluczami słownika; współrzędne stref mapują bezpośrednio na parametry (x, y, width, height):

// 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();
// 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();
Imports IronOcr

' Convert OmniPage zone definition to IronOCR CropRectangle
' OmniPage zone: Name="TotalDue" X="490" Y="612" Width="180" Height="28"
' IronOCR equivalent:
Dim totalDueRegion As New CropRectangle(490, 612, 180, 28)

Using input As New OcrInput()
    input.LoadImage(invoicePath, totalDueRegion)
    Dim totalDue As String = New IronTesseract().Read(input).Text.Trim()
End Using
$vbLabelText   $csharpLabel

Dla dokumentów, w których strefy różnią się na stronę, załaduj ten sam obraz z różnymi wartościami CropRectangle na region, zamiast ponownie ładować plik. Przykład przycinania regionu demonstruje wiele odczytów regionów z jednego źródła obrazu.

Lista kontrolna migracji Kofax OmniPage

Przed migracją

Zidentyfikuj wszystkie punkty integracji OmniPage w kodzie źródłowym:

# 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" .
# 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" .
SHELL

Sprawdź zasoby przed rozpoczęciem:

  • Zliczanie plików z importami przestrzeni nazw OmniPage
  • Wymienienie wszystkich definicji FormTemplate i FormZone oraz wyodrębnienie ich danych współrzędnych
  • Identyfikacja, które słowniki językowe są załadowane i mapowane na pakiety NuGet IronOcr.Languages.*
  • Zwróć uwagę, jakie formaty wyjściowe są używane (PDF z możliwością wyszukiwania, zwykły tekst, XML) oraz ich odpowiedniki w IronOCR
  • Zlokalizowanie wszystkich referencji plików .lic w skryptach wdrożeniowych i konfiguracji

Migracja kodu

  1. Usuń odniesienia DLL OmniPage ze wszystkich plików .csproj
  2. Uruchom dotnet add package IronOcr w każdym projekcie, który wykonuje OCR
  3. Dodaj pakiety językowe dla każdego używanego języka: dotnet add package IronOcr.Languages.[Language]
  4. Dodaj IronOcr.License.LicenseKey = ...; w każdym punkcie wejścia aplikacji (Program.cs, Startup.cs lub host usługi)
  5. Zastąp wszystkie using Kofax.OmniPage.CSDK;, using CSDK; i powiązane importy przestrzeni nazw przez using IronOcr;
  6. Usuń wszystkie konstrukcje OmniPageEngine, SetLicenseFile i wywołania Initialize
  7. Usuń wszystkie wywołania engine.Shutdown() i implementacje IDisposable istniejące wyłącznie w celu zapewnienia zamknięcia
  8. Zastąp engine.CreateDocument() + document.AddPage() przez new OcrInput() + input.LoadImage()
  9. Zastąp engine.OpenPDF() + iterację na stronę przez input.LoadPdf() (wszystkie strony w jednym wywołaniu)
  10. Zastąp engine.OpenTiff() + pętle na klatkę przez input.LoadImageFrames()
  11. Zastąp document.Recognize(settings) przez new IronTesseract().Read(input)
  12. Przekształć współrzędne FormZone na instancje CropRectangle(x, y, width, height)
  13. Zastąp document.GetZoneText() zinput.LoadImage(path, cropRectangle) + result.Textdla każdego regionu
  14. Zastąp document.SaveAs(path, outputSettings) dla wyszukiwalnego PDF przez result.SaveAsSearchablePdf(path)
  15. Zastąp wzorce iteratora wyników przez przejścia właściwościowe result.Pages / .Paragraphs / .Words
  16. Usuń obiekty PreprocessingSettings i zastąp flagi boolowskie wyraźnymi wywołaniami metod input.Deskew(), input.DeNoise(), input.Contrast()
  17. Usuń ścieżki do plików licencji ze skryptów wdrażania, plików konfiguracyjnych i szablonów infrastruktury jako kodu

Po migracji

  • Sprawdź dokładność OCR na reprezentatywnej próbie ponad 100 dokumentów z rzeczywistego korpusu — porównaj z wynikami programu OmniPage wiersz po wierszu dla faktur, umów i formularzy
  • Potwierdź, że ekstrakcja strefowa oparta na CropRectangle zwraca tekst, który pasuje do wyjścia GetZoneText() OmniPage dla każdego mapowanego pola
  • Przetestuj przetwarzanie wielostronicowych plików PDF: sprawdź liczbę stron, kolejność stron i ciągłość tekstu
  • Przetestuj przetwarzanie plików TIFF zawierających wiele klatek: upewnij się, że wszystkie klatki zostały przetworzone, a kolejność klatek została zachowana
  • Sprawdź, czy pliki PDF z funkcją wyszukiwania są indeksowalne w używanym systemie zarządzania dokumentami (SharePoint, OpenText itp.)
  • Przeprowadź test przetwarzania równoległego z ponad 50 dokumentami jednocześnie i upewnij się, że nie ma żadnych problemów z bezpieczeństwem wątków
  • Przetestuj pokrycie pakietów językowych: załaduj każdy wcześniej używany słownik językowy przez IronOcr.Languages.* i zweryfikuj jakość rozpoznawania
  • Upewnij się, że awarie procesu i ponowne uruchomienie kontenera nie wymagają żadnych działań związanych z odzyskiwaniem licencji
  • Uruchom budowanie Docker na agencie CI — potwierdź, że dotnet restore rozwiązuje IronOCR bez kroków instalacyjnych
  • Wyniki oceny pewności są dostępne dla każdego WORD-a i odpowiadają oczekiwaniom dotyczącym jakości danych w każdym dalszym etapie procesu walidacji
  • Sprawdź, czy aplikacja uruchamia się bez obecności pliku .lic na jakiejkolwiek ścieżce

Kluczowe korzyści z migracji do IronOCR

Stopień skomplikowania wdrożenia spada z tygodni na minuty. Projekt, który wcześniej wymagał dostępu do instalatora SDK, wdrożenia pliku .lic, konfiguracji zapory sieciowej dla serwera licencji i koordynacji z zespołem infrastruktury, teraz wdraża się przez dotnet restore. Nowy programista klonuje repozytorium i uruchamia projekt. Nowy serwer produkcyjny jest udostępniany przez potok CI/CD. Obrazy kontenerów są kompilowane bez konieczności wykonywania czynności instalacyjnych.

Ryzyko licencyjne znika całkowicie. Nie ma pływających miejsc do wyczerpania, nie ma limitów czasowych na zakończenie, nie ma odcisków palców sprzętu do ponownej aktywacji i żadnych plików .lic do ochrony w potokach wdrożeniowych. Awaria aplikacji o 3 nad ranem nie powoduje zwolnienia ani zablokowania żadnych danych. Inżynier dyżurny ponownie uruchamia proces; Rozpoznawanie OCR zostanie wznowione natychmiast. Strona produktu IronOCR obejmuje wszystkie poziomy licencji.

Wdrażanie wielopłatformowe staje się standardowym celem NuGet. Komputery programistyczne z systemem macOS działają bez wyjątków platformowych. Serwery produkcyjne z systemem Linux nie wymagają wersji SDK ze stycznia 2026 r. Kontenery Docker budowane są z bazowego obrazu mcr.microsoft.com/dotnet/aspnet z jedną zależnością systemową. Ta sama referencja pakietowa IronOcr w .csproj produkuje działający build na Windows, Linux i macOS. Aby uzyskać informacje na temat konfiguracji specyficznej dla chmury, zapoznaj się z przewodnikiem wdrażania platformy Azure oraz przewodnikiem wdrażania AWS.

Równoległa przepustowość skaluje się wraz ze sprzętem. Architektura współdzielonego silnika OmniPage wymaga blokowania, które serializuje równoczesne rozpoznawanie. Stateless instancje IronTesseractIronOCR skalują się liniowo wraz z dostępnymi rdzeniami CPU. Podwojenie liczby rdzeni serwera przetwarzania wsadowego podwaja przepustowość bez zmian w konfiguracji i dodatkowych licencji.

Dostęp do danych strukturalnych jest natychmiastowy. OcrResult.Pages, Paragraphs, Lines, Words i Characters ujawniają kompletną strukturę dokumentu jako nawigowalną strukturę obiektów .NET. Pewność co do poszczególnych słów oraz współrzędne to właściwości każdego obiektu słowa. Nie ma dodatkowego potoku eksportu, konfiguracji formatu ani konieczności generowania plików wyjściowych w celu uzyskania dostępu do danych pozycyjnych.

Koszt jest stały i przewidywalny. Połączenie licencji SDK, rocznej konserwacji i opłat za wykonanie na stronę w ramach OmniPage tworzy koszt, który skaluje się wraz z wykorzystaniem i powtarza się co roku.IronOCR przy $999–$2,999 wieczyste to jednorazowy zakup. Przepustowość 500 000 stron rocznie, za które naliczane były opłaty za stronę, pozwala na zwrot kosztów licencji IronOCR w ciągu kilku tygodni. Centrum dokumentacji i samouczki IronOCR są dostępne bez umowy wsparcia technicznego.

Zwróć uwagęKofax OmniPage, OpenPDF i Tesseract są zarejestrowanymi znakami towarowymi ich odpowiednich właścicieli. Ta strona nie jest powiązana z, wspierana ani sponsorowana przez Google, Kofax czy LibrePDF. Wszystkie nazwy produktów, logo i marki są własnością ich odpowiednich właścicieli. Porównania mają charakter wyłącznie informacyjny i odzwierciedlają informacje dostępne publicznie w momencie pisania.

Często Zadawane Pytania

Dlaczego warto przejść z Kofax OmniPage na IronOCR?

Typowe czynniki motywujące to eliminacja złożoności interoperacyjności COM, zastąpienie zarządzania licencjami opartego na plikach, uniknięcie rozliczeń za stronę, umożliwienie wdrażania w Dockerze/kontenerach oraz przyjęcie natywnego dla NuGet przepływu pracy, który integruje się ze standardowymi narzędziami .NET.

Jakie są główne zmiany w kodzie podczas migracji z Kofax OmniPage do IronOCR?

Zastąp sekwencje inicjalizacji Kofax OmniPage instancjonowaniem IronTesseract, usuń zarządzanie cyklem życia COM (jawne wzorce Create/Load/Close) i zaktualizuj nazwy właściwości wyników. W rezultacie znacznie zmniejsza się liczba powtarzających się linii kodu.

Jak zainstalować IronOCR, aby rozpocząć migrację?

Uruchom polecenie „Install-Package IronOcr” w konsoli menedżera pakietów lub „dotnet add package IronOcr” w interfejsie CLI. Pakiety językowe są oddzielnymi pakietami: na przykład „dotnet add package IronOcr.Languages.French” dla języka francuskiego.

Czy IronOCR dorównuje dokładnością OCR programowi Kofax OmniPage w przypadku standardowych dokumentów biznesowych?

IronOCR zapewnia wysoką dokładność w przypadku standardowych treści biznesowych, w tym faktur, umów, paragonów i formularzy wypełnionych na komputerze. Filtry przetwarzania wstępnego obrazu (prostowanie, usuwanie szumów, wzmacnianie kontrastu) dodatkowo poprawiają rozpoznawanie w przypadku pogorszonej jakości danych wejściowych.

W jaki sposób IronOCR obsługuje dane językowe, które Kofax OmniPage instaluje oddzielnie?

Dane językowe w IronOCR są dystrybuowane jako pakiety NuGet. Polecenie „dotnet add package IronOcr.Languages.German” instaluje obsługę języka niemiećkiego. Nie wymaga to ręcznego umieszczania plików ani podawania ścieżek katalogów.

Czy migracja z Kofax OmniPage do IronOCR wymaga zmian w infrastrukturze wdrożeniowej?

IronOCR wymaga mniej zmian w infrastrukturze niż Kofax OmniPage. Nie ma ścieżek binarnych SDK, lokalizacji plików licencyjnych ani konfiguracji serwerów licencyjnych. Pakiet NuGet zawiera kompletny silnik OCR, a klucz licencyjny jest ciągiem znaków ustawionym w kodzie aplikacji.

Jak skonfigurować licencjonowanie IronOCR po migracji?

W kodzie uruchamiającym aplikację przypisz IronOcr.License.LicenseKey = „YOUR-KEY”. W Dockerze lub Kubernetesie zapisz klucz jako zmienną środowiskową i odczytaj go podczas uruchamiania. Użyj License.IsValidLicense do sprawdzenia ważności przed przyjęciem ruchu.

Czy IronOCR może przetwarzać pliki PDF w taki sam sposób jak Kofax OmniPage?

Tak. IronOCR odczytuje zarówno natywne, jak i zeskanowane pliki PDF. Należy utworzyć instancję IronTesseract, wywołać ocr.Read(input), gdzie input jest ścieżką do pliku PDF lub obiektem OcrPdfInput, a następnie iterować strony OcrResult. Nie jest wymagany oddzielny proces renderowania plików PDF.

W jaki sposób IronOCR radzi sobie z wątkami podczas przetwarzania dużych ilości danych?

IronTesseract można bezpiecznie instancjonować dla każdego wątku. Uruchom jedną instancję na wątek w Parallel.ForEach lub puli zadań, uruchom OCR równolegle i usuń każdą instancję po zakończeniu. Nie jest wymagany żaden stan globalny ani blokowanie.

Jakie formaty wyjściowe obsługuje IronOCR po wyodrębnieniu tekstu?

IronOCR zwraca ustrukturyzowane wyniki, w tym tekst, współrzędne słów, wyniki pewności i strukturę strony. Opcje eksportu obejmują zwykły tekst, PDF z możliwością wyszukiwania oraz obiekty wyników ustrukturyzowanych do dalszego przetwarzania.

Czy ceny IronOCR są bardziej przewidywalne niż Kofax OmniPage w przypadku skalowania obciążeń?

IronOCR stosuje licencję wieczystą z opłatą ryczałtową, bez opłat za stronę lub wolumen. Niezależnie od tego, czy przetwarzasz 10 000, czy 10 milionów stron, koszt licencji pozostaje stały. Opcje licencji wolumenowych i zespołowych znajdują się na stronie z cennikiem IronOCR.

Co stanie się z moimi istniejącymi testami po migracji z Kofax OmniPage do IronOCR?

Testy sprawdzające wyodrębnioną treść tekstową powinny nadal przechodzić pomyślnie po migracji. Testy weryfikujące wzorce wywołań API lub cykl życia obiektów COM będą wymagały aktualizacji, aby odzwierciedlały prostszy model inicjalizacji i wyników IronOCR.

Kannaopat Udonpant
Inżynier oprogramowania
Zanim stał się inżynierem oprogramowania, Kannapat ukończył doktorat z zasobów środowiskowych na Uniwersytecie Hokkaido w Japonii. W czasie studiowania, Kannapat również został członkiem Laboratorium Robotyki Pojazdów, które jest częścią Wydziału Inżynierii Bioprodukcji. W 2022 roku wykorzystał swoje umiejętności w ...
Czytaj więcej

Zespół wsparcia Iron

Jesteśmy online 24 godziny, 5 dni w tygodniu.
Czat
E-mail
Zadzwoń do mnie