Przejdź do treści stopki
PORóWNAJ Z INNYMI KOMPONENTAMI

IronOCR vs AWS Textract: Rozwiązania OCR dla startupów

GdPicture.NET wymaga licencji podstawowej, zanim zapłacisz dolara za wtyczkę OCR — a jeśli chcesz czytać pliki PDF lub tworzyć wyjścia przeszukiwalne, potrzebujesz też dodatkowych wtyczek PDF. Skontaktuj się z GdPicture, aby uzyskać aktualne ceny. Dla zespołu, który potrzebuje wydobywać tekst z obrazów i PDF, łączny koszt wielu wtyczek plus roczne opłaty za utrzymanie mogą się znacząco zwiększyć. Takie podejście wynika bezpośrednio z architektury GdPicture: jest to kompleksowa platforma do przetwarzania obrazów dokumentów, obejmująca skanowanie, DICOM, adnotacje, przetwarzanie BARCODE i edycję plików PDF, a OCR jest tylko jedną z wielu wtyczek. Zespoły, które potrzebują wyłącznie funkcji OCR, ponoszą koszty całego zestawu SDK do obrazówania dokumentów, z którego nigdy w pełni nie skorzystają.

API odzwierciedla tę samą filozofię. GdPicture używa całkowitych ID obrazów do śledzenia zasobów w pamięci — każdy załadowany obraz zwraca int, wywołujesz metody na tym identyfikatorze liczbowym, a następnie musisz go wyraźnie zwolnić, aby uniknąć wycieku pamięci. Ten wzorzec poprzedza IDisposable i using. To działa, ale za każdym razem nakłada na programistę ciężar podejmowania decyzji dotyczących czyszczenia danych. Niniejsze porównanie analizuje te dwa aspekty — model cenowy oparty na wtyczkach oraz cykl życia identyfikatorów obrazów — w kontekście złożoności API, przetwarzania wstępnego i obsługi plików PDF, przy czym jako punkt odniesienia służy IronOCR.

Zrozumienie GdPicture.NET

GdPicture.NET to komercyjny zestaw SDK do przetwarzania obrazów dokumentów opracowany przez firmę ORPALIS. Przez wiele lat rozbudowano ją do postaci szeroko zakrojonej platformy obejmującej przetwarzanie obrazów, tworzenie i edycję plików PDF, odczyt i generowanie BARCODE-ów, integrację skanerów TWAIN/WIA, obrazówanie medyczne DICOM, procesy adnotacji i recenzji oraz archiwizację dokumentów zgodną ze standardem PDF/A. OCR to jedna z funkcji w tym ekosystemie, udostępniana za pośrednictwem dedykowanej wtyczki.

SDK organizuje swoją funkcjonalność w odrębne moduły, z których każdy posiada własną klasę główną:

  • GdPictureImaging — ładowanie obrazów, przetwarzanie, konwersja formatów oraz źródło wszystkich identyfikatorów obrazów typu integer
  • GdPicturePDF — tworzenie, edycja i renderowanie plików PDF oraz operacje OCR na poziomie stron (wymagana oddzielna licencja na wtyczkę)
  • GdPictureOCR — rozpoznawanie i wyodrębnianie tekstu; wykorzystuje identyfikatory obrazów generowane przez GdPictureImaging
  • GdPicture1BARCODE / GdPicture2BARCODE — odczyt i zapis kodów kreskowych liniowych i 2D (oddzielne licencje na wtyczki)
  • GdPictureDocumentImaging — zaawansowane filtry do czyszczenia dokumentów, w tym prostowanie, usuwanie plam, usuwanie ramek i dziurek po dziurkaczu (oddzielna wtyczka)
  • GdPictureAnnotations — oznaczanie, recenzowanie i redagowanie dokumentów

Nawet podstawowa OCR wymaga inicjalizacji dwóch komponentów — GdPictureImaging do ładowania obrazu i GdPictureOCR do rozpoznawania tekstu — i zarządzania ich cyklami życia. OCR z PDF wymaga trzeciego: GdPicturePDF. Przestrzeń nazw zawiera numer wersji (GdPicture14), co oznacza, że każda większa aktualizacja SDK wymusza znalezienie i zamianę w całej bazie kodu.

Drzewo zależności wtyczek dla typowych scenariuszy OCR wygląda następująco:

Jeśli potrzebujesz Należy uzyskać licencję
OCR z obrazów Licencja podstawowa + wtyczka OCR
OCR z plików PDF Podstawa + wtyczka OCR + wtyczka PDF
Wynik w formacie PDF z możliwością wyszukiwania Podstawa + wtyczka OCR + wtyczka PDF
Porządkowanie dokumentów przed OCR Podstawa + wtyczka OCR + wtyczka do obrazówania dokumentów

Cykl życia identyfikatora obrazu

Cechą charakterystyczną architektury GdPicture jest zarządzanie identyfikatorami obrazów typu integer. Załadowanie dowolnego obrazu alokuje pamięć w środowisku wykonawczym GdPicture i zwraca uchwyt int. Używasz tej liczby całkowitej do odwołania się do obrazu we wszystkich kolejnych wywołaniach. Gdy skończysz, wywołasz ReleaseGdPictureImage z tym liczbą całkowitą. Jeśli tego nie zrobisz, pamięć nie zostanie zwolniona do momentu zakończenia procesu.

using GdPicture14;

// Every image load returns an integer handle
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);

if (imageId == 0)
{
    throw new Exception($"Failed to load image: {_imaging.GetStat()}");
}

try
{
    _ocr.SetImage(imageId);
    _ocr.Language = "eng";

    string resultId = _ocr.RunOCR();

    if (string.IsNullOrEmpty(resultId))
    {
        throw new Exception($"OCR failed: {_ocr.GetStat()}");
    }

    return _ocr.GetOCRResultText(resultId);
}
finally
{
    // CRITICAL: omitting this line causes a memory leak
    _imaging.ReleaseGdPictureImage(imageId);
}
using GdPicture14;

// Every image load returns an integer handle
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);

if (imageId == 0)
{
    throw new Exception($"Failed to load image: {_imaging.GetStat()}");
}

try
{
    _ocr.SetImage(imageId);
    _ocr.Language = "eng";

    string resultId = _ocr.RunOCR();

    if (string.IsNullOrEmpty(resultId))
    {
        throw new Exception($"OCR failed: {_ocr.GetStat()}");
    }

    return _ocr.GetOCRResultText(resultId);
}
finally
{
    // CRITICAL: omitting this line causes a memory leak
    _imaging.ReleaseGdPictureImage(imageId);
}
Imports GdPicture14

' Every image load returns an integer handle
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(imagePath)

If imageId = 0 Then
    Throw New Exception($"Failed to load image: {_imaging.GetStat()}")
End If

Try
    _ocr.SetImage(imageId)
    _ocr.Language = "eng"

    Dim resultId As String = _ocr.RunOCR()

    If String.IsNullOrEmpty(resultId) Then
        Throw New Exception($"OCR failed: {_ocr.GetStat()}")
    End If

    Return _ocr.GetOCRResultText(resultId)
Finally
    ' CRITICAL: omitting this line causes a memory leak
    _imaging.ReleaseGdPictureImage(imageId)
End Try
$vbLabelText   $csharpLabel

