IRONSOFTWAREHOME
FILMY

Migracja z Tesseract.NET SDK do IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 sierpnia 2026

Ten przewodnik przeprowadza deweloperów .NET przez konkretną migrację zSDK Tesseract.NET(Tesseract.Net.SDK, przestrzeń nazw Patagames.Ocr) do IronOCR. Skupia się w szczególności na zespołach przenoszących wzorce inicjalizacji z ery .NET Framework, starsze idiomy usuwania obiektów oraz potoki działające wyłącznie synchronicznie do świata, który obecnie działa na .NET 8, kontenerach Linux oraz frameworkach internetowych opartych na asynchroniczności. Jeśli Twoja usługa OCR jest kompilowana przeciwko net472 i zawodzi w momencie, gdy ktoś doda <TargetFramework>net8.0</TargetFramework> do .csproj, ten przewodnik jest dla Ciebie.

Dlaczego warto przejść z Tesseract.NET SDK

Pakiet SDK firmy Patagames zapewniał rzeczywistą wartość, gdy podstawą wdrożenia był .NET Framework 4.5, a jedyną platformą docelową był system Windows Server. Kontekst uległ zmianie. Większość organizacji obecnie konteneryzuje usługi, uruchamia CI na środowiskach Linux oraz standaryzuje się na .NET 6, 8 lub 9.SDK Tesseract.NET/nie może za nimi nadążyć.

Sztywny limit na .NET Framework 4.5. Pakiet celuje w net20 do net45. Nie generuje ani netstandard, ani net6.0. Plik projektu zawierający Tesseract.Net.SDK nie może ustawić <TargetFramework>net8.0</TargetFramework>. Aktualizacja .NET, którą reszta kodu kończy w sprincie, zatrzymuje się na warstwie OCR na czas nieokreślony.

Brak ścieżki kontenera. SDK dostarcza wywołania P/Invoke przeznaczone wyłącznie dla systemu Windows do natywnych plików binarnych systemu Windows. Na jakimkolwiek obrazie bazowym Linux — mcr.microsoft.com/dotnet/aspnet:8.0, ubuntu:22.04, alpine:3.19 — aplikacja wyrzuca DllNotFoundException przed przetworzeniem pojedynczego dokumentu. Kontenery Windows istnieją jako rozwiązanie alternatywne, ale wiążą się z większymi rozmiarami obrazów, oddzielnymi kosztami licencji oraz niekompatybilnością z większością zarządzanych usług Kubernetes, które domyślnie korzystają z pul węzłów Linux.

Synchroniczne tylko API blokuje pipelines ASP.NET Core. Metoda OcrApi.GetTextFromImage() jest synchroniczna. W .NET Core wywoływanie blokujących operacji synchronicznych w wątkach żądań obniża przepustowość pod obciążeniem i stwarza ryzyko wyczerpania puli wątków.IronOCR oferuje ReadAsync() dla integracji nieblokującej. Wzór można znaleźć w przewodniku dotyczącym asynchronicznego OCR.

Tworzenie silnika na żądanie zużywa pamięć. Kod .NET Framework często tworzy jedną instancję OcrApi na każde wywołanie metody lub żądanie, usuwając ją po zakończeniu. Jest to idiomatyczne zarządzanie cyklem życia platformy .NET Framework. Jest to również kosztowne: każda Init() ładuje 40–100 MB danych językowych. Dziesięć równoczesnych żądań ładuje ten sam model językowy dziesięć razy. IronOCR's IronTesseract jest bezpieczny dla wątków — jedna instancja żyje przez cały cykl życia aplikacji i obsługuje wszystkich równoczesnych wywołujących z jednego załadowania modelu językowego.

Stare wzorce usuwania danych zwiększają ryzyko. Prawidłowe użycie SDK wymaga using (var api = OcrApi.Create()) { ... } statement that predates using var deklaracje. Bazy kodowe napisane przed wprowadzeniem C# 8.0 często zawierają try/finally wzorce usuwania lub, w przypadku błędów, brak usuwania. Wzory te kompilują się i działają w środowisku .NET Framework, ale niosą ze sobą dług techniczny, który uniemożliwia nowoczesną refaktoryzację.

Brak async, brak DI, brak nowoczesnego startu. SDK nie ma koncepcji integracji wstrzykiwania zależności, cyklu życia hostowanej usługi ani konfiguracji IOptions<t>. Włączenie go do aplikacji .NET Core wymaga ręcznej rejestracji usługi i starannego unikania instancjonowania na żądanie.IronOCR integruje się płynnie jako usługa singletonowa w standardowym kontenerze DI.

Podstawowy problem

// Tesseract.NET SDK: .NET Framework 4.5 ceiling — will not compile on net8.0
// Every project referencing this package is locked below the upgrade line
using Patagames.Ocr;  // Patagames.Ocr targets net45; no netstandard or net8 assembly

public class OcrService
{
    public string ProcessDocument(string imagePath)
    {
        // Synchronous-only — blocks ASP.NET Core request threads
        // No DI support — must be instantiated manually each time
        using (var api = OcrApi.Create())    // C# 1.0 using statement, 40-100MB load per call
        {
            api.Init(Languages.English);
            return api.GetTextFromImage(imagePath);
        }
        // Project cannot target net6.0, net8.0, or any Linux container base image
    }
}
C#
// IronOCR: same logic, any runtime from net462 to net9.0, any platform
using IronOcr;  // Single NuGet, supports .NET Framework 4.6.2+, .NET 5/6/7/8/9

