IRONSOFTWAREHOME
FILMY

Jak wyodrębnić tekst arabski z obrazów za pomocą narzędzi OCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 28 czerwca 2026

Ten przewodnik przeprowadza programistów .NET przez proces pełnej migracji z GdPicture.NET OCR do IronOCR. Obejmuje to zamianę pakietów, zmiany przestrzeni nazw oraz praktyczne wzorce kodu "przed i po" dla każdego głównego przepływu pracy OCR, ze szczególnym naciskiem na wyeliminowanie cyklu życia identyfikatorów obrazów typu integer, który definiuje model zarządzania zasobami GdPicture. Nie jest wymagana wcześniejsza lektura artykułu porównawczego.

Dlaczego warto przejść z GdPicture.NET

GdPicture.NET to platforma do przetwarzania obrazów dokumentów stworzona dla zespołów, które potrzebują integracji skanera, obsługi DICOM, edycji plików PDF, dodawania adnotacji i OCR od jednego dostawcy. Gdy jedynym wymaganiem jest OCR, cennik platformy i architektura API powodują tarcia, które z czasem się kumulują.

Koszt wtyczki dla podstawowego przepływu pracy OCR. Wyodrębnianie tekstu ze skanowanych plików PDF i tworzenie wyników z możliwością wyszukiwania wymaga trzech oddzielnych komponentów licencyjnych: Core SDK za około 4000 USD, wtyczki OCR za około 2000 USD oraz wtyczki PDF za około 2000 USD. Oznacza to koszt początkowy w wysokości 8000 USD plus 20% rocznej opłaty za utrzymanie. Zespoły, które potrzebują wyłącznie funkcji OCR, ponoszą pełne koszty związane z platformą do przetwarzania obrazów dokumentów.IronOCR obejmuje ten sam proces — OCR obrazu, OCR PDF, wstępne przetwarzanie, generowanie przeszukiwalnego PDF — z pojedynczego pakietu od $999 do $2,399 za licencję wieczystą, bez decyzji licencyjnych na funkcje. Pełny podział planów taryfowych można znaleźć na stronie licencyjnej IronOCR.

Cykl życia identyfikatora obrazu Integer. Każdy obraz załadowany przez GdPicture zwraca int. Przekazujesz tę wartość całkowitą do operacji OCR, a następnie wywołujesz ReleaseGdPictureImage, gdy skończysz. Ten wzorzec istnieje przed IDisposable. Działa, jeśli jest stosowana prawidłowo; gdy zostanie pominięte, powoduje wyciek pamięci. W usługach produkcyjnych przetwarzających setki dokumentów dziennie jedno przeoczone wywołanie wydania w gałęzi błędów powoduje wzrost zużycia pamięci, który jest naprawdę trudny do zdiagnozowania. OcrInput z IronOCR implementuje IDisposable — instrukcja using eliminuje cały ciężar czyszczenia.

Przestrzeń nazw specyficzna dla wersji. GdPicture osadza główny numer wersji w swojej przestrzeni nazw: using GdPicture14. Aktualizacja do następnego wydania głównej wersji wymaga aktualizacji tej dyrektywy using w każdym pliku źródłowym, który odnosi się do klas GdPicture. Duża aplikacja z OCR rozłożona na dziesiątki usług sprawia, że jest to wielogodzinne zadanie typu "znajdź i zamień", które nie zapewnia żadnej poprawy funkcjonalności. Przestrzeń nazw w IronOCR jest IronOcr we wszystkich głównych wersjach.

Wymaganie na folder zasobów zewnętrznych. GdPicture OCR wymaga właściwości ResourceFolder, która wskazuje na katalog plików językowych .traineddata w czasie wykonywania. Ta ścieżka działa na maszynie deweloperskiej, a następnie ulega awarii na serwerach Linux, kontenerach Docker i wdrożeniach Azure App Service, gdzie struktura katalogów nie istnieje.IronOCR zawiera wsparcie języka angielskiego wewnątrz pakietu NuGet; Dodatkowe języki instaluje się jako pakiety NuGet, które są dołączane do wyników kompilacji.

Inicjalizacja w trzech komponentach. Proces OCR PDF w GdPicture wymaga instancjonowania GdPictureImaging, GdPictureOCR oraz GdPicturePDF — trzech oddzielnych komponentów z indywidualnymi wymaganiami likwidacyjnymi — plus rejestracja menedżera licencji i przypisanie folderu zasobów.IronOCR wymaga jednej linii kodu podczas uruchamiania i jednej klasy w momencie wywołania.

Brak natywnej bezpieczeństwa wątków. Instancje GdPicture OCR nie są bezpieczne dla wątków. Równoległe przetwarzanie dokumentów wymaga starannego zarządzania instancjami i synchronizacji, aby uniknąć uszkodzenia stanu.IronOCR jest zaprojektowany do równoczesnego użycia: utwórz jeden IronTesseract na wątek, lub współdziel jedną instancję pod obciążeniem — każdy z tych wzorców działa bez dodatkowego kodu synchronizacyjnego.

Podstawowy problem