Podczas przetwarzania wielostronicowych plików PDF każda renderowana strona generuje oddzielny identyfikator obrazu. 100-stronicowy dokument o rozdzielczości 200 DPI może zajmować od 1 do 5 GB pamięci, jeśli nie zostanie poddany czyszczeniu. Poprawny wzorzec wymaga zebrania wszystkich ID i zwolnienia ich w bloku finally — ale ta dyscyplina spoczywa wyłącznie na deweloperze.

Zrozumienie IronOCR

IronOCR to komercyjna biblioteka OCR dla platformy .NET, zbudowana jako pojedynczy pakiet NuGet. Jej celem projektowym jest dokładność bez narzutu konfiguracyjnego: zainstaluj pakiet, ustaw klucz licencyjny, wywołaj Read. Biblioteka zawiera zoptymalizowany silnik Tesseract 5 z automatycznym przetwarzaniem wstępnym, natywną obsługą plików PDF oraz dostępem do ustrukturyzowanych wyników, a wszystko to udostępnione za pośrednictwem standardowych wzorców .NET.

Kluczowe cechy:

  • Pojedynczy pakiet NuGetdotnet add package IronOcr instaluje wszystko, w tym wsparcie dla języka angielskiego; brak zewnętrznych folderów zasobów, brak natywnego zarządzania plikami binarnymi
  • Standardowe zarządzanie zasobami .NETOcrInput implementuje IDisposable; oświadczenie using obsługuje całe sprzątanie niezależnie od wyjątków
  • Automatyczne przetwarzanie wstępne — Deskew, DeNoise, Contrast, Binarize i EnhanceResolution to jednowierszowe wywołania metod na OcrInput; silnik stosuje również automatyczne korekty bez wyraźnych instrukcji
  • Natychmiastowe wejście PDF — skanowane PDF i natywny PDF bezpośrednio trafiają do IronTesseract.Read bez oddzielnego kroku renderowania
  • Bezpieczeństwo wątków przez design — jedna instancja IronTesseract obsługuje równoczesne żądania; Parallel.ForEach działa bez dodatkowej synchronizacji
  • 125+ języków — dystrybuowane jako oddzielne pakiety NuGet (IronOcr.Languages.French, itd.), brak plików tessdata do zarządzania
  • Ustrukturyzowany dostęp do wynikówOcrResult eksponuje .Pages, .Lines, .Words, .Characters i .Barcodes jako kolekcje typowane z danymi o współrzędnych

Cena jest wieczysta: $999 Lite, $1,499 Plus, $2,999 Professional, $5,999 Unlimited. Wszystkie funkcje są dostępne na każdym poziomie; Różnica polega na liczbie programistów i projektów, których dotyczy.

Porównanie funkcji

Funkcja GdPicture.NET IronOCR
Model cenowy Wersja wieczysta oparta na wtyczkach + 20% rocznie za utrzymanie Stała licencja bezterminowa, opcjonalne aktualizacje roczne
Koszt wprowadzenia (OCR z plików PDF) Wymagane są różne wtyczki (skontaktuj się z GdPicture w sprawie cen). $2,999 (jeden pakiet, wszystkie funkcje)
Zarządzanie zasobami Ręczne śledzenie identyfikatorów całkowitoliczbowych i wydanie IDisposable / using oświadczenie
Stabilność przestrzeni nazw Numer wersji w przestrzeni nazw (GdPicture14) Niezależne od wersji (IronOcr)
OCR PDF Wymaga osobnej wtyczki PDF Wbudowane, bez dodatkowej licencji
Instalacja Wiele pakietów NuGet + folder zasobów zewnętrznych Pojedynczy pakiet NuGet, bez plików zewnętrznych
Wielopłatformowe Windows, Linux, macOS Windows, Linux, macOS, Docker, AWS, Azure

Szczegółowe porównanie funkcji

Funkcja GdPicture.NET IronOCR
Konfiguracja i instalacja
Instalacja NuGet Wymagane są różne pakiety dotnet add package IronOcr
Folder zasobów zewnętrznych Wymagane (pliki językowe w stylu tessdata) Nie jest wymagane (w pakiecie)
Aktywacja licencji LicenseManager.RegisterKEY() IronOcr.License.LicenseKey = "..."
Inicjalizacja komponentów 3–4 klasy dla przepływu pracy OCR plików PDF new IronTesseract()
Przestrzeń nazw w ramach dużej aktualizacji Konieczna jest aktualizacja każdego pliku źródłowego Nie wymaga zmian
Możliwości OCR
OCR obrazów Tak Tak
OCR PDF Tak (wymagana wtyczka PDF) Tak (wbudowane)
Plik PDF chroniony hasłem Tak Tak
Wielostronicowy plik PDF Pętla stron podręcznika + czyszczenie identyfikatorów Automatyczne
Wynik w formacie PDF z możliwością wyszukiwania OcrPage + SaveToFile result.SaveAsSearchablePdf()
eksport hOCR Nie Tak
Przetwarzanie wstępne
Wyrównanie Za pośrednictwem wtyczki GdPictureDocumentImaging input.Deskew()
Usuwanie szumów Za pośrednictwem wtyczki GdPictureDocumentImaging input.DeNoise()
Wzmocnienie kontrastu Za pośrednictwem GdPictureImaging input.Contrast()
Binaryzacja Za pośrednictwem GdPictureImaging input.Binarize()
Poprawa DPI Za pośrednictwem GdPictureImaging input.EnhanceResolution(300)
Automatyczna korekta (bez kodu) Nie Tak (wbudowane w Read)
Zarządzanie zasobami
Model zarządzania pamięcią Ręczne śledzenie identyfikatorów całkowitoliczbowych IDisposable / GC
Ryzyko wycieku pamięci Wysoka (brakuje ReleaseGdPictureImage) Brak (instrukcja using)
Bezpieczeństwo wątków Ręczne zarządzanie instancjami Zabezpieczone przed współbieżnością już w fazie projektowania
Wyniki i dane
Zwykły tekst GetOCRResultText(resultId) result.Text
Wskaźnik pewności GetOCRResultConfidence(resultId) result.Confidence
Dane na poziomie słów Wnękowe iteracje bloków/wierszy/słów WORD result.Words kolekcja
Koordynacja dostępu Poprzez wywołania indeksu bloków/wierszy/słów Bezpośredni .X, .Y, .Width, .Height
Odczytywanie BarCode podczas OCR Za pomocą oddzielnej wtyczki do BarCodes ocr.Configuration.ReadBarCodes = true
Języki
Liczba słów Oparte na Tesseract, podobny zakres Ponad 125 pakietów dostępnych za pośrednictwem NuGet
Rozkład językowy Pliki w folderze zasobów Pakiety NuGet
Wiele języków w jednym przejściu Tak Tak (AddSecondaryLanguage)
Wdrożenie
Docker Obsługiwane Obsługiwane (udokumentowane)
Linux Obsługiwane Obsługiwane
AWS Lambda Możliwe Dokumentowany przewodnik
Azure App Service Możliwe Dokumentowany przewodnik

Cykl życia identyfikatora obrazu a jednorazowy OcrInput