// Register once as singleton — load language model once, share across all requests
// Call ReadAsync() in ASP.NET Core for non-blocking operation
var ocr = new IronTesseract();
var result = await ocr.ReadAsync("document.jpg");  // Async-first, no thread blocking
Console.WriteLine(result.Text);
C#

##IronOCR a Tesseract.NET SDK: porównanie funkcji

Poniższa tabela przedstawia funkcje bezpośrednio związane z migracją w ramach modernizacji platformy .NET.

FunkcjaSDK Tesseract.NETIronOCR
.NET Framework 2.0–4.5TakNie
.NET Framework 4.6.2–4.8NieTak
.NET Core 2.x / 3.xNieTak
.NET 5NieTak
.NET 6NieTak
.NET 7NieTak
.NET 8NieTak
.NET 9NieTak
Wdrażanie w systemie WindowsTakTak
Wdrożenie w systemie LinuxNieTak
Wdrożenie na systemie macOSNieTak
Kontenery Docker LinuxNieTak
Azure App Service (Linux)NieTak
AWS LambdaNieTak
Async API (ReadAsync)NieTak
Bezpieczna dla wątków pojedyncza instancjaNieTak
Integracja ASP.NET Core DIPodręcznikUsługa singleton
Natywne wprowadzanie plików PDFNieTak
Wbudowane przetwarzanie wstępneNieTak
Wynik w formacie PDF z możliwością wyszukiwaniaNieTak
Dane ustrukturyzowane (słowa, wiersze, akapity)NieTak
Wsparcie komercyjne / SLANie (indywidualny programista)Tak
Cena licencji wieczystej~20–50 USD (jeden programista)Z $999

Szybki start: Migracja zSDK Tesseract.NET/do IronOCR

Krok 1: Zastąp pakiet NuGet

Usuń Tesseract.NET SDK:

dotnet remove package Tesseract.Net.SDK
SHELL

Jeśli biblioteka PdfiumViewer lub podobna biblioteka do renderowania plików PDF została zainstalowana wyłącznie w celu dostarczania stron PDF do SDK, należy ją również usunąć —IronOCR odczytuje pliki PDF natywnie:

dotnet remove package PdfiumViewer
SHELL

Zainstaluj IronOCR z NuGet:

dotnet add package IronOcr

Krok 2: Aktualizacja przestrzeni nazw

// Before (Tesseract.NET SDK)
using Patagames.Ocr;
using Patagames.Ocr.Enums;

// After (IronOCR)
using IronOcr;
C#

Krok 3: Inicjalizacja licencji

Dodaj wywołanie klucza licencyjnego raz przy starcie aplikacji — w Program.cs, Startup.cs lub w konstruktora hosta aplikacji:

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

Dostępna jest bezpłatna licencja próbna do oceny bez znaków wodnych.

Przykłady migracji kodu

Wzorzec uruchamiania .NET Framework w nowoczesnym Builderze do tworzenia hostów

Aplikacje .NET Framework zazwyczaj inicjalizują silnik OCR w statycznym konstruktorze, zdarzeniu Application_Start lub w handlerze Global.asax. Żadne z nich nie występuje w aplikacjach .NET 6+ zbudowanych w oparciu o model generycznego hosta.

Podejście Tesseract.NET SDK:

// Global.asax.cs — .NET Framework MVC application
// OcrApi lifecycle managed manually; no DI container involved
public class MvcApplication : System.Web.HttpApplication
{
    // Static field — one engine for the app lifetime
    // But: NOT thread-safe; concurrent requests share a single OcrApi instance
    private static OcrApi _globalApi;

    protected void Application_Start()
    {
        // Initialize OCR engine on app startup
        // Path to tessdata hardcoded for deployment environment
        _globalApi = OcrApi.Create();
        _globalApi.Init(Languages.English);

        AreaRegistration.RegisterAllAreas();
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

    protected void Application_End()
    {
        // Must manually dispose on shutdown
        _globalApi?.Dispose();
    }
}
C#

Podejście IronOCR:

// Program.cs —.NET 8ASP.NET Core application
// IronTesseract jest bezpieczny dla wątków; register as singleton, inject where needed
var builder = WebApplication.CreateBuilder(args);

IronOcr.License.LicenseKey = builder.Configuration["IronOcr:LicenseKey"];

// Register as singleton — one instance, thread-safe, shared across all requests
builder.Services.AddSingleton<IronTesseract>();

builder.Services.AddControllers();

var app = builder.Build();
app.MapControllers();
app.Run();
C#

Wzorzec Global.asax całkowicie znika. IronTesseract rejestruje się jako standardowa usługa singleton, wstrzykiwana do kontrolerów i serwisów przez konstruktor. Model językowy ładuje się jednorazowo przy pierwszym użyciu i pozostaje w pamięci przez cały czas działania aplikacji. Przewodnik konfiguracji IronTesseract obejmuje opcje konfiguracyjne, w tym wybór języka i tryb silnika w momencie rejestracji.

Modernizacja wzorca usuwania starszych wersji

Kod .NET Framework 2.0 używa bloku using (var x = ...) { }. C# 8.0 wprowadził deklaracje using var, które ograniczają usuwanie do zewnętrznego bloku. Starsze bazy kodowe również zawierają try/finally zabezpieczenia usuwania napisane, gdy using instrukcje nie były uważane za godne zaufania we wszystkich scenariuszach. Wszystkie te wzorce wskazują na kod napisany dla platformy .NET Framework i powinny zostać zmodernizowane podczas migracji.

Podejście Tesseract.NET SDK:

// .NET Framework 4.x disposal patterns — three variants encountered in production
public class LegacyOcrProcessor
{
    // Pattern 1: try/finally guard (pre-C# 2.0 style, still common in legacy code)
    public string ProcessWithTryFinally(string imagePath)
    {
        OcrApi api = null;
        try
        {
            api = OcrApi.Create();
            api.Init(Languages.English);
            return api.GetTextFromImage(imagePath);
        }
        finally
        {
            if (api != null)
                api.Dispose();  // Manual null check required
        }
    }