GdPicture przydziela pamięć dla każdego obrazu jako uchwyt całkowitoliczbowy zarządzany w czasie wykonywania. Każde wywołanie RenderPageToGdPictureImage w pętli przetwarzania TIFF tworzy nową alokację, która musi być uwolniona ręcznie:

// GdPicture: every frame = new integer ID = manual release required
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("multi-page.tiff", false);

var frameIds = new List<int>();
try
{
    for (int i = 1; i <= pdf.GetPageCount(); i++)
    {
        pdf.SelectPage(i);
        int frameId = pdf.RenderPageToGdPictureImage(200, false); // new allocation
        if (frameId != 0) frameIds.Add(frameId);
        // ... OCR call here ...
    }
}
finally
{
    foreach (var id in frameIds) _imaging.ReleaseGdPictureImage(id); // manual per-frame release
}
C#

IronOCR całkowicie eliminuje ten cykl. OcrInput obsługuje enumerację ramek i czyszczenie:

// IronOCR: the using statement handles everything
using var input = new OcrInput();
input.LoadImageFrames("multi-page.tiff");
var result = new IronTesseract().Read(input);
C#

##IronOCR a GdPicture.NET: porównanie funkcji

Poniższa tabela przedstawia zestawienie funkcji obu bibliotek w kontekście procesów opartych na OCR.

FunkcjaGdPicture.NETIronOCR
InstalacjaWiele pakietów NuGetdotnet add package IronOcr
Aktywacja licencjiLicenseManager.RegisterKEY()IronOcr.License.LicenseKey = "..."
Przestrzeń nazw w ramach dużej aktualizacjiWymaga znajdź-zastąp (GdPicture14 → następny)Niezmieniony (IronOcr)
Inicjalizacja komponentówGdPictureImaging + GdPictureOCR + GdPicturePDFnew IronTesseract()
Model pamięci zasobówRęczne śledzenie identyfikatorów całkowitoliczbowych i wydanieIDisposable / using instrukcja
Ryzyko wycieku pamięciWysoki (brakujący ReleaseGdPictureImage)Brak (wymuszony przez kompilator przy using)
Folder zasobów zewnętrznychWymagany (_ocr.ResourceFolder = path)Nie jest wymagane — zawarte w pakiecie
OCR obrazówTakTak
OCR PDFTak (wymagana wtyczka PDF)Wbudowane, bez dodatkowej licencji
Wielostronicowy plik TIFFRęczna pętla klatek + czyszczenie identyfikatorów poszczególnych klatekinput.LoadImageFrames()
Dane wejściowe strumieniaPrzez przeciążenie strumienia GdPictureImaginginput.LoadImage(stream)
Wynik w formacie PDF z możliwością wyszukiwaniapdf.OcrPage() + pdf.SaveToFile()result.SaveAsSearchablePdf()
Przetwarzanie wstępne w celu wyeliminowania przekrzywieniaWymagana wtyczka do przetwarzania obrazów dokumentówinput.Deskew() — wbudowany
Usuwanie szumówWymagana wtyczka do przetwarzania obrazów dokumentówinput.DeNoise() — wbudowany
JęzykiPliki traineddata oparte na Tesseract w folderzePonad 125 pakietów dostępnych za pośrednictwem NuGet
Wielojęzyczne OCRTakOcrLanguage.French + OcrLanguage.German
Bezpieczeństwo wątkówRęczne zarządzanie instancjamiZabezpieczone przed współbieżnością już w fazie projektowania
Asynchroniczne OCRNie wbudowaneReadAsync()
Odczytywanie BarCodeOddzielna wtyczka do BarCodeocr.Configuration.ReadBarCodes = true
Strukturalny wynikDostęp do bloków/wierszy/słów oparty na indeksieTypowany .Pages, .Words, .Characters
Ocena pewnościGetOCRResultConfidence(resultId)result.Confidence
WielopłatformoweWindows, Linux, macOSWindows, Linux, macOS, Docker, AWS, Azure
Koszt wprowadzenia (OCR z plików PDF)~8 000 USD (pakiet podstawowy + OCR + wtyczki PDF)$999–$2,399
Model cenowyWersja wieczysta oparta na wtyczkach + 20% rocznie za utrzymanieStała licencja bezterminowa, opcjonalne aktualizacje roczne
Wsparcie komercyjneTakTak

Szybki start: Migracja z GdPicture.NET do IronOCR

Krok 1: Zastąp pakiet NuGet

Usuń pakiety GdPicture:

dotnet remove package GdPicture.NET
dotnet remove package GdPicture.NET.OCR
dotnet remove package GdPicture.NET.PDF
SHELL

Zainstaluj IronOCR ze strony pakietu NuGet:

dotnet add package IronOcr

W przypadku języków innych niż angielski należy zainstalować odpowiedni pakiet językowy:

dotnet add package IronOcr.Languages.French, IronOcr.Languages.German

Krok 2: Aktualizacja przestrzeni nazw

Zastąp przestrzeń nazw GdPicture przestrzenią nazw IronOCR:

// Before (GdPicture)
using GdPicture14;

// After (IronOCR)
using IronOcr;
C#

Krok 3: Inicjalizacja licencji