Najistotniejsza różnica architektoniczna między GdPicture a IronOCR nie polega na braku funkcji — dotyczy ona sposobu, w jaki każda z bibliotek zarządza pamięcią dla przetwarzanych obrazów.

Podejście GdPicture

Każdy obraz w GdPicture istnieje jako uchwyt typu integer w puli zarządzanej w czasie wykonywania. Uchwyt uzyskuje się poprzez załadowanie obrazu, przekazanie tej liczby całkowitej do OCR i innych operacji, a następnie zwolnienie go po zakończeniu. Wzór jest jasny i poprawny, jeśli się go przestrzega. Problem polega na tym, że łatwo popełnić błąd, a konsekwencją tego jest nieograniczony wzrost zużycia pamięci.

Przepływ pracy OCR plików PDF najlepiej ilustruje to ryzyko. Każde wywołanie pdf.RenderPageToGdPictureImage() przydziela nowy rastrowy obraz w pamięci i zwraca nowy całkowity ID. Dokument liczący 100 stron tworzy 100 oddzielnych przydziałów. Pominięcie jednego wywołania ReleaseGdPictureImage powoduje, że proces akumuluje przeciekającą pamięć:

using GdPicture14;

public string ExtractTextFromPdf(string pdfPath)
{
    var text = new StringBuilder();

    using var pdf = new GdPicturePDF();

    GdPictureStatus status = pdf.LoadFromFile(pdfPath, false);
    if (status != GdPictureStatus.OK)
        throw new Exception($"Failed to load PDF: {status}");

    int pageCount = pdf.GetPageCount();

    for (int i = 1; i <= pageCount; i++)
    {
        pdf.SelectPage(i);

        // Each page render = new memory allocation + new integer ID
        int imageId = pdf.RenderPageToGdPictureImage(200, false);

        if (imageId == 0) continue;

        try
        {
            _ocr.SetImage(imageId);
            _ocr.Language = "eng";
            string resultId = _ocr.RunOCR();

            if (!string.IsNullOrEmpty(resultId))
                text.AppendLine(_ocr.GetOCRResultText(resultId));
        }
        finally
        {
            // Without this: ~10–50MB leaked per page
            _imaging.ReleaseGdPictureImage(imageId);
        }
    }

    return text.ToString();
}
using GdPicture14;

public string ExtractTextFromPdf(string pdfPath)
{
    var text = new StringBuilder();

    using var pdf = new GdPicturePDF();

    GdPictureStatus status = pdf.LoadFromFile(pdfPath, false);
    if (status != GdPictureStatus.OK)
        throw new Exception($"Failed to load PDF: {status}");

    int pageCount = pdf.GetPageCount();

    for (int i = 1; i <= pageCount; i++)
    {
        pdf.SelectPage(i);

        // Each page render = new memory allocation + new integer ID
        int imageId = pdf.RenderPageToGdPictureImage(200, false);

        if (imageId == 0) continue;

        try
        {
            _ocr.SetImage(imageId);
            _ocr.Language = "eng";
            string resultId = _ocr.RunOCR();

            if (!string.IsNullOrEmpty(resultId))
                text.AppendLine(_ocr.GetOCRResultText(resultId));
        }
        finally
        {
            // Without this: ~10–50MB leaked per page
            _imaging.ReleaseGdPictureImage(imageId);
        }
    }

    return text.ToString();
}
Imports GdPicture14
Imports System.Text

Public Function ExtractTextFromPdf(ByVal pdfPath As String) As String
    Dim text As New StringBuilder()

    Using pdf As New GdPicturePDF()
        Dim status As GdPictureStatus = pdf.LoadFromFile(pdfPath, False)
        If status <> GdPictureStatus.OK Then
            Throw New Exception($"Failed to load PDF: {status}")
        End If

        Dim pageCount As Integer = pdf.GetPageCount()

        For i As Integer = 1 To pageCount
            pdf.SelectPage(i)

            ' Each page render = new memory allocation + new integer ID
            Dim imageId As Integer = pdf.RenderPageToGdPictureImage(200, False)

            If imageId = 0 Then Continue For

            Try
                _ocr.SetImage(imageId)
                _ocr.Language = "eng"
                Dim resultId As String = _ocr.RunOCR()

                If Not String.IsNullOrEmpty(resultId) Then
                    text.AppendLine(_ocr.GetOCRResultText(resultId))
                End If
            Finally
                ' Without this: ~10–50MB leaked per page
                _imaging.ReleaseGdPictureImage(imageId)
            End Try
        Next
    End Using

    Return text.ToString()
End Function
$vbLabelText   $csharpLabel

Sytuację komplikuje przetwarzanie wsadowe wielu plików PDF. Dokumentacja dla każdego for pętli musi zawierać notatkę przypominającą konserwatorom o zbieraniu ID w List<int> i ich zwolnieniu w finally. To zadanie związane z infrastrukturą, a nie z OCR.

Podejście IronOCR

OcrInput jest standardowym IDisposable. Deklaracja using gwarantuje sprzątanie, niezależnie czy metoda zwraca wartość normalnie, czy rzuca wyjątek. Nie ma żadnych identyfikatorów całkowitoliczbowych do śledzenia, nie ma oddzielnego komponentu obrazówania do zainicjowania i nie ma zewnętrznego etapu renderowania DPI dla stron PDF.

using IronOcr;

public string ExtractTextFromPdf(string pdfPath)
{
    // LoadPdf handles page rendering internally
    using var input = new OcrInput();
    input.LoadPdf(pdfPath);

    var result = new IronTesseract().Read(input);

    foreach (var page in result.Pages)
        Console.WriteLine($"Page {page.PageNumber}: {page.Text}");

    return result.Text;
    // using block exits — all internal resources released automatically
}
using IronOcr;

public string ExtractTextFromPdf(string pdfPath)
{
    // LoadPdf handles page rendering internally
    using var input = new OcrInput();
    input.LoadPdf(pdfPath);

    var result = new IronTesseract().Read(input);

    foreach (var page in result.Pages)
        Console.WriteLine($"Page {page.PageNumber}: {page.Text}");

    return result.Text;
    // using block exits — all internal resources released automatically
}
Imports IronOcr

Public Function ExtractTextFromPdf(pdfPath As String) As String
    ' LoadPdf handles page rendering internally
    Using input As New OcrInput()
        input.LoadPdf(pdfPath)

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

        For Each page In result.Pages
            Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
        Next

        Return result.Text
        ' using block exits — all internal resources released automatically
    End Using
End Function
$vbLabelText   $csharpLabel

W przypadku plików PDF chronionych hasłem parametr jest argumentem nazwanym, a nie oddzielnym przeciążeniem wymagającym dodatkowej kontroli stanu:

using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");

var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf("searchable-output.pdf");
using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");

var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf("searchable-output.pdf");
Imports IronOcr

Using input As New OcrInput()
    input.LoadPdf("encrypted.pdf", Password:="secret")

    Dim result = New IronTesseract().Read(input)
    result.SaveAsSearchablePdf("searchable-output.pdf")
End Using
$vbLabelText   $csharpLabel

Podręcznik wprowadzania plików PDF w IronOCR obejmuje dodatkowe opcje, w tym wybór zakresu stron. Dla zespołów zaznajomionych już z wzorcami IDisposable w całym Entity Framework, HttpClient i zarządzaniu strumieniem, OcrInput nie wymaga nowego modelu myślenia.