    // Pattern 2: nested using blocks — one for engine, one for image object
    public string ProcessWithNestedUsing(string imagePath)
    {
        using (var api = OcrApi.Create())
        {
            api.Init(Languages.English);
            using (var img = OcrImage.FromFile(imagePath))
            {
                api.SetImage(img);
                return api.GetText();
            }   // img disposed here
        }       // api disposed here — nested indentation grows with each resource
    }

    // Pattern 3: missing disposal — memory leak, common in older service code
    public string ProcessUnsafe(string imagePath)
    {
        var api = OcrApi.Create();   // WARNING: never disposed
        api.Init(Languages.English);
        return api.GetTextFromImage(imagePath);
    }
}
C#

Podejście IronOCR:

// Modern C# 8.0+ disposal — flat, readable, no nesting
public class ModernOcrProcessor
{
    private readonly IronTesseract _ocr;  // Injected singleton, never disposed per-request

    public ModernOcrProcessor(IronTesseract ocr) => _ocr = ocr;

    // Pattern 1: using var declaration — scoped to method, no nesting
    public string ProcessDocument(string imagePath)
    {
        using var input = new OcrInput();  // OcrInput is the disposable resource, not the engine
        input.LoadImage(imagePath);
        return _ocr.Read(input).Text;
    }   // input disposed here automatically — no nesting, no try/finally

    // Pattern 2: multiple inputs in one scope — still flat
    public string ProcessMultipleInputs(string imagePath, string pdfPath)
    {
        using var imageInput = new OcrInput();
        imageInput.LoadImage(imagePath);

        using var pdfInput = new OcrInput();
        pdfInput.LoadPdf(pdfPath);

        var imageText = _ocr.Read(imageInput).Text;
        var pdfText = _ocr.Read(pdfInput).Text;

        return $"{imageText}\n{pdfText}";
    }   // both inputs disposed here — zero nesting
}
C#

OcrInput jest jedynym zasobem jednorazowym w IronOCR. Sam silnik (IronTesseract) nie jest usuwany na żądanie — jest singletonem. Eliminuje to konieczność ponownego ładowania modelu językowego 40–100 MB na każde żądanie, narzuconego przez OcrApi.Create() + api.Init(). Przewodnik wejściowych obrazów obejmuje wszystkie metody ładowania OcrInput, w tym strumienie, tablice bajtów i adresy URL.

Integracja asynchroniczna dla kontrolerów ASP.NET Core

Tesseract.NET SDK nie posiada asynchronicznego interfejsu API. Każde wywołanie jest synchroniczne. W .NET Core wywoływanie synchronicznych operacji blokujących z asynchronicznych akcji kontrolera stwarza ryzyko wyczerpania puli wątków pod obciążeniem. Popularnym obejściem — opakowując wywołania synchroniczne w Task.Run() — przenosi pracę blokującą na wątek puli wątków, ale nie eliminuje zużycia wątku. IronOCR's ReadAsync() oferuje pełną integrację asynchronicznego I/O.

Podejście Tesseract.NET SDK:

// ASP.NET Core controller — forced workaround for synchronous OCR API
[ApiController]
[Route("api/ocr")]
public class OcrController : ControllerBase
{
    [HttpPost("extract")]
    public async Task<IActionResult> ExtractText(IFormFile file)
    {
        // Must copy upload to temp file — OcrApi does not accept streams directly
        var tempPath = Path.GetTempFileName();
        await using (var stream = System.IO.File.OpenWrite(tempPath))
            await file.CopyToAsync(stream);

        string text;
        try
        {
            // Task.Run wraps synchronous call — still consumes a thread-pool thread
            // Does NOT free the calling thread during OCR processing
            text = await Task.Run(() =>
            {
                using (var api = OcrApi.Create())   // 40-100MB load per request
                {
                    api.Init(Languages.English);
                    return api.GetTextFromImage(tempPath);  // synchronous, blocking
                }
            });
        }
        finally
        {
            System.IO.File.Delete(tempPath);  // Manual temp file cleanup
        }

        return Ok(new { text });
    }
}
C#

Podejście IronOCR:

// ASP.NET Core controller — genuine async OCR, no temp files, no thread blocking
[ApiController]
[Route("api/ocr")]
public class OcrController : ControllerBase
{
    private readonly IronTesseract _ocr;  // Singleton injected via DI