Umieść tę linię w Program.cs lub Startup.cs, przed jakimikolwiek wywołaniami OCR:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

Całkowicie usuń blok rejestracji licencji GdPicture:

// Remove this
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
C#

Na stronie produktu IronOCR dostępny jest bezpłatny klucz próbny, który pozwala przetestować oprogramowanie przed zakupem.

Przykłady migracji kodu

Przetwarzanie wielostronicowych ramek TIFF

Przetwarzanie wielostronicowych plików TIFF w GdPicture wymaga wybrania każdej klatki za pomocą interfejsu API PDF/obrazówania, renderowania jej do nowego identyfikatora obrazu, uruchomienia OCR i zwolnienia identyfikatora. Pojedyncza ramka, która nie jest uwolniona w bloku finally, wycieka 10-50 MB w zależności od DPI.

Podejście GdPicture.NET:

using GdPicture14;

public class GdPictureTiffProcessor
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;

    public string ExtractTextFromTiff(string tiffPath)
    {
        var text = new StringBuilder();

        // Load TIFF through the imaging component
        int tiffId = _imaging.CreateGdPictureImageFromFile(tiffPath);

        if (tiffId == 0)
            throw new Exception($"TIFF load failed: {_imaging.GetStat()}");

        // Outer try: release the original TIFF handle
        try
        {
            int frameCount = _imaging.GetPageCount(tiffId);

            for (int i = 1; i <= frameCount; i++)
            {
                // Switch to frame — modifies the existing ID in place
                _imaging.SelectPage(tiffId, i);

                // Clone frame to a new image ID for OCR
                int frameId = _imaging.CloneImage(tiffId);

                if (frameId == 0) continue;

                // Inner try: release each cloned frame ID
                try
                {
                    _ocr.SetImage(frameId);
                    _ocr.Language = "eng";

                    string resultId = _ocr.RunOCR();

                    if (!string.IsNullOrEmpty(resultId))
                    {
                        text.AppendLine($"[Frame {i}] {_ocr.GetOCRResultText(resultId)}");
                    }
                }
                finally
                {
                    // Release cloned frame — critical for each iteration
                    _imaging.ReleaseGdPictureImage(frameId);
                }
            }
        }
        finally
        {
            // Release original TIFF handle
            _imaging.ReleaseGdPictureImage(tiffId);
        }

        return text.ToString();
    }
}
C#

Podejście IronOCR:

using IronOcr;

public class IronOcrTiffProcessor
{
    public string ExtractTextFromTiff(string tiffPath)
    {
        using var input = new OcrInput();
        input.LoadImageFrames(tiffPath);  // all frames loaded, all cleanup automatic

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

        // Per-frame text is available on result.Pages
        foreach (var page in result.Pages)
            Console.WriteLine($"[Frame {page.PageNumber}] {page.Text}");

        return result.Text;
    }
}
C#

LoadImageFrames ładuje każdą ramkę z wielostronicowego TIFF do potoku OcrInput. Blok using obsługuje całą pamięć związaną z każdą ramką na końcu zakresu. Brak List<int> do utrzymania, brak zagnieżdżonych bloków try/finally wymaganych. Przewodnik dotyczący plików wejściowych TIFF i GIF szczegółowo omawia wybór klatek i obsługę wielu formatów.

Wejście oparte na strumieniu zastępujące inicjalizację wtyczki

Aplikacje serwerowe często odbierają dokumenty w postaci strumieni, a nie ścieżek do plików — z przesyłania HTTP, kolejek komunikatów lub obiektów blob w bazach danych. GdPicture wymaga ładowania strumienia przez GdPictureImaging, co samo w sobie wymaga sekwencji inicjalizacji komponentu i konfiguracji folderu zasobów, które poprzedzają każdą operację.

Podejście GdPicture.NET:

using GdPicture14;

public class GdPictureStreamOcr : IDisposable
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;

    public GdPictureStreamOcr()
    {
        // Plugin initialization required before stream loading is possible
        var lm = new LicenseManager();
        lm.RegisterKEY("GDPICTURE-LICENSE-KEY");

        _imaging = new GdPictureImaging();
        _ocr = new GdPictureOCR();
        _ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR"; // path must exist at runtime
    }

    public string ExtractTextFromStream(Stream documentStream)
    {
        // Load stream into imaging component to get an image ID
        int imageId = _imaging.CreateGdPictureImageFromStream(documentStream);

        if (imageId == 0)
            throw new Exception($"Stream load failed: {_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
        {
            _imaging.ReleaseGdPictureImage(imageId);
        }
    }

    public void Dispose()
    {
        _ocr?.Dispose();
        _imaging?.Dispose();
    }
}
C#

Podejście IronOCR:

using IronOcr;

public class IronOcrStreamOcr
{
    public string ExtractTextFromStream(Stream documentStream)
    {
        using var input = new OcrInput();
        input.LoadImage(documentStream);  // stream accepted directly — no imaging component

        return new IronTesseract().Read(input).Text;
    }
}
C#