Koszt pakietu wtyczek

Dla aplikacji serwerowej, która wydobywa tekst z obrazów i PDF oraz tworzy wyjścia przeszukiwalne, stos licencji GdPicture wymaga kilku wtyczek. Skontaktuj się z GdPicture, aby uzyskać aktualne ceny licencji Professional, wtyczki OCR i wtyczki PDF. Coroczne opłaty za utrzymanie (zwykle procent całkowitej wartości licencji) gromadzą się z czasem.

IronOCR Professional obejmuje ten sam przebieg pracy w jednym pakiecie:

IronOCR Professional: $professionalLicense (jednorazowo)
Opcjonalne coroczne aktualizacje: $plusLicense/rok

Suma na 3 lata (wieczysta, bez aktualizacji): $professionalLicense

Różnica kosztów na wiele lat może być znaczna, w zależności od preferencji aktualizacji. Ta luka istnieje, ponieważ model wtyczek GdPicture jest wyceniony jako pełna platforma do przetwarzania obrazów dokumentów, a nie jako rozwiązanie przeznaczone do zadań związanych z OCR. Wtyczka OCR jest wymagana przed wtyczką PDF, która czyni ją użyteczną dla najczęstszego formatu wejściowego OCR.

Zespoły oceniające GdPicture pod kątem OCR płacą za funkcje, które rzadko pojawiają się w listach zadań skupionych na OCR: integrację skanerów TWAIN/WIA, obrazówanie medyczne DICOM, procesy tworzenia adnotacji i redagowania oraz zaawansowaną edycję plików PDF wykraczającą poza wyodrębnianie tekstu. Zobacz stronę licencjonowania IronOCR dla modelu cenowego, gdzie wszystkie funkcje są dostępne na każdym poziomie - bez wtyczek, bez dodatków, bez decyzji dotyczących licencjonowania na funkcje.

Złożoność API i przetwarzanie wstępne

GdPicture udostępnia przetwarzanie wstępne przez GdPictureImaging (kontrast, binaryzację, skalowanie rozdzielczości) oraz przez osobny dodatek GdPictureDocumentImaging (deskew, despeckle, usuwanie ramki). Zastosowanie funkcji prostowania przed OCR wymaga licencji na wtyczkę Document Imaging, co powoduje powstanie trzeciego kosztu w stosie dla każdego przepływu pracy, który przetwarza zeskanowane dokumenty o zmiennej jakości.

Podejście GdPicture

Pełny przebieg pracy w przypadku skanowanego pliku PDF o niskiej jakości — ładowanie, przetwarzanie wstępne, OCR każdej strony, wydanie — obejmuje trzy klasy komponentów i wymaga starannego sprawdzania statusu na każdym etapie:

using GdPicture14;

public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
    using var pdf = new GdPicturePDF();

    GdPictureStatus status = pdf.LoadFromFile(inputPdf, false);
    if (status != GdPictureStatus.OK)
        throw new Exception($"Load failed: {status}");

    int pageCount = pdf.GetPageCount();

    for (int i = 1; i <= pageCount; i++)
    {
        pdf.SelectPage(i);

        // OcrPage adds text layer to each page
        // Requires: OCR plugin + PDF plugin + resource folder path
        GdPictureStatus ocrStatus = pdf.OcrPage(
            "eng",
            @"C:\GdPicture\Resources\OCR",  // Folder zasobów zewnętrznych required
            "",
            200
        );

        if (ocrStatus != GdPictureStatus.OK)
            Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}");
    }

    pdf.SaveToFile(outputPdf, true);
}
using GdPicture14;

public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
    using var pdf = new GdPicturePDF();

    GdPictureStatus status = pdf.LoadFromFile(inputPdf, false);
    if (status != GdPictureStatus.OK)
        throw new Exception($"Load failed: {status}");

    int pageCount = pdf.GetPageCount();

    for (int i = 1; i <= pageCount; i++)
    {
        pdf.SelectPage(i);

        // OcrPage adds text layer to each page
        // Requires: OCR plugin + PDF plugin + resource folder path
        GdPictureStatus ocrStatus = pdf.OcrPage(
            "eng",
            @"C:\GdPicture\Resources\OCR",  // Folder zasobów zewnętrznych required
            "",
            200
        );

        if (ocrStatus != GdPictureStatus.OK)
            Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}");
    }

    pdf.SaveToFile(outputPdf, true);
}
Imports GdPicture14

Public Sub CreateSearchablePdf(inputPdf As String, outputPdf As String)
    Using pdf As New GdPicturePDF()

        Dim status As GdPictureStatus = pdf.LoadFromFile(inputPdf, False)
        If status <> GdPictureStatus.OK Then
            Throw New Exception($"Load failed: {status}")
        End If

        Dim pageCount As Integer = pdf.GetPageCount()

        For i As Integer = 1 To pageCount
            pdf.SelectPage(i)

            ' OcrPage adds text layer to each page
            ' Requires: OCR plugin + PDF plugin + resource folder path
            Dim ocrStatus As GdPictureStatus = pdf.OcrPage(
                "eng",
                "C:\GdPicture\Resources\OCR",  ' Folder zasobów zewnętrznych required
                "",
                200
            )

            If ocrStatus <> GdPictureStatus.OK Then
                Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}")
            End If
        Next

        pdf.SaveToFile(outputPdf, True)
    End Using
End Sub
$vbLabelText   $csharpLabel

Ścieżka ResourceFolder nie jest opcjonalna. Musi rozwiązać się do katalogu zawierającego pliki językowe .traineddata w czasie pracy. Ta ścieżka działa na maszynie deweloperskiej, a następnie zawodzi w środowisku produkcyjnym, gdy konto serwisowe nie widzi C:\GdPicture\Resources\OCR, lub gdy aplikacja jest wdrażana na Linuksie, lub gdy obrazyDockernie zawierają tej struktury katalogu. Debugowanie tych awarii często oznacza pogoń za ogólnymi kodami błędów GdPictureStatus, które mówią niewiele o przyczynie korzeniowej.

Podejście IronOCR

Odpowiedni przebieg pracy w IronOCR— w tym przetwarzanie wstępne w celu wyprostowania i usunięcia szumów — to pięć wierszy:

using IronOcr;

public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
    var ocr = new IronTesseract();

    using var input = new OcrInput();
    input.LoadPdf(inputPdf);
    input.Deskew();   // Nie separate plugin required
    input.DeNoise();

    var result = ocr.Read(input);
    result.SaveAsSearchablePdf(outputPdf);
}
using IronOcr;

public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
    var ocr = new IronTesseract();

    using var input = new OcrInput();
    input.LoadPdf(inputPdf);
    input.Deskew();   // Nie separate plugin required
    input.DeNoise();

    var result = ocr.Read(input);
    result.SaveAsSearchablePdf(outputPdf);
}
Imports IronOcr

Public Sub CreateSearchablePdf(inputPdf As String, outputPdf As String)
    Dim ocr As New IronTesseract()

    Using input As New OcrInput()
        input.LoadPdf(inputPdf)
        input.Deskew() ' Nie separate plugin required
        input.DeNoise()

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