    public OcrController(IronTesseract ocr) => _ocr = ocr;

    [HttpPost("extract")]
    public async Task<IActionResult> ExtractText(IFormFile file)
    {
        // Load stream directly — no temp file needed
        using var input = new OcrInput();
        input.LoadImage(file.OpenReadStream());  // Stream input, no disk write

        // ReadAsync — genuinely non-blocking, integrates with ASP.NET Core pipeline
        var result = await _ocr.ReadAsync(input);

        return Ok(new
        {
            text = result.Text,
            confidence = result.Confidence
        });
    }
}
C#

Znikają operacje związane z plikami tymczasowymi. Opakowanie Task.Run znika. Żądanie OcrApi.Create() i związane z nim załadunki 40–100 MB znikają. Poradnik dotyczący asynchronicznego OCR oraz przewodnik po danych wejściowych typu stream dokumentują kompletny potok asynchroniczny, w tym obsługę tokenów anulowania.

Przetwarzanie plików TIFF z wieloma ramkami

Artykuł porównawczy z fazy 1 dotyczył podstawowego przetwarzania obrazów i plików PDF. Wielokadrowy format TIFF to specyficzny scenariusz, powszechnie spotykany w archiwizacji dokumentów, systemach faksowych i procesach przetwarzania obrazów medycznych.SDK Tesseract.NET/wymaga ręcznego iterowania ramek TIFF za pomocą System.Drawing.Bitmap, ekstraktowania każdej ramki do tymczasowego pliku PNG, uruchamiania OCR na pliku tymczasowym i sprzątania. Wzorzec wymusza jawne wywołania GC na dużych dokumentach, aby uniknąć błędów z brakiem pamięci.

Podejście Tesseract.NET SDK:

// Multi-frame TIFF: manual frame extraction to temp files + forced GC
using System.Drawing;
using System.Drawing.Imaging;
using Patagames.Ocr;

public List<string> ProcessMultiFrameTiff(string tiffPath)
{
    var pageTexts = new List<string>();

    using (var api = OcrApi.Create())
    {
        api.Init(Languages.English);

        using (var bitmap = new Bitmap(tiffPath))
        {
            var dimension = new FrameDimension(bitmap.FrameDimensionsList[0]);
            int frameCount = bitmap.GetFrameCount(dimension);

            for (int i = 0; i < frameCount; i++)
            {
                bitmap.SelectActiveFrame(dimension, i);

                // Must write each frame to a temp file — no in-memory path
                var tempPath = Path.GetTempFileName() + ".png";
                bitmap.Save(tempPath, ImageFormat.Png);

                try
                {
                    pageTexts.Add(api.GetTextFromImage(tempPath));
                }
                finally
                {
                    File.Delete(tempPath);  // Manual cleanup on every frame
                }

                // Force GC every 10 frames — workaround for memory pressure
                // Slows processing; indicates memory management is manual
                if (i % 10 == 0)
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
            }
        }
    }

    return pageTexts;
}
C#

Podejście IronOCR:

// Multi-frame TIFF: one method call, no temp files, no manual GC
using IronOcr;

public List<string> ProcessMultiFrameTiff(string tiffPath)
{
    var ocr = new IronTesseract();

    using var input = new OcrInput();
    input.LoadImageFrames(tiffPath);  // Loads all frames natively — no temp files

    var result = ocr.Read(input);

    // Pages map directly to TIFF frames
    return result.Pages.Select(page => page.Text).ToList();
}
C#

Trzydzieści wierszy skrócono do ośmiu. Bez plików tymczasowych, bez iteracji ramek Bitmap, bez wywołań GC.Collect(). LoadImageFrames obsługuje dowolnie duże wieloklatkowe pliki TIFF bez pisania plików pośrednich. Przewodnik dotyczący plików wejściowych TIFF i GIF obejmuje selektywne ładowanie klatek (według zakresu indeksów) oraz wywołania zwrotne postępu dla dużych dokumentów.

Przygotowanie do wdrożenia kontenerów Docker

KodSDK Tesseract.NET/działający na komputerze programisty z systemem Windows zawodzi na etapie kompilacji lub uruchamiania Docker, gdy obrazem bazowym jest Linux. Rozwiązanie nie polega na modyfikacji pliku Dockerfile — natywne pliki binarne są przeznaczone wyłącznie dla systemu Windows i nie można ich w ogóle załadować w systemie Linux. Wsparcie dla Linuxa w IronOCR wymaga niewielkiego uzupełnienia apt-get w pliku Dockerfile i niczego więcej w kodzie aplikacji.

Podejście Tesseract.NET SDK:

# Dockerfile attempt — fails at runtime on Linux base image
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
# This base image is Linux (Debian) by default
# Tesseract.Net.SDK's Windows native DLLs cannot load here
# Application throws DllNotFoundException on first OCR call

WORKDIR /app
COPY --from=build /app/publish .

# Even copying the Windows tessdata folder has no effect —
# the P/Invoke DLL cannot be loaded regardless of file placement
COPY tessdata/ ./tessdata/

ENTRYPOINT ["dotnet", "MyApp.dll"]
# Runtime error: DllNotFoundException: Unable to load DLL 'libtesseract'
# No fix available within Tesseract.Net.SDK — requires replacing the library
Text

Podejście IronOCR:

# Dockerfile for IronOCR on Linux — add one apt-get line, nothing else changes
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base

# Required system dependency for IronOCR on Debian/Ubuntu base images
RUN apt-get update && apt-get install -y libgdiplus \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY --from=build /app/publish .

# No tessdata folder — language data is bundled with the IronOcr NuGet packages
# No platform check code — IronOCR runs identically on Windows and Linux

ENTRYPOINT ["dotnet", "MyApp.dll"]
Text

Jedna linia apt-get. Żadnego folderu tessdata. W aplikacji nie ma kodu zależnego od platformy. Ten sam plik binarny aplikacji, który działa na komputerze programisty z systemem Windows, działa bez zmian w tym kontenerze Linux. Przewodnik wdrożeniowy Docker obejmuje obrazy oparte na Alpine (które używają apk zamiast apt-get), optymalizację budowy wieloetapowej i konfigurację zmiennych środowiskowych dla klucza licencyjnego. Przewodnik wdrożeniowy dla systemu Linux obejmuje scenariusze z systemem Linux na sprzęcie fizycznym oraz WSL2.

Dokumentacja APISDK Tesseract.NET/do IronOCR

SDK Tesseract.NETOdpowiednik IronOCRUwagi
Install-Package Tesseract.Net.SDKdotnet add package IronOcrIronOCR jest przeznaczony dla platform .NET Framework 4.6.2+ oraz .NET 5–9
using Patagames.Ocr;using IronOcr;Pojedyncza przestrzeń nazw
using Patagames.Ocr.Enums;(not needed)Enumy znajdują się w przestrzeni nazw IronOcr.
OcrApi.Create()new IronTesseract()IronTesseract jest bezpieczny dla wątków; użyj jako singleton
api.Init(Languages.English)ocr.Language = OcrLanguage.EnglishPrzypisanie właściwości, a nie wywołanie metody
api.Init(Languages.English | Języki.Niemiećki)ocr.Language = OcrLanguage.English + OcrLanguage.GermanOperator +, nie bitowe OR.
api.GetTextFromImage(path)ocr.Read("path.jpg").TextBezpośrednio lub przez OcrInput.
api.GetTextFromImage(path) (asynchronicznie)await ocr.ReadAsync(input)Prawdziwie asynchroniczny — bez opakowania Task.Run.
OcrImage.FromFile(path)input.LoadImage(path)OcrInput zastępuje OcrImage.
OcrImage.FromBitmap(bitmap)input.LoadImage(bitmap)
new MemoryStream(bytes)OcrImage.FromBitmap.input.LoadImage(bytes)Bezpośrednia obsługa tablic bajtów
api.SetImage(img); api.GetText()ocr.Read(input).TextOcrInput przekazane do Read.
api.GetMeanConfidence()result.ConfidenceZwraca wartość procentową; also available per-word
api.SetRectangle(x, y, w, h)input.LoadImage(path, new CropRectangle(x, y, w, h))OCR bazowane na regionach przez CropRectangle.
api.SetVariable("tessedit_char_whitelist", x)ocr.Configuration.WhiteListCharacters = x
api.SetVariable("tessedit_char_blacklist", x)ocr.Configuration.BlackListCharacters = x
Iteracja ramki bitmapowej + plik tymczasowyinput.LoadImageFrames(tiffPath)Natywna obsługa plików TIFF z wieloma ramkami
(synchronous only)result.SaveAsSearchablePdf("out.pdf")Brak odpowiednika wSDK Tesseract.NET
(no structured output)result.Pages, result.Words, result.LinesWspółrzędne na poziomie słów i poziom pewności
Obejścia GC.Collect().(not needed)IronOCR zarządza pamięcią wewnętrznie
Sprawdzenie platformy: IsOSPlatform(Windows).(remove entirely)IronOCR jest wielopłatformowy
Zarządzanie folderami Tessdata(remove entirely)Języki dołączone do pakietów NuGet

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

Problem 1: Konflikt między docelowymi frameworkami projektu

Tesseract.NET SDK: Po usunięciu Tesseract.Net.SDK i dodaniu IronOcr, projekt nadal jest skierowany na net45 lub net472 z dawnego wymagania.IronOCR obsługuje net462 i późniejsze, więc projekty net45 muszą zaktualizować docelowe framework przed pomyślnym przywróceniem pakietu.

Rozwiązanie: Zaktualizuj <TargetFramework> w pliku .csproj przed dodaniem IronOCR. Jeśli projekt musi obsługiwać zarówno stare, jak i nowe środowiska uruchomieniowe podczas migracji etapowej, należy zastosować wielokierunkowość:

<!-- Single modern target (preferred) -->
<TargetFramework>net8.0</TargetFramework>

<!-- Multi-targeting during phased migration — supports both simultaneously -->
<TargetFrameworks>net462;net8.0</TargetFrameworks>
XML

IronOCR automatycznie określa właściwy zestaw dla każdego języka docelowego. To samo polecenie dotnet add package IronOcr działa dla obu. Strona biblioteki OCR .NET zawiera listę wszystkich obsługiwanych frameworków docelowych.

Problem 2: Pole statyczne OcrApi zastąpione przez singleton DI

Tesseract.NET SDK: Kod zaplecza rejestruje pojedynczą instancję OcrApi jako pole statyczne (w Global.asax, statycznym lokalizatorze usługi lub klasie opakowania singleton). Ten wzorzec był konieczny, ponieważ OcrApi nie jest bezpieczny dla wątków — współdzielenie jednej instancji między wątkami powoduje warunki wyścigu, więc pole statyczne było chronione przez blokadę lub faktycznie tworzone na nowo na żądanie mimo nazwy pola.

Rozwiązanie: Zarejestruj IronTesseract jako prawdziwy singleton bezpieczny dla wątków poprzez kontener DI. Usuń blokadę, usuń pole statyczne, usuń wszelkie ponowne tworzenie na żądanie:

// Remove: private static OcrApi _instance; / private static readonly object _lock = new();

// Replace with DI registration in Program.cs
builder.Services.AddSingleton<IronTesseract>();

// In consuming classes — constructor injection
public class DocumentProcessor
{
    private readonly IronTesseract _ocr;
    public DocumentProcessor(IronTesseract ocr) => _ocr = ocr;