Podejście GdPicture wymaga utworzenia trzech obiektów i skonfigurowania ścieżki systemu plików, zanim będzie można wykorzystać pierwszy strumień.IronOCR akceptuje strumień bezpośrednio na OcrInput bez wcześniejszego przygotowania. Przewodnik po wejściu strumieniowym obejmuje tablice bajtów, MemoryStream i wzorce FileStream dla architektur przepływu, gdzie zapisywanie plików tymczasowych jest niepożądane.

Asynchroniczne OCR zastępujące odpytywanie kodów statusu

GdPicture OCR działa synchronicznie. Aplikacje przetwarzające dokumenty w punktach końcowych ASP.NET Core lub usługach w tle muszą opakować RunOCR w Task.Run, aby uniknąć blokowania wątków żądań — a następnie zarządzać cyklem życia identyfikatora obrazu przez granicę wątku.IronOCR zapewnia wsparcie dla asynchronicznego działania na najwyższym poziomie przez ReadAsync.

Podejście GdPicture.NET:

using GdPicture14;
using System.Threading.Tasks;

public class GdPictureAsyncWrapper
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;
    private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

    public async Task<string> ExtractTextAsync(string imagePath)
    {
        // Must acquire lock: GdPictureOCR is not thread-safe
        await _lock.WaitAsync();

        try
        {
            return await Task.Run(() =>
            {
                int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);

                if (imageId == 0)
                    throw new Exception($"Load failed: {_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
                {
                    _imaging.ReleaseGdPictureImage(imageId);
                }
            });
        }
        finally
        {
            _lock.Release();
        }
    }
}
C#

Podejście IronOCR:

using IronOcr;

public class IronOcrAsyncService
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public async Task<string> ExtractTextAsync(string imagePath)
    {
        // ReadAsync is natively async — no Task.Run wrapper, no lock required
        var result = await _ocr.ReadAsync(imagePath);
        return result.Text;
    }

    public async Task<string> ExtractFromStreamAsync(Stream stream)
    {
        using var input = new OcrInput();
        input.LoadImage(stream);

        var result = await _ocr.ReadAsync(input);
        return result.Text;
    }
}
C#

Podejście GdPicture wymaga SemaphoreSlim do serializacji dostępu do współdzielonej instancji GdPictureOCR, plus Task.Run do przenoszenia pracy blokującej synchronicznie z wątku wywołującego, plus pełen cykl życia identyfikatora obrazu wewnątrz tej lamda. ReadAsync z IronOCR jest naprawdę nieblokujący i bezpieczny w obsłudze wielowątkowej. Przewodnik po asynchronicznym OCR obejmuje integrację z oprogramowaniem pośredniczącym .NET Core oraz hostowanymi usługami działającymi w tle.

Równoległe przetwarzanie wsadowe z bezpieczeństwem wątków

Aby jak najszybciej przetworzyć folder ze skanami dokumentów, konieczne jest równoległe wykonywanie zadań. GdPicture wymaga jednej instancji GdPictureOCR na wątek — współdzielenie jednej instancji powoduje niedeterministyczne awarie. Każda instancja przypadająca na wątek wymaga również własnego komponentu GdPictureImaging i konfiguracji folderu zasobów, co czyni podejścia oparte na pulach wątków niepraktycznymi bez wzorca fabryki.

Podejście GdPicture.NET:

using GdPicture14;
using System.Collections.Concurrent;
using System.Threading.Tasks;

public class GdPictureParallelBatch
{
    private readonly string _resourceFolder = @"C:\GdPicture\Resources\OCR";

    public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
    {
        var results = new ConcurrentDictionary<string, string>();

        // Each thread must have its own component instances
        Parallel.ForEach(imagePaths, imagePath =>
        {
            // Create per-thread instances — shared instances cause failures
            using var threadImaging = new GdPictureImaging();
            using var threadOcr = new GdPictureOCR();
            threadOcr.ResourceFolder = _resourceFolder;

            // Re-register license per thread (may be required depending on SDK version)
            var lm = new LicenseManager();
            lm.RegisterKEY("GDPICTURE-LICENSE-KEY");

            int imageId = threadImaging.CreateGdPictureImageFromFile(imagePath);

            if (imageId == 0)
            {
                results[imagePath] = $"ERROR: {threadImaging.GetStat()}";
                return;
            }

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

                string resultId = threadOcr.RunOCR();
                results[imagePath] = string.IsNullOrEmpty(resultId)
                    ? $"ERROR: {threadOcr.GetStat()}"
                    : threadOcr.GetOCRResultText(resultId);
            }
            finally
            {
                threadImaging.ReleaseGdPictureImage(imageId);
            }
        });

        return results;
    }
}
C#

Podejście IronOCR:

using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;

public class IronOcrParallelBatch
{
    public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
    {
        var results = new ConcurrentDictionary<string, string>();

        // IronTesseract is thread-safe — one instance handles all threads
        var ocr = new IronTesseract();

        Parallel.ForEach(imagePaths, imagePath =>
        {
            try
            {
                results[imagePath] = ocr.Read(imagePath).Text;
            }
            catch (Exception ex)
            {
                results[imagePath] = $"ERROR: {ex.Message}";
            }
        });

        return results;
    }
}
C#