Obsługa języka angielskiego jest wbudowana w pakiet NuGet. Dodatkowe języki są instalowane jako pakiety NuGet (IronOcr.Languages.French) zamiast plików .traineddata w ścieżce systemu plików. Przewodnik dotyczący korekty jakości obrazu i przewodnik dotyczący korekty orientacji obrazu obejmują pełny zestaw opcji przetwarzania wstępnego dostępnych na OcrInput.

W przypadku przetwarzania uwzględniającego poziom pewności — na przykład filtrowania wyników poniżej progu przed zapisaniem do bazy danych — obiekt wyniku bezpośrednio ujawnia poziom pewności:

var result = new IronTesseract().Read("scanned.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");

// Per-word confidence for fine-grained filtering
var highConfidenceWords = result.Words
    .Where(w => w.Confidence > 85)
    .Select(w => w.Text);
var result = new IronTesseract().Read("scanned.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");

// Per-word confidence for fine-grained filtering
var highConfidenceWords = result.Words
    .Where(w => w.Confidence > 85)
    .Select(w => w.Text);
Imports System
Imports System.Linq

Dim result = (New IronTesseract()).Read("scanned.jpg")
Console.WriteLine($"Confidence: {result.Confidence}%")

' Per-word confidence for fine-grained filtering
Dim highConfidenceWords = result.Words _
    .Where(Function(w) w.Confidence > 85) _
    .Select(Function(w) w.Text)
$vbLabelText   $csharpLabel

GdPicture wymaga trzech zagnieżdżonych pętli — bloków, linii, słów — aby osiągnąć te same dane, z metodami wywoływanymi na każdym poziomie (GetOCRResultBlockLineWordConfidence(resultId, b, l, w)). Instrukcja dotycząca oceny pewności pokazuje model dostępu strukturalnego dla typowych przypadków użycia.

Dane ustrukturyzowane i dostęp do wyników

Wyodrębnianie współrzędnych i wartości pewności dla poszczególnych WORD-ów jest powszechnym wymaganiem w procesach rozumienia dokumentów — jest to niezbędne przy wyodrębnianiu pól z faktur, przetwarzaniu formularzy i analizie układu.

Podejście GdPicture

GdPicture zwraca ciąg resultId z RunOCR(), a wszystkie dane wynikowe są zapytane za pomocą tego ID poprzez wywołania metod na instancji GdPictureOCR. Osiągnięcie pewności co do poszczególnych słów wymaga przejścia przez trzy zagnieżdżone poziomy:

using GdPicture14;

public List<(string word, float confidence)> GetWordConfidences(int imageId)
{
    var words = new List<(string, float)>();

    _ocr.SetImage(imageId);
    _ocr.Language = "eng";
    string resultId = _ocr.RunOCR();

    int blockCount = _ocr.GetOCRResultBlockCount(resultId);

    for (int b = 0; b < blockCount; b++)
    {
        int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);

        for (int l = 0; l < lineCount; l++)
        {
            int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);

            for (int w = 0; w < wordCount; w++)
            {
                string word = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w);
                float conf = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w);
                words.Add((word, conf));
            }
        }
    }

    return words;
}
using GdPicture14;

public List<(string word, float confidence)> GetWordConfidences(int imageId)
{
    var words = new List<(string, float)>();

    _ocr.SetImage(imageId);
    _ocr.Language = "eng";
    string resultId = _ocr.RunOCR();

    int blockCount = _ocr.GetOCRResultBlockCount(resultId);

    for (int b = 0; b < blockCount; b++)
    {
        int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);

        for (int l = 0; l < lineCount; l++)
        {
            int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);

            for (int w = 0; w < wordCount; w++)
            {
                string word = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w);
                float conf = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w);
                words.Add((word, conf));
            }
        }
    }

    return words;
}
Imports GdPicture14

Public Function GetWordConfidences(imageId As Integer) As List(Of (word As String, confidence As Single))
    Dim words As New List(Of (String, Single))()

    _ocr.SetImage(imageId)
    _ocr.Language = "eng"
    Dim resultId As String = _ocr.RunOCR()

    Dim blockCount As Integer = _ocr.GetOCRResultBlockCount(resultId)

    For b As Integer = 0 To blockCount - 1
        Dim lineCount As Integer = _ocr.GetOCRResultBlockLineCount(resultId, b)

        For l As Integer = 0 To lineCount - 1
            Dim wordCount As Integer = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l)

            For w As Integer = 0 To wordCount - 1
                Dim word As String = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w)
                Dim conf As Single = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w)
                words.Add((word, conf))
            Next
        Next
    Next

    Return words
End Function
$vbLabelText   $csharpLabel

To nie jest błąd — dane są dostępne. Wymaga to jednak zrozumienia i utrzymania trójwymiarowego indeksu w strukturze wynikowej dla każdego projektu, który wymaga danych na poziomie słów.

Podejście IronOCR

OcrResult eksponuje .Words jako kolekcję typowaną. LINQ działa bezpośrednio w oparciu o to:

using IronOcr;

var result = new IronTesseract().Read("invoice.jpg");

// All words with position and confidence
foreach (var word in result.Words)
{
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}");
}

// Lines, paragraphs, and pages follow the same pattern
foreach (var line in result.Lines)
    Console.WriteLine(line.Text);

foreach (var page in result.Pages)
    Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters");
using IronOcr;

var result = new IronTesseract().Read("invoice.jpg");

// All words with position and confidence
foreach (var word in result.Words)
{
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}");
}

// Lines, paragraphs, and pages follow the same pattern
foreach (var line in result.Lines)
    Console.WriteLine(line.Text);

foreach (var page in result.Pages)
    Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters");
Imports IronOcr

Dim result = New IronTesseract().Read("invoice.jpg")

' All words with position and confidence
For Each word In result.Words
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}")
Next

' Lines, paragraphs, and pages follow the same pattern
For Each line In result.Lines
    Console.WriteLine(line.Text)
Next

For Each page In result.Pages
    Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters")
Next
$vbLabelText   $csharpLabel

OCR oparte na regionach — wyodrębnianie tekstu z określonego prostokąta w dokumencie — jest równie proste:

var region = new CropRectangle(0, 0, 600, 100); // header area

using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);

var headerText = new IronTesseract().Read(input).Text;
var region = new CropRectangle(0, 0, 600, 100); // header area

using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);

var headerText = new IronTesseract().Read(input).Text;
Imports IronOcr

Dim region As New CropRectangle(0, 0, 600, 100) ' header area

Using input As New OcrInput()
    input.LoadImage("invoice.jpg", region)

    Dim headerText As String = New IronTesseract().Read(input).Text
End Using
$vbLabelText   $csharpLabel

Przewodnik po wynikach odczytu oraz przewodnik po OCR opartym na regionach pokazują, w jaki sposób wzorce te można zastosować w przypadku dokumentów wielostronicowych oraz procesów ekstrakcji pól ustrukturyzowanych.

Przewodnik po mapowaniu API