    public async Task<string> ProcessAsync(string path)
    {
        using var input = new OcrInput();
        input.LoadImage(path);
        var result = await _ocr.ReadAsync(input);
        return result.Text;
    }
}
C#

Problem 3: Brak folderu Tessdata po wdrożeniu

Tesseract.NET SDK: Po przejściu na IronOCR zespoły czasami pozostawiają etapy wdrażania tessdata w potokach CI/CD. Folder tessdata/ wskazywany w skryptach build i manifestach wdrożeniowych już nie istnieje — był częścią zarządzania modelem językowym starego SDK. Skrypty kończą się niepowodzeniem, gdy próbują skopiować lub zweryfikować folder, który już nie istnieje.

Rozwiązanie: Usuń wszystkie odniesienia do tessdata ze skryptów wdrożeniowych, celów kopiowania .csproj, poleceń Docker COPY i kroków w pipeline CI/CD. Dane językowe IronOCRsą dostarczane wraz z pakietami NuGet. Uruchom dotnet restore, a dane językowe będą dostępne. Nie jest potrzebne nic więcej:

# Remove from CI/CD pipeline
# BEFORE (delete these lines):
# - cp -r tessdata/ $DEPLOY_PATH/tessdata/
# - test -f $DEPLOY_PATH/tessdata/eng.traineddata

# AFTER: nothing — language data is in the NuGet package restore output
dotnet restore   # Downloads IronOcr and any IronOcr.Languages.* packages
dotnet publish   # Includes language data automatically
SHELL

Przewodnik po wielu językach obejmuje instalację konkretnych pakietów językowych jako pakietów NuGet do wdrożeń offline/airgapped.

Problem 4: BadImageFormatException z niezgodnością 32/64-bitową

Tesseract.NET SDK: Pakiet SDK zawiera oddzielne natywne pliki binarne dla systemów Windows x86 i x64. Projekty skierowane na AnyCPU czasami rozwiązują się w niewłaściwy binarny w zależności od architektury procesu. Błąd pojawia się jako BadImageFormatException lub DllNotFoundException w czasie wykonywania na maszynach, gdzie architektura procesu nie pasuje do natywnego DLL w folderze wyjściowym.

**Rozwiązanie:**IronOCR zawiera odpowiednie natywne binarium dla każdego systemu w ramach pakietu NuGet i automatycznie rozwiązuje odpowiednie binarium przez folder runtimes/ w układzie pakietu. Bez ustawienia celu Platform, bez komend kopiowania warunkowych w zależności od architektury, bez zarządzania podfolderami x64:

<!-- Remove architecture-specific build configurations from .csproj -->
<!-- BEFORE: Conditional native DLL copy based on Platform target -->
<!--
<ItemGroup Condition="'$(Platform)' == 'x64'">
  <Content Include="$(SolutionDir)libs\x64\*.dll">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
</ItemGroup>
-->

<!-- AFTER: Nothing.IronOCR resolves the correct binary automatically. -->
XML

Problem 5: Migracja ciągów konfiguracyjnych

Tesseract.NET SDK: Zmienne silnika Tesseract są ustawiane za pomocą api.SetVariable(string name, string value), używając surowych kluczy string z odniesienia do API Tesseract (np. "tessedit_char_whitelist", "tessedit_pageseg_mode"). Są to ciągi znaków bez typu, bez autouzupełniania w środowisku IDE. Literówki powodują ciche błędy — zmienna jest ignorowana, a nie traktowana jako wyjątek.

**Rozwiązanie:**IronOCR udostępnia konfigurację silnika jako typu właściwości na ocr.Configuration. Literówki stają się błędami kompilacji:

// Before: untyped string variables, silent failures on typos
api.SetVariable("tessedit_char_whitelist", "0123456789");
api.SetVariable("tessedit_pageseg_mode", "7");

// After: typed properties, compile-time validation, IDE completion
ocr.Configuration.WhiteListCharacters = "0123456789";
ocr.Configuration.PageSegmentationMode = TesseractPageSegmentationMode.SingleLine;
C#

Dokumentacja API IronTesseract zawiera wszystkie właściwości konfiguracyjne wraz z ich typami i akceptowanymi wartościami.

Problem 6: Raportowanie postępów w przypadku długich zadań wsadowych

Tesseract.NET SDK: Kod przetwarzania wsadowego raportujący postęp za pomocą IProgress<t> działa na poziomie zadania (zwiększ licznik po każdym pliku) ale nie może raportować wewnątrz pojedynczego dokumentu — nie ma mechanizmu zwrotnego wewnątrz GetTextFromImage(). W przypadku dokumentu liczącego 500 stron pasek postępu pozostaje wstrzymany do momentu zakończenia przetwarzania całego dokumentu.

**Rozwiązanie:**IronOCR oferuje wbudowane śledzenie postępu przez zdarzenie OcrProgress na OcrInput. Wskaźnik postępu wyświetlany na każdej stronie, umożliwiający dokładne wyświetlanie pasków postępu w przypadku długich, wielostronicowych dokumentów:

// IronOCR: page-level progress tracking for multi-page documents
using IronOcr;

var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadPdf("large-archive.pdf");

// Subscribe to page-level progress events
input.OcrProgress += (sender, e) =>
{
    Console.WriteLine($"Processing page {e.CurrentPage} of {e.TotalPages} " +
                      $"({e.ProgressPercent:F0}%)");
};

var result = ocr.Read(input);
Console.WriteLine($"Complete: {result.Pages.Count} pages extracted");
C#

Przewodnik po śledzeniu postępów obejmuje integrację z .NET Core SignalR w celu przesyłania informacji o postępach w czasie rzeczywistym do klientów przeglądarek.

Lista kontrolna migracji Tesseract.NET SDK

Przed migracją

Przed rozpoczęciem pracy nad kodem należy sprawdzić bazę kodu pod kątem wszystkich zastosowań Tesseract.NET SDK:

# Find all files referencing Patagames namespace
grep -rl "Patagames" --include="*.cs" .

# Find all OcrApi instantiation points
grep -rn "OcrApi.Create" --include="*.cs" .

# Find tessdata references in project and build files
grep -rn "tessdata" --include="*.cs" --include="*.csproj" --include="*.yaml" --include="*.yml" .

# Find platform guard checks that can be removed after migration
grep -rn "IsOSPlatform.*Windows" --include="*.cs" .

# Find Task.Run wrappers around synchronous OCR calls
grep -rn "Task.Run" --include="*.cs" . | grep -i "ocr\|image\|text"

# Count distinct OcrApi.Create() call sites to estimate migration scope
grep -c "OcrApi.Create" $(find . -name "*.cs")
SHELL

Udokumentuj liczbę miejsc wywołań OcrApi.Create() — każde z nich jest kandydatem do zastąpienia wstrzyknięciem singleton. Zauważ wszelkie wzorce usuwania try/finally do modernizacji. Zidentyfikuj wszelkie inicjacje Global.asax, Application_Start lub statyczne konstruktor, które zostaną przeniesione do Program.cs.

Migracja kodu