Równoległa implementacja GdPicture tworzy trzy obiekty na wątek i wymaga rejestracji licencji dla każdego wątku.IronOCR obsługuje równoczesne odczyty z jednej instancji IronTesseract bez obciążenia synchronizacyjnego. Przykład wielowątkowości demonstruje testy wydajności i wzorce Parallel.ForEach dla zadań przetwarzania dużych ilości dokumentów.

Wejście tablicy bajtów i ekstrakcja ustrukturyzowanych akapitów

Aplikacje pobierające dokumenty z baz danych lub magazynów obiektów często pracują z tablicami bajtów, a nie ścieżkami do plików. GdPicture wymaga konwersji tablicy bajtów na strumień i ładowania jej przez GdPictureImaging. Wyodrębnienie ustrukturyzowanych danych na poziomie akapitu z wyniku wymaga poruszania się po hierarchii indeksu bloków/wierszy.

Podejście GdPicture.NET:

using GdPicture14;

public class GdPictureByteArrayOcr
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;

    public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
    {
        var paragraphs = new List<string>();

        // Byte array must go through MemoryStream to reach CreateGdPictureImageFromStream
        using var ms = new MemoryStream(imageBytes);
        int imageId = _imaging.CreateGdPictureImageFromStream(ms);

        if (imageId == 0)
            throw new Exception($"Byte array load failed: {_imaging.GetStat()}");

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

            string resultId = _ocr.RunOCR();

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

            // Paragraph-level data requires iterating block structure
            int blockCount = _ocr.GetOCRResultBlockCount(resultId);

            for (int b = 0; b < blockCount; b++)
            {
                var blockText = new StringBuilder();
                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++)
                    {
                        blockText.Append(_ocr.GetOCRResultBlockLineWordText(resultId, b, l, w));
                        blockText.Append(" ");
                    }
                }

                string text = blockText.ToString().Trim();
                if (!string.IsNullOrEmpty(text))
                    paragraphs.Add(text);
            }
        }
        finally
        {
            _imaging.ReleaseGdPictureImage(imageId);
        }

        return paragraphs;
    }
}
C#

Podejście IronOCR:

using IronOcr;

public class IronOcrByteArrayOcr
{
    public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
    {
        using var input = new OcrInput();
        input.LoadImage(imageBytes);  // byte array accepted directly

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

        // Paragraphs are a first-class typed collection
        return result.Paragraphs
            .Select(p => p.Text)
            .Where(t => !string.IsNullOrWhiteSpace(t))
            .ToList();
    }
}
C#

IronOCR akceptuje byte[] bezpośrednio na LoadImage bez pośredniego MemoryStream. Wynik udostępnia .Paragraphs jako typowaną kolekcję zapytawliną LINQ — nie są wymagane potrójne pętle blok-linia-słowo. Przewodnik po wynikach odczytu obejmuje dostęp do współrzędnych, filtrowanie poziomu pewności oraz wzorce wyników strukturalnych dla procesów przetwarzania faktur i formularzy. W celu skanowania określonych obszarów dokumentu zobacz OCR oparte na regionach.

Dokumentacja API GdPicture.NET do IronOCR

GdPicture.NETOdpowiednik IronOCR
using GdPicture14;using IronOcr;
LicenseManager.RegisterKEY("key")IronOcr.License.LicenseKey = "key"
new GdPictureImaging()Nie jest wymagane — wewnętrzne dla OcrInput
new GdPictureOCR()new IronTesseract()
new GdPicturePDF()Nie jest wymagane — OcrInput.LoadPdf() obsługuje to
_ocr.ResourceFolder = pathNie jest wymagane — zasoby dołączone w pakiecie NuGet
imaging.CreateGdPictureImageFromFile(path)input.LoadImage(path)
imaging.CreateGdPictureImageFromStream(stream)input.LoadImage(stream)
imaging.CreateGdPictureImageFromBytes(bytes)input.LoadImage(bytes)
imaging.CloneImage(tiffId) na ramkęinput.LoadImageFrames(tiffPath)
imaging.ReleaseGdPictureImage(imageId)using var input = new OcrInput() — automatyczne
ocr.SetImage(imageId)Nie jest wymagane — OcrInput utrzymuje obraz
ocr.Language = "eng"ocr.Language = OcrLanguage.English
ocr.RunOCR() → łańcuch resultIdocr.Read(input) → typowany OcrResult
ocr.GetOCRResultText(resultId)result.Text
ocr.GetOCRResultConfidence(resultId)result.Confidence
ocr.GetOCRResultBlockCount(resultId)result.Pages[i].Paragraphs.Count
ocr.GetOCRResultBlockLineWordText(resultId, b, l, w)result.Words[i].Text
imaging.GetStat() / ocr.GetStat()Standardowe wyjątki .NET Standard
GdPictureStatus.OK sprawdź po każdym wywołaniuNie jest wymagane — wyjątki są propagowane
pdf.OcrPage("eng", resourcePath, "", 200)result.SaveAsSearchablePdf(outputPath)
pdf.RenderPageToGdPictureImage(200, false)Nie jest wymagane —IronOCR renderuje wewnętrznie
pdf.SelectPage(i)Nie jest wymagane — wszystkie strony przetwarzane domyślnie
pdf.GetPageCount()result.Pages.Count
Task.Run(() => ocr.RunOCR()) + SemaphoreSlimawait ocr.ReadAsync(input)

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