GdPicture.NET Odpowiednik IronOCR
LicenseManager.RegisterKEY("key") IronOcr.License.LicenseKey = "key"
new GdPictureImaging() Nie jest wymagane — obsługiwane wewnętrznie
new GdPictureOCR() new IronTesseract()
new GdPicturePDF() Nie wymaga — OcrInput.LoadPdf() obsługuje to
ocr.ResourceFolder = path Nie jest wymagane — zasoby dołączone w pakiecie NuGet
imaging.CreateGdPictureImageFromFile(path) input.LoadImage(path) na OcrInput
imaging.ReleaseGdPictureImage(imageId) using var input = new OcrInput() — automatyczny
ocr.SetImage(imageId) Nie wymaga — OcrInput przechowuje obraz
ocr.Language = "eng" ocr.Language = OcrLanguage.English
ocr.RunOCR()resultId ocr.Read(input)OcrResult
ocr.GetOCRResultText(resultId) result.Text
ocr.GetOCRResultConfidence(resultId) result.Confidence
ocr.GetOCRResultBlockLineWordText(resultId, b, l, w) result.Words[i].Text
ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w) result.Words[i].Confidence
pdf.LoadFromFile(path, false)GdPictureStatus input.LoadPdf(path) — rzuca wyjątek przy niepowodzeniu
pdf.LoadFromFile(path, password) input.LoadPdf(path, Password: password)
pdf.RenderPageToGdPictureImage(200, false) Nie jest wymagane —IronOCR renderuje wewnętrznie
pdf.SelectPage(i) Nie jest wymagane — wszystkie strony przetwarzane domyślnie
pdf.GetPageCount() Nie wymaga — lub result.Pages.Count
pdf.OcrPage("eng", resourcePath, "", 200) result.SaveAsSearchablePdf(outputPath)
pdf.SaveToFile(outputPath, true) result.SaveAsSearchablePdf(outputPath)
imaging.GetStat() / ocr.GetStat() Standardowe wyjątki .NET Standard
GdPictureStatus.OK sprawdzenie po każdym wywołaniu Nie jest wymagane — wyjątki są propagowane normalnie
using GdPicture14; using IronOcr;

Kiedy zespoły rozważają przejście z GdPicture.NET na IronOCR

Jedynym wymaganiem jest OCR

Zespoły wdrażające procesy pozyskiwania dokumentów — przyjmowanie zeskanowanych faktur, przetwarzanie formularzy medycznych, wyodrębnianie treści umów — często rozważają GdPicture, ponieważ pojawia się ono w katalogach oprogramowania Enterprise obok LEADTOOLS i Kofax. Gdy tabela zależności wtyczek stanie się jasna, sytuacja ulegnie zmianie. Wtyczka PDF nie jest opcjonalna, jeśli wymagane jest wprowadzanie danych w formacie PDF. Wtyczka Document Imaging Plugin nie jest opcjonalna, jeśli wymagane jest przetwarzanie wstępne. Zespół, który potrzebuje OCR z zeskanowanych PDF-ów z korekcją deskew, kończy z trzema licencjami na wtyczki przy znaczącym koszcie wejścia na poziom Professional. Gdy wymóg to ekstrakcja tekstu i nic z listy funkcji GdPicture poza tym nie jest potrzebne, taka cena to czysty koszt ogólny.IronOCR na $2,999 Professional obejmuje identyczny proces roboczy — wejście obrazów, wejście PDF, przetwarzanie wstępne, wyjście wyszukiwalnego PDF — z jednego pakietu bez potrzeby podejmowania decyzji dotyczących wtyczek.

Przypadki wycieków pamięci w środowisku produkcyjnym

Cykl życia identyfikatorów całkowitoliczbowych staje się potencjalnym incydentem produkcyjnym w usługach przetwarzania dokumentów o dużej przepustowości. Punkt końcowy interfejsu API sieci Web, który przetwarza przesłane pliki PDF pod obciążeniem, będzie w końcu miał ścieżkę kodu, w której wywołanie zwolnienia obrazu nie zostanie osiągnięte — wczesny powrót w gałęzi błędu, nieobsługiwany wyjątek przed blokiem czyszczenia lub po prostu nowy programista, który nie zna tego wzorca, dodający metodę pomocniczą, która przyjmuje jako parametr całkowitoliczbowy uchwyt obrazu i zapomina go zwolnić. Pamięć się zapełnia, usługa zwalnia, a przyczyna tego nie jest oczywista w zrzucie sterty. Zespoły, które debugowały jeden z takich incydentów, zazwyczaj chcą modelu, w którym środowisko uruchomieniowe zajmuje się czyszczeniem. Standardowy wzorzec usuwania w IronOCR to właśnie ten model — uporządkowane czyszczenie wymuszane przez kompilator, a nie przez dyscyplinę programisty w każdym miejscu wywołania.

Trudności związane z aktualizacją wersji

GdPicture umieszcza numer głównej wersji w swojej przestrzeni nazw. Aktualizacja z wersji 14 do wersji 15 wymaga zaktualizowania tej dyrektywy przestrzeni nazw w każdym pliku źródłowym, który odwołuje się do klas GdPicture. W dużej aplikacji z OCR, obsługą plików PDF i przetwarzaniem obrazów rozłożonym na dziesiątki usług i klas narzędziowych jest to niebanalne zadanie migracyjne — i nie zapewnia żadnych korzyści funkcjonalnych. Każda nowoczesna biblioteka .NET, od Microsoft.EntityFrameworkCore po Newtonsoft.Json, wykorzystuje przestrzenie nazw niezależne od wersji, zarządzając wersjonowaniem za pomocą numeru wersji pakietu NuGet.IronOCR przestrzega tej konwencji: ten sam import przestrzeni nazw obowiązuje od wersji 1 do aktualnej wersji.

Wdrażanie mikrousług i kontenerów

GdPicture OCR wymaga, aby w czasie wykonywania w określonej ścieżce znajdował się zewnętrzny folder zasobów zawierający pliki danych językowych. W przypadku wdrożenia kontenerowego oznacza to albo wbudowanie tych plików w obraz Docker, zamontowanie woluminu, albo skonfigurowanie skryptu startowego w celu ich pobrania. Typowym rezultatem jest obrazDockero kilkaset megabajtów większy niż to konieczne, pominięta pozycja na liście kontrolnej wdrożenia oraz awarie produkcyjne podczas czystego restartu kontenerów, w których wolumin nie jest zamontowany.IronOCR zawiera obsługę języka angielskiego w samym pakiecie; Dodatkowe języki instaluje się jako pakiety NuGet, które są częścią wyników kompilacji. Kontener pobiera potrzebne dane z etapu przywracania i nie ma żadnych ścieżek do skonfigurowania. Przewodnik wdrażania Docker oraz przewodnik wdrażania Linux obejmują konkretną konfigurację dla każdego środowiska docelowego.

Zespoły programistów bez doświadczenia w zakresie obrazówania dokumentów

Zakres działania GdPicture jest z konieczności szeroki — obejmuje on pełną platformę do przetwarzania obrazów dokumentów. Dla programisty dołączającego do zespołu zajmującego się utrzymaniem mikrousługi OCR zrozumienie komponentu obrazówania, komponentu OCR, komponentu PDF, cyklu życia identyfikatorów całkowitoliczbowych, obsługi kodów zwrotnych statusu oraz konfiguracji folderów zasobów stanowi spore wyzwanie na początku. Powierzchnia robocza IronOCR do OCR składa się z trzech klas: silnika, kontenera wejściowego i obiektu wynikowego. To jest cały model mentalny dla 90% przypadków użycia. Wprowadzenie nowego programisty oznacza skierowanie go do instrukcji konfiguracji IronTesseract, a nie do wielomodułowego przewodnika po SDK.