  1. Zaktualizuj <TargetFramework> do net8.0 (lub celu nowoczesnego środowiska wykonawczego) we wszystkich plikach .csproj.
  2. Uruchom dotnet remove package Tesseract.Net.SDK w każdym projekcie.
  3. Uruchom dotnet remove package PdfiumViewer (lub równoważny pakiet renderowania PDF) jeśli jest obecny.
  4. Uruchom dotnet add package IronOcr w każdym projekcie.
  5. Dodaj IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; do Program.cs lub do konstruktora hosta.
  6. Zarejestruj IronTesseract jako singleton w kontenerze DI: services.AddSingleton<IronTesseract>().
  7. Zamień wszystkie using Patagames.Ocr; i using Patagames.Ocr.Enums; na using IronOcr;.
  8. Zamień OcrApi.Create() + api.Init(Languages.X) na wstrzykiwaną przez konstruktor IronTesseract.
  9. Zastąp using (var api = OcrApi.Create()) { ... } blocks with using var input = new OcrInput() declarations
  10. Zamień api.GetTextFromImage(path) na ocr.Read(input).Text lub await ocr.ReadAsync(input).
  11. Zamień Task.Run(() => { /* synchronous OCR */ }) na bezpośredni await ocr.ReadAsync(input).
  12. Zamień api.GetMeanConfidence() na result.Confidence.
  13. Zamień iteracyjne pętle ramek Bitmap TIFF na input.LoadImageFrames(tiffPath).
  14. Zamień api.SetVariable("tessedit_char_whitelist", x) na ocr.Configuration.WhiteListCharacters = x.
  15. Usuń folder tessdata z projektu, usuń wszystkie odniesienia do tessdata ze skryptów wdrażania

Po migracji