Problem 1: Zmienne identyfikujące obrazy pozostałe w kodzie po refaktoryzacji

GdPicture.NET: Istniejący kod ogłasza int imageId na początku metod, śledzi go przez try/finally i przekazuje do wielu wywołań GdPicture. Po zastąpieniu wywołań GdPicture, te zmienne i ich wywołania ReleaseGdPictureImage stają się osieroconym martwym kodem.

Rozwiązanie: Usuń cały wzorzec identyfikatora obrazu. Zastąp deklarację, try, finally i wywołanie uwolnienia blokiem using var input = new OcrInput(). Szukaj ReleaseGdPictureImage, aby znaleźć każde wywołanie czyszczenia, które musi zostać usunięte:

grep -rn "ReleaseGdPictureImage\|imageId\|resultId" --include="*.cs" .
SHELL
// Remove all of this
int imageId = _imaging.CreateGdPictureImageFromFile(path);
try
{
    _ocr.SetImage(imageId);
    string resultId = _ocr.RunOCR();
    return _ocr.GetOCRResultText(resultId);
}
finally
{
    _imaging.ReleaseGdPictureImage(imageId);
}

// Replace with
using var input = new OcrInput();
input.LoadImage(path);
return new IronTesseract().Read(input).Text;
C#

Problem 2: Nie znaleziono ścieżki do folderu zasobów w środowisku wdrożeniowym

GdPicture.NET: Ścieżka ustawiona w _ocr.ResourceFolder rozwiązuje się na maszynie deweloperskiej ale zawodzi w produkcji. Typowymi objawami są ciche niepowodzenia OCR zwracające puste wyniki lub ogólne błędy GdPictureStatus, które nie wskazują brakującego pliku.

Rozwiązanie: Całkowicie usuń przypisanie ResourceFolder. Obsługa języka angielskiego jest wbudowana w pakiet IronOCR NuGet. Dodatkowe języki instaluje się jako pakiety NuGet. Nie ma ścieżki systemu plików do skonfigurowania ani wdrożenia:

dotnet add package IronOcr.Languages.French, IronOcr.Languages.German

Problem 3: Obsługa błędów GdPictureStatus zastąpiona przez wyjątki

GdPicture.NET: Każda operacja zwraca lub ustawia wartość enum GdPictureStatus, którą trzeba natychmiast sprawdzić. Kod jest zagęszczony ochronami if (status != GdPictureStatus.OK). Niektóre kody statusu są ogólne (np. Error, InvalidParameter) i wymagają konsultacji z dokumentacją w celu ustalenia pierwotnej przyczyny.

**Rozwiązanie:**IronOCR generuje typowe wyjątki .NET. Zastąp sprawdzanie statusu blokami try/catch. Standardowe IOException i FileNotFoundException obejmują niepowodzenia wejściowe; IronOcr.Exceptions.OcrException obejmuje błędy specyficzne dla OCR. Zobacz przewodnik konfiguracji IronTesseract, aby zapoznać się z zalecanymi wzorcami obsługi błędów:

try
{
    var result = new IronTesseract().Read(imagePath);
    return result.Text;
}
catch (FileNotFoundException ex)
{
    _logger.LogError("Input file missing: {Path}", ex.FileName);
    throw;
}
catch (IronOcr.Exceptions.OcrException ex)
{
    _logger.LogError("OCR processing failed: {Message}", ex.Message);
    throw;
}
C#

Problem 4: Przestrzeń nazw GdPicture14 w wielu plikach

GdPicture.NET: Numer wersji w przestrzeni nazw oznacza, że projektowa dyrektywa using GdPicture14; istnieje w dziesiątkach plików. Po migracji wszystkie te muszą być zastąpione przez using IronOcr;.

Rozwiązanie: Użyj globalnej funkcji znajdź-i-zastąp w całych plikach .cs, a następnie zweryfikuj, że żadne odniesienia do GdPicture nie pozostają:

# Find all files with GdPicture namespace
grep -rln "using GdPicture" --include="*.cs" .

# After replacing, verify nothing remains
grep -rn "GdPicture14\|GdPictureOCR\|GdPictureImaging\|GdPicturePDF" --include="*.cs" .
SHELL

Problem 5: Logika liczenia klatek TIFF

GdPicture.NET: Kod iterujący ramki TIFF często miesza wywołania pomiędzy GdPictureImaging.GetPageCount(imageId) a GdPicturePDF.GetPageCount() w zależności od tego, jak plik został załadowany. Indeks ramki zaczyna się od 1.

Rozwiązanie: input.LoadImageFrames(path) obsługuje wszystkie ramki automatycznie. Jeśli Twój istniejący kod przetwarza tylko konkretne ramki, użyj input.LoadImageFrames(path, frameNumbers) z tablicą indeksów opartą na zerze. Dostęp do wyników dla poszczególnych ramek poprzez result.Pages, które również są indeksowane od zera. W instrukcji dotyczącej plików wejściowych TIFF wyraźnie opisano zachowanie indeksu.