Typowe kwestie związane z migracją

Zastępowanie inicjalizacji komponentów

GdPicture wymaga czterostopniowej sekwencji inicjalizacji: zarejestruj klucz licencyjny za pomocą LicenseManager, zainicjalizuj GdPictureImaging, zainicjalizuj GdPictureOCR oraz ustaw ścieżkę folderu zasobów.IronOCR redukuje to do przypisania jednej właściwości, które należy do Program.cs lub Startup.cs:

// Remove
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR";

// Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY";
// IronTesseract instances are instantiated per-use or as a singleton
// Remove
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR";

// Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY";
// IronTesseract instances are instantiated per-use or as a singleton
' Remove
Dim lm As New LicenseManager()
lm.RegisterKEY("GDPICTURE-LICENSE-KEY")
_imaging = New GdPictureImaging()
_ocr = New GdPictureOCR()
_ocr.ResourceFolder = "C:\GdPicture\Resources\OCR"

' Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY"
' IronTesseract instances are instantiated per-use or as a singleton
$vbLabelText   $csharpLabel

Eliminacja śledzenia identyfikatorów obrazów

Każde wywołanie CreateGdPictureImageFromFile i każde wywołanie RenderPageToGdPictureImage ma odpowiadające wywołanie ReleaseGdPictureImage gdzieś w istniejącej bazie kodu. Te wywołania sprzątania są całkowicie usunięte w IronOCR— OcrInput obsługuje diszalowanie. Migracja jest mechaniczna: znajdź każde int imageId = ..., znajdź jej sparowane ReleaseGdPictureImage(imageId), owiń kod załadowania w using var input = new OcrInput() i zastąp wywołania metod GdPicture ich odpowiednikami w IronOCR.

// Remove
int imageId = _imaging.CreateGdPictureImageFromFile(path);
if (imageId == 0) throw new Exception(_imaging.GetStat().ToString());
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId)) throw new Exception(_ocr.GetStat().ToString());
string text = _ocr.GetOCRResultText(resultId);
_imaging.ReleaseGdPictureImage(imageId);

// Replace with
using var input = new OcrInput();
input.LoadImage(path);
var result = new IronTesseract().Read(input);
string text = result.Text;
// Remove
int imageId = _imaging.CreateGdPictureImageFromFile(path);
if (imageId == 0) throw new Exception(_imaging.GetStat().ToString());
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId)) throw new Exception(_ocr.GetStat().ToString());
string text = _ocr.GetOCRResultText(resultId);
_imaging.ReleaseGdPictureImage(imageId);

// Replace with
using var input = new OcrInput();
input.LoadImage(path);
var result = new IronTesseract().Read(input);
string text = result.Text;
Imports System

' Remove
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(path)
If imageId = 0 Then Throw New Exception(_imaging.GetStat().ToString())
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then Throw New Exception(_ocr.GetStat().ToString())
Dim text As String = _ocr.GetOCRResultText(resultId)
_imaging.ReleaseGdPictureImage(imageId)

' Replace with
Using input As New OcrInput()
    input.LoadImage(path)
    Dim result = New IronTesseract().Read(input)
    Dim text As String = result.Text
End Using
$vbLabelText   $csharpLabel

Dostosowanie obsługi błędów

GdPicture używa kodów zwrotnych GdPictureStatus sprawdzanych po każdej znaczącej operacji.IronOCR generuje standardowe wyjątki .NET. Migracja zastępuje strażników if (status != GdPictureStatus.OK) blokami try/catch, które obsługują IronOcr.Exceptions.OcrException dla specyficznych dla OCR niepowodzeń oraz standardowymi IOException i FileNotFoundException dla niepowodzeń wejścia. Samouczek dotyczący odczytywania tekstu z obrazów obejmuje wzorce obsługi błędów w typowych scenariuszach.

Wdrażanie pakietu językowego

Pliki języków GdPicture to pliki .traineddata w folderze systemu plików. Pakiety językowe IronOCRsą pakietami NuGet. Migracja usuwa folder zasobów z manifestu wdrożenia i dodaje odwołania do pakietów NuGet dla każdego wymaganego języka:

# Remove filesystem dependency for each language
# Add NuGet package instead
dotnet add package IronOcr.Languages.French
dotnet add package IronOcr.Languages.German
dotnet add package IronOcr.Languages.ChineseSimplified
# Remove filesystem dependency for each language
# Add NuGet package instead
dotnet add package IronOcr.Languages.French
dotnet add package IronOcr.Languages.German
dotnet add package IronOcr.Languages.ChineseSimplified
SHELL

Przewodnik dotyczący wielu języków opisuje konfigurację dla dokumentów wielojęzycznych, gdzie zarówno podstawowe, jak i drugorzędne języki są określone na instancji IronTesseract.

Dodatkowe możliwości IronOCR

Oprócz obszarów objętych tym porównaniem,IronOCR zawiera funkcje, które nie mają bezpośrednich odpowiedników w GdPicture w kontekście czystego OCR:

  • Async OCRReadAsync dla operacji nieblokujących w ASP.NET Core, obsługujących żądania i usługi w tle
  • Wykrywanie obróconych stron — automatyczne wykrywanie i korekta obróconych stron bez ręcznego przetwarzania wstępnego
  • Śledzenie postępu — zdarzenia postępu oparte na wywołaniach zwrotnych dla długotrwałych zadań wsadowych, wyświetlane na paskach postępu w interfejsie użytkownika
  • Wejście strumienioweinput.LoadImage(stream) akceptuje System.IO.Stream bezpośrednio, unikając tymczasowego zapisywania plików w architekturach potokowych
  • Specjalizowane czytanie dokumentów — dedykowana obsługa paszportów, tablic rejestracyjnych, czeków MICR i ręcznie pisanych tekstów przez ten sam interfejs IronTesseract

Zgodność z platformą .NET i gotowość na przyszłość

IronOCR jest przeznaczony dla platform .NET 8, .NET 9, .NET Standard 2.0 oraz .NET Framework 4.6.2 i nowszych. Pojedynczy pakiet NuGet instaluje się identycznie w systemach Windows x64, Windows x86,Linuxx64 i macOS. GdPicture.NET obsługuje również platformy krzyżowe, ale jego architektura wtyczek oznacza, że wdrożenia w systemieLinuxi kontenerach muszą indywidualnie uwzględniać natywne zależności każdej wtyczki. Przestrzeń nazw IronOCR pozostaje IronOcr przy wszystkich głównych zmianach wersji, co oznacza, że ścieżki aktualizacji nie wymagają operacji znajdź-i-zamień w całej bazie kodu. Wraz z pojawieniem się .NET 10 pod koniec 2026 r. dotychczasowe osiągnięcia IronOCR w zakresie utrzymania kompatybilności między kolejnymi wersjami .NET bez naruszania zmian API stanowią stabilną podstawę dla aplikacji o długich cyklach utrzymania.

Wnioski