  • Skompiluj projekt skierowany na net8.0 i potwierdź, że nie pozostają żadne odwołania Patagames w wyniku budowy.
  • Uruchom aplikację na hoście Linux lub w kontenerze Docker Linux i potwierdź brak DllNotFoundException.
  • Sprawdź, czy wynik tekstowy OCR odpowiada wynikowi sprzed migracji na reprezentatywnej próbce dokumentów produkcyjnych (10–20 dokumentów)
  • Przetestuj przetwarzanie wielostronicowych plików TIFF i sprawdź, czy liczba stron zgadza się z liczbą klatek w oryginale
  • Przeprowadź testy obciążenia na punktach końcowych ASP.NET Core używając ReadAsync() i zweryfikuj, że metryki puli wątków nie pokazują blokowania.
  • Potwierdź, że kontener DI rozwiązuje IronTesseract jako singleton (ta sama instancja na żądanie).
  • Sprawdź, czy potok CI/CD przebiega bez błędów po usunięciu etapów kopiowania danych tessdata
  • Przetestuj kompilację obrazu Docker i uruchomienie kontenera na obrazie bazowym systemu Linux
  • Sprawdź, czy zdarzenia postępu są wywoływane poprawnie w przypadku dokumentów wielostronicowych (PDF lub TIFF)
  • Sprawdź, czy wyniki pewności mieszczą się w oczekiwanym zakresie dla dokumentów o znanej poprawności

Kluczowe korzyści z migracji do IronOCR

Blokada aktualizacji .NET została usunięta. Przed migracją każdy plan przeniesienia usługi z .NET Framework 4.x do.NET 8zatrzymywał się na warstwie OCR. Po migracji usługa OCR kompiluje się i działa na platformach .NET Framework 4.6.2, .NET 6,.NET 8oraz.NET 9z tego samego odwołania do pakietu. Ścieżka aktualizacji jest odblokowana. Zespoły, które utrzymywały oddzielne wdrożenie starszego środowiska uruchomieniowego wyłącznie dla OCR, mogą skonsolidować je w jednym nowoczesnym środowisku docelowym.

Wdrożenie w kontenerze działa bez kompromisów. Element DllNotFoundException na obrazach bazowych Linux został wyeliminowany. Ten sam binarny aplikacji, który działa na stacji roboczej Windows dewelopera, działa wewnątrz kontenera Debian lub Alpine z jedną linią apt-get w pliku Dockerfile. Wdrożenia Kubernetes, Azure Container Apps i zadania AWS ECS na pulach węzłów Linux działają bez licencjonowania kontenerów Windows, większych rozmiarów obrazów ani ścieżek kodu zależnych od architektury. Przewodnik wdrażania Docker oraz przewodnik Azure dokumentują dokładną konfigurację dla każdego środowiska docelowego.

Rurociągi zaprojektowane z myślą o asynchroniczności eliminują presję puli wątków. Obejście Task.Run, które opakowywało synchroniczne OCR w asynchronicznej metodzie, zostało zastąpione przez ReadAsync(). Wątki żądań ASP.NET Core są zwalniane podczas przetwarzania OCR, a nie blokowane. W warunkach wysokiej współbieżności przekłada się to bezpośrednio na wyższą przepustowość żądań i mniejsze opóźnienia dla całej aplikacji, a nie tylko dla punktów końcowych OCR.

Zużycie pamięci spada proporcjonalnie do współbieżności. Usługa, która wcześniej tworzyła jedną instancję OcrApi na każde równoczesne żądanie — każda ładowała 40–100 MB danych językowych — teraz ładuje te dane raz do singleton instancji IronTesseract. Przy dziesięciu równoczesnych żądaniach różnica wynosi 400–1000 MB w porównaniu z pojedynczym stałym obciążeniem. Ta redukcja jest natychmiast widoczna w metrykach zasobów kontenerów i umożliwia mniejsze limity pamięci podów, wyższą gęstość podów oraz niższe koszty infrastruktury chmurowej.

Nowoczesne wzorce C# zastępują ceremonie .NET Framework. Zabezpieczenia usuwania try/finally, zagnieżdżone bloki using oraz wywołania GC.Collect() między ramkami TIFF — wszystkie te znikają. using var input = new OcrInput() jest całą wzorcem zarządzania zasobami. Recenzje kodu są krótsze. Wdrożenie nowych programistów do usługi OCR zajmuje mniej czasu. Dokumentacja API OcrResult opisuje pełny model obiektowy wyników, w tym dane strukturalne, wyniki pewności oraz pliki PDF z możliwością wyszukiwania, które zastępują ręczne wzorce obsługi wyników ze starszego zestawu SDK.

**Wsparcie komercyjne zastępuje zależność od pojedynczego programisty.**SDK Tesseract.NET/jest obsługiwany przez indywidualnego programistę bez umowy SLA i gwarancji ciągłości działania organizacji.IronOCR został opracowany przez Iron Software, podmiot komercyjny posiadający dedykowane kanały wsparcia, udokumentowane procesy ujawniania informacji dotyczących bezpieczeństwa oraz warunki licencji spełniające wymagania dotyczące zamówień korporacyjnych. Strona licencjonowania IronOCR obejmuje poziomy wsparcia oraz model licencji wieczystej (od $999), który zastępuje zarówno opłatę za SDK Patagames jak i ukryte koszty utrzymania infrastruktury wyłącznie dla Windows na modernizującej się .NET stack.

Zwróć uwagę: PDFium i Tesseract są zarejestrowanymi znakami towarowymi ich odpowiednich właścicieli. Ta strona nie jest powiązana, zatwierdzona ani sponsorowana przez Chromium Project ani Google. 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