Problem 6: Przetwarzanie wstępne wymaga wtyczki do obrazówania dokumentów

GdPicture.NET: Operacje deskew i despeckle należą do wtyczki GdPictureDocumentImaging, która wymaga oddzielnego zakupu licencji. Zespoły, które pominęły tę wtyczkę, często borykają się z problemami z dokładnością OCR w przypadku zeskanowanych dokumentów o przekrzywionych lub zaszumionych stronach.

Rozwiązanie: Metody przetwarzania wstępnego IronOCRsą częścią pakietu podstawowego. Dodaj Deskew() i DeNoise() bezpośrednio na OcrInput. Przewodnik po korekcji jakości obrazu obejmuje wszystkie dostępne filtry, w tym Contrast(), Sharpen(), Binarize(), i DeepCleanBackgroundNoise() dla skanów o poważnie zniszczonej jakości:

using var input = new OcrInput();
input.LoadImage("scanned-document.tiff");
input.Deskew();        // no separate plugin license
input.DeNoise();
input.Contrast();

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

Lista kontrolna migracji GdPicture.NET

Przed migracją

Przed wprowadzeniem zmian należy przeprowadzić audyt kodu źródłowego w celu zlokalizowania wszystkich zależności GdPicture:

# Find all GdPicture namespace imports
grep -rn "using GdPicture" --include="*.cs" .

# Find all image ID creation points
grep -rn "CreateGdPictureImageFromFile\|CreateGdPictureImageFromStream\|RenderPageToGdPictureImage\|CloneImage" --include="*.cs" .

# Find all release calls — these map to using block boundaries
grep -rn "ReleaseGdPictureImage" --include="*.cs" .

# Find all resource folder assignments
grep -rn "ResourceFolder" --include="*.cs" .

# Find all OCR result ID accesses
grep -rn "RunOCR\|GetOCRResult\|resultId" --include="*.cs" .

# Find all GdPictureStatus checks
grep -rn "GdPictureStatus\|GetStat()" --include="*.cs" .

# Count GdPicture-dependent files
grep -rln "GdPicture14" --include="*.cs" . | wc -l
SHELL

Przed modyfikacją kodu należy udokumentować następujące elementy:

  • Które pliki zawierają odniesienia do GdPictureImaging, GdPictureOCR, i GdPicturePDF
  • Ile istnieje różnych par tworzenia/wydania identyfikatorów obrazów
  • Czy używana jest wtyczka do przetwarzania obrazów dokumentów (korekcja krzywizny, usuwanie plam)
  • W jakim języku pliki traineddata znajdują się w folderze zasobów
  • Które skrypty wdrożeniowe lub pliki Docker odwołują się do ścieżki folderu zasobów

Migracja kodu

  1. Usuń wszystkie pakiety GdPicture NuGet z pliku projektu
  2. Zainstaluj IronOcr przez NuGet
  3. Zainstaluj pakiety IronOcr.Languages.* dla każdego języka wcześniej w folderze zasobów
  4. Dodaj IronOcr.License.LicenseKey = "..." do Program.cs lub Startup.cs
  5. Usuń wywołanie LicenseManager.RegisterKEY() oraz obiekt menedżera licencji
  6. Usuń wszystkie deklaracje pól GdPictureImaging i inicjalizację konstruktora
  7. Usuń wszystkie deklaracje pól GdPictureOCR oraz przypisanie ResourceFolder
  8. Usuń wszystkie deklaracje pól GdPicturePDF używane do zadań OCR
  9. Zastąp każdy blok int imageId = _imaging.CreateGdPictureImage*(...) poprzez using var input = new OcrInput(); input.Load*(...)
  10. Zastąp każde _ocr.SetImage(imageId); _ocr.Language = "..."; string resultId = _ocr.RunOCR(); with var result = new IronTesseract().Read(input);
  11. Zamień _ocr.GetOCRResultText(resultId) na result.Text
  12. Usuń wszystkie wywołania _imaging.ReleaseGdPictureImage(imageId)
  13. Zamień sprawdzenia GdPictureStatus na bloki try/catch
  14. Zamień pętle ramki TIFF na input.LoadImageFrames(path)
  15. Zamień pdf.OcrPage(...) + pdf.SaveToFile(...) na result.SaveAsSearchablePdf(outputPath)
  16. Usuń ścieżkę do folderu zasobów ze skryptów wdrażania i obrazów Docker
  17. Zaktualizuj using GdPicture14; do using IronOcr; we wszystkich dotkniętych plikach

Po migracji