GdPicture.NET to doskonały wybór dla zespołów, które potrzebują zintegrowanej platformy do przetwarzania obrazów dokumentów — integracji skanera, edycji plików PDF, dodawania adnotacji, obsługi DICOM oraz OCR w jednym pakiecie SDK od jednego dostawcy. Taki przypadek użycia istnieje. Model wtyczki ma sens, gdy większość tych możliwości faktycznie mieści się w zakresie.

Niezgodność pojawia się, gdy wymaganiem jest OCR, a odpowiedzią jest GdPicture. Wtyczka PDF jest nierozerwalnie związana z zastosowaniem OCR z plików PDF. Wtyczka do przetwarzania obrazów dokumentów jest nierozerwalnie związana z przetwarzaniem wstępnym. Cykl życia identyfikatorów całkowitoliczbowych nie jest opcjonalny — stanowi podstawowy model zarządzania zasobami dla całego zestawu SDK. Zespół, który musi wyodrębniać tekst ze skanowanych plików PDF, bierze na siebie całą tę złożoność i wszystkie związane z tym koszty, a żadna z dodatkowych funkcji nie uzasadnia tego w kontekście ich obciążenia pracą.

Różnica cen na przestrzeni wielu lat może być znacząca dla jednego programisty korzystającego z profesjonalnego przepływu pracy. Różnica w złożoności kodu jest wymierna: ponad 25 linii dla podstawowego OCR z czyszczeniem w porównaniu z jedną linią. Luka operacyjna — foldery zasobów zewnętrznych, przestrzenie nazw specyficzne dla wersji, inicjalizacja wielu komponentów — przejawia się raczej w postaci utrudnień związanych z wdrażaniem i czasem wdrożenia niż w liczbie wierszy, ale jest ona realna.

IronOCR na $2,999 wieczyste zapewnia takie same podstawowe wyniki OCR — ekstrakcja tekstu z obrazów, przetwarzanie skanowanych PDF, wyjście w wyszukiwalnym PDF, 125+ języków, ocena wiarygodności, ustrukturyzowany dostęp do danych — przez standardowe wzorce .NET, które nie wymagają specjalistycznej wiedzy o SDK do utrzymania. Dla zespołów, dla których OCR jest celem samym w sobie, a nie elementem szerszej platformy do zarządzania dokumentami, jest to bardziej odpowiednie rozwiązanie.

Zwróć uwagęGdPicture.NET, Kofax OmniPage, LEADTOOLS i Tesseract są zarejestrowanymi znakami towarowymi odpowiednich właścicieli. Ta strona nie jest powiązana z, zatwierdzona przez, ani sponsorowana przez Apryse, Google, Kofax, LEAD Technologies, Nutrient lub ORPALIS. 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

Czym jest GdPicture.NET OCR?

GdPicture.NET OCR to rozwiązanie OCR wykorzystywane przez programistów i przedsiębiorstwa do wyodrębniania tekstu z obrazów i dokumentów. Jest to jedna z kilku opcji OCR ocenianych obok IronOCR for .NET pod kątem tworzenia aplikacji .NET.

Jak IronOCR wypada w porównaniu z GdPicture.NET OCR dla programistów .NET?

IronOCR to natywna biblioteka OCR .NET dla NuGet, wykorzystująca IronTesseract jako główny silnik. W porównaniu z GdPicture.NET OCR oferuje prostsze wdrożenie (bez instalatorów SDK), stałą cenę oraz przejrzysty interfejs API w języku C# bez interoperacyjności COM i zależności od chmury.

Czy IronOCR jest łatwiejszy w konfiguracji niż GdPicture.NET OCR?

IronOCR instaluje się za pomocą jednego pakietu NuGet. Nie ma żadnych instalatorów SDK, plików licencyjnych do skopiowania, komponentów COM do zarejestrowania ani oddzielnych plików binarnych środowiska uruchomieniowego, którymi trzeba by zarządzać. Cały silnik OCR jest zawarty w pakiecie.

Jakie różnice w dokładności występują między GdPicture.NET OCR a IronOCR?

IronOCR osiąga wysoką dokładność rozpoznawania standardowych dokumentów biznesowych, faktur, paragonów i zeskanowanych formularzy. W przypadku dokumentów o bardzo niskiej jakości lub rzadkich skryptów dokładność zależy od jakości źródła. IronOCR zawiera filtry wstępnego przetwarzania obrazu, które poprawiają rozpoznawanie danych wejściowych o niskiej jakości.

Czy IronOCR obsługuje wyodrębnianie tekstu z plików PDF?

Tak. IronOCR wyodrębnia tekst zarówno z natywnych plików PDF, jak i ze skanowanych obrazów PDF za pomocą jednego wywołania. Obsługuje również wielostronicowe pliki TIFF, obrazy i strumienie. W przypadku skanowanych plików PDF OCR jest stosowany strona po stronie, z obiektami wynikowymi dla każdej strony.

Czym różni się licencjonowanie GdPicture.NET OCR od IronOCR?

IronOCR korzysta z licencji wieczystej o stałej stawce, bez opłat za stronę lub skan. Organizacje przetwarzające duże ilości dokumentów płacą ten sam koszt licencji niezależnie od ilości. Szczegóły i ceny hurtowe znajdują się na stronie licencji IronOCR.

Jakie języki obsługuje IronOCR?

IronOCR obsługuje 127 języków za pośrednictwem oddzielnych pakietów językowych NuGet. Dodanie języka wymaga wykonania pojedynczego polecenia „dotnet add package IronOcr.Languages.{Language}”. Nie jest wymagane ręczne umieszczanie plików ani konfiguracja ścieżek.

Jak zainstalować IronOCR w projekcie .NET?

Instalacja przez NuGet: „Install-Package IronOcr” w konsoli menedżera pakietów lub „dotnet add package IronOcr” w CLI. Dodatkowe pakiety językowe instaluje się w ten sam sposób. Nie jest wymagany natywny instalator SDK.

Czy IronOCR nadaje się do wdrożeń w Dockerze i kontenerach, w przeciwieństwie do GdPicture.NET?

Tak. IronOCR działa w kontenerach Docker za pośrednictwem pakietu NuGet. Klucz licencyjny jest ustawiany za pomocą zmiennej środowiskowej. Silnik OCR nie wymaga żadnych plików licencyjnych, ścieżek SDK ani montowania woluminów.

Czy mogę wypróbować IronOCR przed zakupem, w porównaniu z GdPicture.NET?

Tak. Tryb próbny IronOCR przetwarza dokumenty i zwraca wyniki OCR z nakładką znaku wodnego na wyjściu. Przed zakupem licencji można sprawdzić dokładność na własnych dokumentach.

Czy IronOCR obsługuje odczytywanie kodów kreskowych oprócz wyodrębniania tekstu?

IronOCR koncentruje się na wyodrębnianiu tekstu i OCR. Do odczytu kodów kreskowych firma Iron Software udostępnia bibliotekę IronBarcode jako dodatek. Obie biblioteki są dostępne osobno lub w ramach pakietu Iron Suite.

Czy łatwo jest przejść z GdPicture.NET OCR na IronOCR?

Migracja z GdPicture.NET OCR do IronOCR zazwyczaj polega na zastąpieniu sekwencji inicjalizacyjnych instancjonowaniem IronTesseract, usunięciu zarządzania cyklem życia COM oraz aktualizacji wywołań API. Większość migracji znacznie zmniejsza złożoność kodu.

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