Po wprowadzeniu wszystkich zmian w kodzie, przed wdrożeniem do środowiska produkcyjnego sprawdź, czy:

  • Jedno OCR obrazu zwraca oczekiwany tekst bez NullReferenceException z usuniętych komponentów
  • Przetwarzanie wielu stron TIFF obejmuje wszystkie ramki i generuje tekst dla każdej strony przez result.Pages
  • OCR plików PDF przetwarza wszystkie strony bez zwiększania zużycia pamięci w partii ponad 50 dokumentów
  • Wejście strumienia akceptuje MemoryStream i FileStream bez pośrednich zapisów plików
  • Async OCR integruje się z modułami obsługi żądań ASP.NET Core bez blokowania puli wątków
  • Równoległe przetwarzanie wsadowe z Parallel.ForEach generuje dokładne wyniki we wszystkich wątkach
  • Wszystkie pakiety językowe (francuski, niemiećki itp.) aktywują się poprawnie poprzez pakiety NuGet
  • Filtry przetwarzania wstępnego (prostowanie, usuwanie szumów) poprawiają dokładność skanowanych dokumentów
  • Wygenerowany plik PDF z możliwością wyszukiwania jest odczytywany przez przeglądarki PDF i aplikacje do wyszukiwania tekstu
  • Żadne odniesienia do przestrzeni nazw GdPicture nie pozostają w żadnym pliku .cs po migracji
  • Profil pamięci wykazuje stabilne zużycie przy długotrwałym obciążeniu (brak wycieków alokacji obrazów)
  • Wdrożenie przebiega pomyślnie na systemach Linux i Docker bez błędów ścieżki systemu plików

Kluczowe korzyści z migracji do IronOCR

Bezpieczeństwo pamięci wymuszane przez kompilator. Cykl życia identyfikatorów obrazów, który GdPicture wymaga od programistów ręcznego utrzymywania, całkowicie znika. OcrInput implementuje IDisposable, a bloki using wymuszają czyszczenie na końcu każdego zakresu — łącznie ze ścieżkami wyjątków. Brak List<int> do utrzymania, brak bloków finally do zapamiętania, brak incydentów pamięci produkcyjnej z powodu pominiętych wywołań uwolnienia.

Pojedynczy pakiet dla każdego scenariusza OCR. Image OCR, PDF OCR, przetwarzanie wielostronicowych TIFF, generowanie przeszukiwalnych PDF, filtry wstępnego przetwarzania, odczyt kodów kreskowych, i ponad 125 pakietów językowych są wszystkie dostępne z pakietu NuGet IronOcr i jego towarzyszy językowych. Nie ma żadnych ograniczeń, które wymagałyby zakupu drugiej lub trzeciej licencji, zanim możliwe będzie korzystanie ze standardowego przepływu pracy. Pełną listę funkcji można znaleźć w przeglądzie funkcji IronOCR.

Natywna asynchronizacja i bezpieczeństwo wątkowe. ReadAsync jest prawdziwą metodą asynchroniczną, nie osłoną Task.Run. IronTesseract może być używany bezpiecznie na wszystkich wątkach bez synchronizacji. Usługi przetwarzania dokumentów, które wcześniej wymagały inicjalizacji komponentów na wątek i serializacji z semaforem, redukują się do pojedynczej współdzielonej instancji z Parallel.ForEach. Przewodnik po asynchronicznym OCR obejmuje zarówno ASP.NET Core, jak i wzorce usług hostowanych.

**Zero konfiguracji wdrożeniowej.**IronOCR nie wymaga żadnych ścieżek w systemie plików, zewnętrznych plików językowych, natywnych plików binarnych ani skryptów wdrożeniowych. Etap przywracania NuGet zapewnia wszystko, czego potrzebuje aplikacja. Obrazy Docker, wdrożenia usługi Azure App Service i serwery Linux działają identycznie jak maszyna programistyczna. Przewodnik po wdrażaniu Docker oraz przewodnik po wdrażaniu Azure przedstawiają konfiguracje gotowe do produkcji.

Stabilna przestrzeń nazw wersji. using IronOcr nie uległ zmianie w głównych wydaniach wersji. Numery wersji NuGet obsługują wersjonowanie poprzez standardowy model zarządzania pakietami. Przyszłe większe aktualizacje nie wymagają przeszukiwania i zamiany importu przestrzeni nazw w całym kodzie źródłowym.

**Przewidywalne licencjonowanie wieczyste.**IronOCR kosztuje $999 (Lite), $1 499 (Plus), $2 999 (Professional) i $5 999 (Unlimited) — jednorazowe zakupy licencji wieczystej obejmujące rok aktualizacji, z opcjonalnym odnowieniem co rok. Wszystkie funkcje są dostępne na każdym poziomie. Nie ma żadnych wtyczek dla poszczególnych funkcji, żadnych kosztów za stronę ani żadnych zobowiązań dotyczących konserwacji po pierwszym roku. Zespoły, które wcześniej poniosły koszty licencji wtyczek GdPicture w wysokości ponad 8 000 USD w ramach procesu opartego wyłącznie na OCR, odzyskują tę różnicę w ciągu pierwszego cyklu licencyjnego. Pełne informacje o cenach są dostępne na stronie licencyjnej IronOCR.

Zwróć uwagę: GdPicture.NET i Tesseract są zarejestrowanymi znakami towarowymi ich właścicieli. Ta strona nie jest związana, popierana ani sponsorowana przez Google, Nutrient ani 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.

Powiązane artykuły

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Your trial license will be sent to your email address

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Otrzymaj swoją Konsultację Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta