IRONSOFTWAREHOME
FILMY

Jak odczytywać pliki GIF i TIFF z wieloma ramkami w języku C#

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 sierpnia 2026

Ten przewodnik prowadzi programistów .NET przez pełną migrację zPaddleSharp OCR(Sdcb.PaddleOCR) na IronOCR. Obejmuje to zastąpienie zarządzania sesjami wnioskowania, wyeliminowanie zależności od przetwarzania wstępnego OpenCV, usunięcie logiki wyboru zaplecza dla procesorów CPU, GPU i OpenVINO oraz migrację procesów rozpoznawania tabel. Każda sekcja zawiera kod przed i po przetworzeniu, zaczerpnięty z wzorców specyficznych dla PaddleSharp, które nie pojawiają się w ogólnych porównaniach OCR.

Dlaczego warto przejść z PaddleSharp OCR

PaddleSharp udostępnia potok wnioskowania oparty na głębokim uczeniu się na poziomie warstwy aplikacji. Architektura ta zapewnia dostęp do wydajności modeli PaddlePaddle, ale wymaga, aby aplikacja zarządzała kwestiami, które w innym przypadku należałyby do infrastruktury. Następujące problemy skłaniają większość zespołów .NET do poszukiwania alternatyw.

Konfiguracja Backend Inference to kod aplikacji. Wybór między backendami CPU, GPU i OpenVINO w PaddleSharp wymaga konstrukcji i konfiguracji obiektów PaddleConfig, wybrania odpowiedniego pakietu NuGet dla natywnego środowiska uruchomieniowego na docelową platformę wdrożeniową oraz warunkowego rozgałęzienia kodu inicjalizacyjnego w zależności od dostępnego sprzętu podczas uruchamiania. Ta logika znajduje się w aplikacji, a nie w bibliotece, i przestaje działać, gdy zmienia się docelowe środowisko.

OpenCV jest wymaganym elementem zależności dla danych wejściowych obrazu. PaddleSharp nie może bezpośrednio akceptować ścieżki pliku ani strumienia. Każdy obraz przechodzi przez Cv2.ImRead() OpenCV zanim dotrze do silnika OCR. To wymusza OpenCvSharp4 oraz specyficzny dla platformy pakiet OpenCvSharp4.runtime.* do grafu zależności. Aktualizacja środowiska uruchomieniowego jednej platformy bez aktualizacji drugiej powoduje awarie środowiska uruchomieniowego, które trudno odtworzyć w różnych środowiskach.

Żywotność sesji inferencji wymaga wyraźnego projektowania. PaddleOcrAll ładuje trzy binaria modelu z dysku przy konstrukcji. Ten koszt — mierzony w setkach milisekund — oznacza, że obiekt nie może być instancjonowany per-żądanie. Zespoły muszą zaprojektować strategię cyklu życia: singleton, puli, lub zakres. W ASP.NET Core zazwyczaj oznacza to zarejestrowaną usługę z dokładną analizą bezpieczeństwa wątków, ponieważ PaddleOcrAll dzieli się podstawowym stanem natywnym.

Rozpoznawanie tabel wymaga pobrania oddzielnych modeli. Ekstrakcja dokumentów strukturalnych w PaddleSharp wymaga dedykowanego modelu rozpoznawania tabel oprócz standardowego trzyetapowego procesu wykrywania/klasyfikacji/rozpoznawania. Model ten jest czwartym plikiem, który należy pobrać, zaktualizować i skonfigurować. Nie ma ujednoliconego interfejsu API — rozpoznawanie tabel wykorzystuje odrębną ścieżkę kodu z własnym typem wyniku.

Brak możliwości tworzenia plików PDF z funkcją wyszukiwania. PaddleSharp generuje ciągi tekstowe. Nie może tworzyć plików PDF z możliwością wyszukiwania. Zespoły, które muszą archiwizować zeskanowane dokumenty jako pliki PDF z możliwością wyszukiwania tekstu, muszą zintegrować oddzielną bibliotekę PDF, zarządzać tą dodatkową zależnością i napisać warstwę konwersji. Luka w formacie wyjściowym jest całkowita: brak hOCR, brak strukturalnego, przeszukiwalnego pliku PDF, brak nakładki warstwy tekstowej.

Łańcuch zależności upstream nie jest własnością społeczności .NET. PaddleSharp stanowi nakładkę na framework wnioskowania PaddlePaddle firmy Baidu. Zmiany formatu modelu między wersjami PaddleOCR spowodowały w przeszłości uszkodzenie warstwy powiązania .NET. Większość działań związanych ze śledzeniem problemów, dokumentacją i dyskusjami na temat wydań odbywa się w języku chińskim. Dla zespołu .NET, w którym nie ma osób posługujących się językiem mandaryńskim monitorujących projekty nadrzędne, przełomowe zmiany pojawiają się bez ostrzeżenia.

Podstawowy problem

Wybór i inicjalizacja backendu w PaddleSharp wymaga kodu konfiguracyjnego, który należy do infrastruktury, a nie do logiki OCR:

// PaddleSharp: Backend selection sprawls into application startup
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;

// CPU-only deployment
var config = PaddleConfig.FromModelDir("models/det");
config.SetCpuMathLibraryNumThreads(4);

// GPU deployment — different package, different init path
// var config = PaddleConfig.FromModelDir("models/det");
// config.EnableGpu(500, 0);  // memoryMB, deviceId

// OpenVINO deployment — third conditional branch
// config.EnableMkldnn();

// Application code now owns the hardware topology decision
C#
// IronOCR: Nie backend selection. Nie config objects. Zero hardware decisions.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var result = new IronTesseract().Read("document.jpg");
Console.WriteLine(result.Text);
// Runs on CPU, Linux, Docker, or ARM without a code change
C#

##IronOCR a PaddleSharp OCR: porównanie funkcji

Oto bezpośrednie porównanie możliwości w wymiarach, które mają największe znaczenie podczas migracji:

FunkcjaPaddleSharp OCRIronOCR
Wymagane pakiety NuGetMinimum 3–41
Metoda wprowadzania obrazówOpenCV Cv2.ImRead()Ścieżka bezpośrednia, strumień lub tablica bajtów
Wejście PDF (natywne)NieTak
Plik PDF chroniony hasłemNieTak
Wielostronicowy plik TIFFZa pośrednictwem OpenCVJęzyk ojczysty
Wynik w formacie PDF z możliwością wyszukiwaniaNieTak (result.SaveAsSearchablePdf())
eksport hOCRNieTak
Wybór zaplecza (CPU/GPU/OpenVINO)Ręczny PaddleConfigAutomatyczne
Potok przetwarzania wstępnegoRęczne operacje OpenCVWbudowany (Deskew, DeNoise, Contrast, itd.)
Zarządzanie cyklem życia sesji wnioskowaniaPodręcznik (kosztowna konstrukcja)Lekki IronTesseract
Model rozpoznawania tabelOddzielna ścieżka pobierania i koduinput.LoadImage() + uporządkowany wynik
Obsługiwane języki~10–20125+
Instalacja językaPobierz plik wzorcowyPakiet NuGet
Wielojęzyczne tłumaczenie symultaniczneOgraniczoneTak (OcrLanguage.French + OcrLanguage.German)
OCR oparte na regionieBrak wbudowanychCropRectangle
Odczytywanie BarCode podczas OCRNieTak (ocr.Configuration.ReadBarCodes = true)
Wyniki pewnościW podziale na regionyZa słowo, za wiersz, za stronę
Strukturalna hierarchia wynikówLista regionów płaskichStrony → Akapity → Wiersze → Słowa → Znaki
Wdrażanie wielopłatformoweZłożone (pakiety środowiska uruchomieniowego platformy)Pojedynczy pakiet NuGet, wszystkie platformy
Wdrożenie DockerWiele warstw, pakiety uruchomieniowePojedyncza warstwa
Wsparcie komercyjneZgłoszenia na GitHubie (głównie w języku chińskim)Wsparcie e-mail
Model licencjiApache 2.0Wieczysty ($999 Lite, 1 499 $ Pro, 2 999 $ Enterprise)

Szybki start: Migracja zPaddleSharp OCRdo IronOCR

Krok 1: Zastąp pakiet NuGet

Usuń PaddleSharp i jego zależność od OpenCV:

dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleInference
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
SHELL

Zainstaluj IronOCR z NuGet:

dotnet add package IronOcr

Krok 2: Aktualizacja przestrzeni nazw

Zastąp przestrzenie nazw PaddleSharp pojedynczą przestrzenią nazw IronOCR:

// Before (PaddleSharp)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleInference;
using OpenCvSharp;

// After (IronOCR)
using IronOcr;
C#

Krok 3: Inicjalizacja licencji

Dodaj inicjalizację licencji raz podczas uruchamiania aplikacji — w Program.cs, Startup.cs, lub w korzeniu kompozycji:

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

Przykłady migracji kodu

Wymiana cyklu życia sesji wnioskowania

Konstrukcja PaddleOcrAll PaddleSharp jest kosztowna, ponieważ ładuje trzy binaria modelu synchronicznie przy instancji. Aplikacje produkcyjne muszą traktować go jako obiekt długotrwały, co determinuje konkretny wzorzec wstrzykiwania zależności. Należy również zwrócić uwagę na łańcuch usuwania, ponieważ podstawowe zasoby natywne muszą być zwalniane we właściwej kolejności.

Podejście PaddleSharp OCR:

// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;
using Microsoft.Extensions.DependencyInjection;

// Expensive: loads 3 model files from disk on construction (~300–800ms)
public class PaddleOcrEngine : IDisposable
{
    private readonly PaddleOcrAll _ocr;
    private bool _disposed;

    public PaddleOcrEngine()
    {
        var detModel = LocalFullModels.ChineseV3.DetectionModel;
        var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
        var recModel = LocalFullModels.ChineseV3.RecognitionModel;

        // Must be singleton — cannot afford per-request construction
        _ocr = new PaddleOcrAll(detModel, clsModel, recModel);
    }

    public string Read(string imagePath)
    {
        using var mat = Cv2.ImRead(imagePath); // OpenCV required even for a file path
        var result = _ocr.Run(mat);
        return string.Join(" ", result.Regions.Select(r => r.Text));
    }

    public void Dispose()
    {
        if (!_disposed)
        {
            _ocr?.Dispose();
            _disposed = true;
        }
    }
}

// Startup.cs — forced singleton because of construction cost
services.AddSingleton<PaddleOcrEngine>();
C#

Podejście IronOCR:

using IronOcr;
using Microsoft.Extensions.DependencyInjection;

// IronTesseract has lightweight initialization — no model loading on construction
public class OcrEngine
{
    public string Read(string imagePath)
    {
        return new IronTesseract().Read(imagePath).Text;
    }
}

// Flexible registration — singleton, scoped, or transient all work
services.AddTransient<OcrEngine>();

// Or skip the wrapper entirely and inject IronTesseract directly
services.AddTransient<IronTesseract>();
C#

Shift od wymuszonego singletonu do elastycznego cyklu życia jest znaczące. Koszt budowy PaddleSharp determinuje decyzję dotyczącą okresu eksploatacji usługi;IronOCR pozwala dokonać wyboru w oparciu o wymagania aplikacji dotyczące wielowątkowości i izolacji żądań. Podręcznik konfiguracji IronTesseract obejmuje opcje konfiguracyjne, które mają zastosowanie na poziomie instancji.

Migracja potoku przetwarzania wstępnego OpenCV

Zespoły korzystające z PaddleSharp w przypadku skanów o niskiej jakości zazwyczaj tworzą potok przetwarzania wstępnego OpenCV przed uruchomieniem silnika OCR. Potok ten wymaga znajomości interfejsu API OpenCV, który jest znacznie większy niż to, czego faktycznie wymaga jakiekolwiek zadanie przetwarzania wstępnego OCR. Typowe operacje — deskew, denoise, rozciąganie kontrastu — wymagają wielu operacji Mat i dokładnego zarządzania pamięcią z użyciem bloków using, aby zapobiec wyciekom pamięci natywnej.

Podejście PaddleSharp OCR:

// Simplified — see OpenCvSharp documentation for full API
using OpenCvSharp;
using Sdcb.PaddleOCR;

public string ReadWithPreprocessing(string imagePath, PaddleOcrAll ocr)
{
    using var original = Cv2.ImRead(imagePath);

    // Step 1: Grayscale conversion
    using var gray = new Mat();
    Cv2.CvtColor(original, gray, ColorConversionCodes.BGR2GRAY);

    // Step 2: Denoise (Gaussian blur to reduce noise)
    using var denoised = new Mat();
    Cv2.GaussianBlur(gray, denoised, new Size(3, 3), 0);

    // Step 3: Adaptive threshold for binarization
    using var binary = new Mat();
    Cv2.AdaptiveThreshold(denoised, binary, 255,
        AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2);

    // Step 4: Deskew — requires custom rotation detection logic (not shown)
    // Several dozen lines of custom Mat operations

    var result = ocr.Run(binary);
    return string.Join(" ", result.Regions.Select(r => r.Text));
    // Each Mat must be disposed; missing a using block leaks native memory
}
C#

Podejście IronOCR:

using IronOcr;

public string ReadWithPreprocessing(string imagePath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);

    // Named operations replace OpenCV knowledge requirements
    input.Deskew();
    input.DeNoise();
    input.Contrast();
    input.Binarize();

    var result = new IronTesseract().Read(input);
    return result.Text;
    // OcrInput implements IDisposable; using block handles cleanup
}
C#

Brak przydziałów Mat. Brak wiedzy na temat parametrów progu adaptacyjnego. Bez niestandardowych obliczeń matematycznych dotyczących obracania w celu wyprostowania. Ten sam proces przetwarzania wstępnego, który wymagał 30–50 linii kodu OpenCV, sprowadza się teraz do czterech wywołań metod. Przewodnik po korekcji jakości obrazu dokumentuje każdy dostępny filtr wraz z przykładami przed i po. Dla dokumentów z dużym szumem tła, input.DeepCleanBackgroundNoise() idzie dalej niż DeNoise() bez żadnych dodatkowych parametrów.

Dla zespołów, których wymagania dotyczące przetwarzania wstępnego są niestandardowe, kreator filtrów zapewnia interaktywne narzędzie do oceny kombinacji filtrów na konkretnych typach dokumentów przed zatwierdzeniem kodu.

Eliminacja wyboru backendu

PaddleSharp udostępnia backend wnioskowania jako element na poziomie aplikacji. Wdrożenie, które musi działać na maszynie wirtualnej w chmurze wyposażonej wyłącznie w procesor, wykorzystuje inny kod inicjalizacyjny niż to przeznaczone dla stacji roboczej z procesorem graficznym lub urządzenia brzegowego obsługującego Intel OpenVINO. Ta logika warunkowa zazwyczaj znajduje się w kodzie uruchamiającym aplikację, sprawdzaniu zmiennych środowiskowych lub flagach funkcji — czyli w elementach infrastruktury, które nie mają nic wspólnego z odczytywaniem tekstu z obrazów.

Podejście PaddleSharp OCR:

// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;

public PaddleOcrAll CreateOcrEngine(string backendMode)
{
    // Each backend requires a different NuGet runtime package installed
    switch (backendMode)
    {
        case "gpu":
            // Requires: Sdcb.PaddleInference.runtime.win64.cuda
            // Requires: CUDA toolkit + cuDNN installed on host
            var gpuConfig = PaddleConfig.FromModelDir("models/");
            gpuConfig.EnableGpu(500, deviceId: 0); // Simplified
            break;

        case "openvino":
            // Requires: Sdcb.PaddleInference.runtime.win64.mkl
            var oviConfig = PaddleConfig.FromModelDir("models/");
            oviConfig.EnableMkldnn(); // Simplified
            break;

        default:
            // CPU-only — still requires platform-specific runtime package
            var cpuConfig = PaddleConfig.FromModelDir("models/");
            cpuConfig.SetCpuMathLibraryNumThreads(Environment.ProcessorCount);
            break;
    }

    // Backend-specific config passed to model constructors — Simplified
    var detModel = LocalFullModels.ChineseV3.DetectionModel;
    var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
    var recModel = LocalFullModels.ChineseV3.RecognitionModel;
    return new PaddleOcrAll(detModel, clsModel, recModel);
}
C#

Podejście IronOCR:

using IronOcr;

// Nie backend selection. Nie switch statement. Nie environment variable check.
// The same code runs on CPU-only VMs, GPU workstations, and ARM devices.
public IronTesseract CreateOcrEngine()
{
    return new IronTesseract();
}

// Parallel processing across CPU cores — no GPU configuration required
public IEnumerable<string> ReadBatch(IEnumerable<string> imagePaths)
{
    var results = new System.Collections.Concurrent.ConcurrentBag<string>();
    Parallel.ForEach(imagePaths, path =>
    {
        var result = new IronTesseract().Read(path);
        results.Add(result.Text);
    });
    return results;
}
C#

Wzorzec Parallel.ForEach tutaj jest wątkowo-bezpieczny prosto z pudełka. Każda instancja IronTesseract jest niezależna i nie współdzieli stanu natywnego. Dla zespołów, których wdrożenie PaddleSharp wymaga poświęcania czasu na zarządzanie warunkami backendowymi, uproszczenie to oznacza również poprawę niezawodności wdrożenia — ten sam artefakt kompilacji działa wszędzie bez kodu wykrywającego sprzęt. Przewodnik po optymalizacji szybkości obejmuje opcje konfiguracyjne dla scenariuszy, w których ważna jest przepustowość.

Migracja rozpoznawania tabel

Wyodrębnianie tabel w PaddleSharp wymaga dedykowanego modelu rozpoznawania tabel — czwartego pliku modelu, wykraczającego poza standardowy zestaw wykrywania, klasyfikacji i rozpoznawania. Model tabelowy wykorzystuje oddzielne wywołanie API i zwraca własną strukturę wyników. Zespoły tworzące potoki przetwarzania faktur, formularzy lub arkuszy kalkulacyjnych utrzymują dwie równoległe ścieżki inicjalizacji i dwie strategie analizowania wyników.

Podejście PaddleSharp OCR:

// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;

public class TableRecognitionService
{
    // Standard OCR engine — 3 models
    private readonly PaddleOcrAll _textOcr;

    // Table engine — 4th model, separate initialization
    // private readonly PaddleOcrTable _tableOcr; // Simplified

    public TableRecognitionService()
    {
        var detModel = LocalFullModels.ChineseV3.DetectionModel;
        var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
        var recModel = LocalFullModels.ChineseV3.RecognitionModel;
        _textOcr = new PaddleOcrAll(detModel, clsModel, recModel);

        // Table model: separate download, separate version tracking
        // var tableModel = LocalFullModels.TableEnV2.Model; // Simplified
        // _tableOcr = new PaddleOcrTable(tableModel); // Simplified
    }

    public void ProcessDocument(string imagePath)
    {
        using var image = Cv2.ImRead(imagePath);

        // Text extraction path
        var textResult = _textOcr.Run(image);
        var text = string.Join(" ", textResult.Regions.Select(r => r.Text));

        // Table extraction path — different API, different result structure
        // var tableResult = _tableOcr.Run(image); // Simplified
        // foreach (var cell in tableResult.Cells) { ... } // Simplified
    }
}
C#

Podejście IronOCR:

using IronOcr;

public class TableRecognitionService
{
    // One engine handles both text and table regions
    public void ProcessDocument(string imagePath)
    {
        var ocr = new IronTesseract();
        var result = ocr.Read(imagePath);

        // Structured hierarchy: pages → paragraphs → lines → words
        foreach (var page in result.Pages)
        {
            foreach (var paragraph in page.Paragraphs)
            {
                Console.WriteLine($"Block at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");
            }
        }

        Console.WriteLine($"Full document text: {result.Text}");
    }
}
C#

W przypadku dokumentów, w których sama struktura tabeli musi zostać wyodrębniona jako wiersze i kolumny,IronOCR zapewnia dedykowaną funkcję wyodrębniania tabel:

using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice-with-table.jpg");

var result = ocr.Read(input);

// Access structured page layout for table region extraction
foreach (var page in result.Pages)
{
    foreach (var line in page.Lines)
    {
        // Lines within a table region preserve spatial ordering
        Console.WriteLine($"Row text: {line.Text} | Y position: {line.Y}");
        foreach (var word in line.Words)
        {
            Console.WriteLine($"  Cell: '{word.Text}' at X={word.X}");
        }
    }
}
C#

Usunięto jedno pobranie modelu. Wyeliminowano jedną ścieżkę inicjalizacji. Strukturalna hierarchia wyników w IronOCR— z współrzędnymi X/Y na poziomie słów — zapewnia dane pozycyjne potrzebne do odtworzenia wierszy i kolumn tabeli bez oddzielnego modelu rozpoznawania. Przewodnik po odczytywaniu tabeli oraz przewodnik po wynikach odczytu obejmują pełny, ustrukturyzowany interfejs API.

Wyszukiwalny plik PDF z zeskanowanych dokumentów

PaddleSharp generuje ciągi tekstowe i nic więcej. Stworzenie archiwum dokumentów, w którym zeskanowane pliki PDF umożliwiają wyszukiwanie tekstu, wymaga zintegrowania oddzielnej biblioteki PDF, napisania warstwy nakładki tekstowej oraz współdziałania dwóch bibliotek. Zespoły, które zaakceptowały to ograniczenie, często uznają je za czynnik decydujący o migracji — wysiłek związany z integracją dwóch bibliotek przewyższa wysiłek związany ze zmianą dostawcy usług OCR.

Podejście PaddleSharp OCR:

// Simplified — PaddleSharp has no PDF output. Requires a separate PDF library.
// Example of what teams typically build:

// using Sdcb.PaddleOCR;
// using SomePdfLibrary; // Third dependency to produce searchable PDF

public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
    // Step 1: OCR via PaddleSharp — produces text only
    // var text = _ocr.Run(Cv2.ImRead(imagePath));

    // Step 2: Build a PDF with text overlay using a separate PDF library
    // Requires: text positions mapped to PDF coordinate space
    // Requires: image embedded as background
    // Requires: invisible text layer positioned over image
    // ~50–100 lines of PDF construction code
    throw new NotImplementedException("Requires a separate PDF library");
}
C#

Podejście IronOCR:

using IronOcr;

public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    input.Deskew();   // Straighten scan before archiving
    input.DeNoise();  // Clean up scan artifacts

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

    // One call: OCR + searchable PDF with text layer + image background
    result.SaveAsSearchablePdf(outputPdfPath);
}

// Multi-page document — same pattern
public void ArchiveMultiPageDocument(string[] imageFiles, string outputPdfPath)
{
    using var input = new OcrInput();
    foreach (var file in imageFiles)
        input.LoadImage(file);

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

Brak biblioteki PDF. Bez mapowania współrzędnych. Brak pozycjonowania warstw tekstowych. Format wyjściowy PDF z możliwością wyszukiwania w IronOCR osadza niewidoczną warstwę tekstową na oryginalnym obrazie, tworząc plik, który jest zarówno wierny wizualnie zeskanowanemu dokumentówi, jak i w pełni przeszukiwalny pod kątem tekstu. Poradnik w formacie PDF z funkcją wyszukiwania obejmuje wybór stron, opcje jakości oraz kontrolę metadanych.

Odnośnik do dokumentacji APIPaddleSharp OCRdo IronOCR

PaddleSharp OCRIronOCR
Sdcb.PaddleOCR (namespace)IronOcr (namespace)
Sdcb.PaddleInference (namespace)Nie jest wymagane — konfiguracja automatyczna
PaddleOcrAllIronTesseract
new PaddleOcrAll(det, cls, rec)new IronTesseract()
LocalFullModels.ChineseV3.DetectionModelBrak odpowiednika — brak wyboru modelu
LocalFullModels.ChineseV3.ClassifierModelBrak odpowiednika — brak wyboru modelu
LocalFullModels.ChineseV3.RecognitionModelBrak odpowiednika — brak wyboru modelu
PaddleConfig.FromModelDir()Brak odpowiednika — brak obiektu konfiguracyjnego
config.EnableGpu(memMB, deviceId)Brak odpowiednika — backend jest automatyczny
config.EnableMkldnn()Brak odpowiednika — backend jest automatyczny
config.SetCpuMathLibraryNumThreads(n)Brak odpowiednika — zarządzane wewnętrznie
Cv2.ImRead(path) (OpenCV load)input.LoadImage(path)
ocr.Run(mat)ocr.Read(input) lub ocr.Read("file.jpg")
result.Regionsresult.Pages[0].Words lub result.Pages[0].Lines
region.Textword.Text, line.Text, paragraph.Text
region.Rect.Center.X/.Yword.X, word.Y
region.Score (confidence)word.Confidence, result.Confidence
Zmiana języka na poziomie modeluocr.Language = OcrLanguage.French
Model tabelaryczny (do pobrania osobno)Wbudowana hierarchia wyników strukturalnych
Cv2.CvtColor(..., GRAY)input.Binarize() lub input.Contrast()
Cv2.GaussianBlur(...)input.DeNoise()
Brak możliwości wyszukiwania w pliku PDFresult.SaveAsSearchablePdf("output.pdf")

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

Problem 1: Nieudane wyładowanie zależności OpenCV

PaddleSharp OCR: OpenCvSharp4.runtime.win i podobne specyficzne dla platformy pakiety uruchomieniowe instalują nienadzorowane natywne biblioteki DLL. Te biblioteki DLL mogą uniemożliwić prawidłowe czyszczenie w niektórych scenariuszach hostingu — w szczególności podczas recyklingu puli aplikacji IIS — i powodować błędy ładowania zestawów, gdy w czasie kompilacji odwołuje się do niewłaściwego pakietu środowiska uruchomieniowego platformy. Ich usunięcie wymaga zarówno usunięcia pakietu NuGet, jak i wyczyszczenia wszelkich buforowanych plików binarnych w katalogu wyjściowym.

Rozwiązanie: Po usunięciu pakietów OpenCvSharp4 oraz OpenCvSharp4.runtime.*, wyczyść katalog wyjściowy build przed ponownym zbudowaniem:

dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet clean
dotnet build
SHELL

IronOCR wewnętrznie łączy swoje natywne zależności i obsługuje niezarządzany cykl życia. Nie jest wymagany wybór pakietu uruchomieniowego specyficznego dla danej platformy. Podręcznik konfiguracji IronTesseract zawiera informacje o wymaganiach platformy, które IronOCR obsługuje automatycznie.

Problem 2: Pliki modeli pozostawione na dysku po migracji

PaddleSharp OCR: Pliki modeli pobrane przez PaddleSharp (wykrywanie, klasyfikacja, rozpoznawanie oraz wszelkie modele tabel) są zazwyczaj przechowywane w katalogu models/ względnym do aplikacji lub w skonfigurowanej ścieżce. Pliki te nie są usuwane po odinstalowaniu pakietu NuGet. W obrazie Docker zwiększają one niepotrzebnie rozmiar warstwy. W potoku wdrażania nieaktualne pliki modeli znajdujące się w starych ścieżkach mogą powodować błędy uruchamiania, jeśli jakikolwiek pozostały kod inicjalizacyjny odwołuje się do nich.

Rozwiązanie: Wyraźnie usuń katalogi modeli w ramach migracji. Sprawdź konfigurację startową pod kątem wszelkich odniesień do ścieżek:

# Locate model directory references in application code
grep -r "LocalFullModels\|ModelPath\|models/" --include="*.cs" .
grep -r "DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
SHELL

Po usunięciu odniesień do modeli i zainicjowaniu IronOCR należy usunąć katalog modelu z repozytorium i kontekstu kompilacji Docker.

Problem 3: Założenie dotyczące czasu życia singletonu przestaje obowiązywać po migracji

PaddleSharp OCR: PaddleOcrAll był zarejestrowany jako singleton, ponieważ koszt jego konstrukcji sprawiał, że instancjonowanie per-żądanie było niepraktyczne. Kod migracyjny, który przenosi IronOCR do tej samej rejestracji singletonowej, wprowadza niepotrzebne współdzielenie stanu między żądaniami. Podczas gdy IronTesseract jest wątkowo-bezpieczny, gdy jest używany równocześnie, nie ma potrzeby udostępniać jednej instancji — każda instancja jest niezależna.

Rozwiązanie: Należy ocenić, czy rejestracja singletonów służy celom wykraczającym poza wydajność. W przypadku większości aplikacji ASP.NET Core rejestracja tymczasowa jest lepszym wyborem w przypadku IronOCR:

// PaddleSharp — forced singleton due to construction cost
services.AddSingleton<PaddleOcrAll>(sp =>
{
    var det = LocalFullModels.ChineseV3.DetectionModel;  // Simplified
    var cls = LocalFullModels.ChineseV3.ClassifierModel; // Simplified
    var rec = LocalFullModels.ChineseV3.RecognitionModel; // Simplified
    return new PaddleOcrAll(det, cls, rec);
});

//IronOCR— transient works; no expensive construction
services.AddTransient<IronTesseract>();
C#

W scenariuszach przetwarzania wsadowego o dużej przepustowości, w których wymagane jest wyraźne ponowne wykorzystanie instancji, wzorzec singleton lub wzorzec puli nadal działa — jest to jednak wybór związany z wydajnością, a nie wymóg poprawności.

Problem 4: Kolejność regionów wyników nie jest już wymagana

PaddleSharp OCR: result.Regions zwraca wykryte regiony tekstowe w kolejności wykrycia, która niekoniecznie odpowiada kolejności czytania (od lewej do prawej, z góry do dołu). Zespoły zazwyczaj stosują sortowanie według .Rect.Center.Y, a następnie .Rect.Center.X zanim połączą tekst regionu — wzorzec ten pojawia się w prawie każdym wdrożeniu ekstrakcji tekstu PaddleSharp. Dosłowne przeniesienie tego wzorca do IronOCR powoduje powstanie zbędnego kodu.

**Rozwiązanie:**IronOCR domyślnie zwraca wyniki w kolejności odczytu. Usuń sortowanie:

// PaddleSharp — manual reading-order sort required
var text = string.Join("\n", result.Regions
    .OrderBy(r => r.Rect.Center.Y)
    .ThenBy(r => r.Rect.Center.X)
    .Select(r => r.Text));

//IronOCR— result.Text is already in reading order; no sort needed
var text = result.Text;

// For word-level access with position, use the structured hierarchy directly
foreach (var word in result.Pages[0].Words)
{
    Console.WriteLine($"{word.Text} at ({word.X},{word.Y})");
}
C#

Problem 5: Przywracanie uszkodzonych pakietów zależnych od backendu

PaddleSharp OCR: Niektóre konfiguracje PaddleSharp warunkowo odwołują się do różnych pakietów Sdcb.PaddleInference.runtime.* w zależności od docelowego środowiska (CUDA dla GPU, MKL dla OpenVINO, tylko CPU). Czasami pojawia się to jako warunki .csproj lub jako oddzielne pliki projektu na docelowe wdrożenie. Powstała w ten sposób macierz kompilacji powoduje przerwanie działania potoków CI, gdy przywracany jest niewłaściwy zestaw pakietów.

Rozwiązanie: Po usunięciu pakietów PaddleSharp, przeprowadź audyt pliku .csproj dla warunkowych bloków PackageReference odwołujących się do jakichkolwiek pakietów Sdcb.* lub OpenCvSharp* i usuń je całkowicie:

grep -n "Sdcb\|OpenCvSharp\|PaddleInference" *.csproj
SHELL

IronOCR używa pojedynczego odniesienia do pakietu IronOcr bez warunków platformowych. Ten sam pakiet działa poprawnie w systemach Windows, Linux i macOS.

Problem 6: Struktura wyników tabeli nie ma bezpośredniego odpowiednika

PaddleSharp OCR: PaddleOcrTable zwraca strukturę opartą na komórkach z indeksami wierszy i kolumn dla każdej rozpoznanej komórki. Kod, który konsumuje tę strukturę, zazwyczaj buduje dwuwymiarową tablicę indeksowaną przez (row, column).IronOCR nie zapewnia identycznej struktury indeksu komórek — dostarcza współrzędne słów i wierszy, które wymagają grupowania przestrzennego w celu odtworzenia siatki komórek.

Rozwiązanie: Odtworzyć strukturę tabeli na podstawie współrzędnych słów z IronOCR, stosując grupowanie według pozycji Y dla wierszy i sortowanie według pozycji X dla kolumn. W przypadku popularnych formatów tabel instrukcja czytania tabel przedstawia podejście oparte na grupowaniu przestrzennym. Dla ustrukturyzowanych faktur z znanymi pozycjami pól, regionowe OCR z CropRectangle jest czystszym wzorcem niż pełne wyodrębnianie tabeli na stronie:

using IronOcr;

// Target specific table cells by region instead of full-page table detection
var totalAmountRegion = new CropRectangle(400, 600, 200, 30); // x, y, width, height
using var input = new OcrInput();
input.LoadImage("invoice.jpg", totalAmountRegion);

var result = new IronTesseract().Read(input);
Console.WriteLine($"Total: {result.Text}");
C#

Lista kontrolna migracji PaddleSharp OCR

Przed migracją

Przed usunięciem pakietów sprawdź wszystkie odwołania do PaddleSharp w kodzie źródłowym:

# Find all PaddleSharp and PaddleInference usages
grep -rn "Sdcb\.PaddleOCR\|Sdcb\.PaddleInference" --include="*.cs" .

# Find OpenCV usages that will need replacement
grep -rn "OpenCvSharp\|Cv2\.\|using var.*Mat\b" --include="*.cs" .

# Find model path references and configuration
grep -rn "LocalFullModels\|ModelDir\|DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .

# Find backend selection logic
grep -rn "EnableGpu\|EnableMkldnn\|PaddleConfig\|SetCpuMath" --include="*.cs" .

# Find table recognition usages
grep -rn "PaddleOcrTable\|TableModel\|table.*ocr\|ocr.*table" --include="*.cs" .

# Find result region access patterns that need updating
grep -rn "\.Regions\b\|Rect\.Center\|region\.Text" --include="*.cs" .
SHELL

Zrób spis plików modeli na dysku i zanotuj ich ścieżki. Zinwentaryzuj wszystkie docelowe wdrożenia i czy jakiekolwiek mają specyficzne dla GPU lub OpenVINO warunki NuGet w .csproj. Należy zwrócić uwagę na usługi zarejestrowane jako singletony ze względu na koszt konstrukcji PaddleSharp.

Migracja kodu

  1. Usuń wszystkie pakiety NuGet Sdcb.PaddleOCR, Sdcb.PaddleInference, OpenCvSharp4 i OpenCvSharp4.runtime.* ze wszystkich plików projektów.
  2. Zainstaluj pakiet NuGet IronOcr.
  3. Zainstaluj pakiety językowe NuGet dla wymaganych języków (np. IronOcr.Languages.ChineseSimplified).
  4. Dodaj IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; do uruchamiania aplikacji.
  5. Zastąp wszystkie instrukcje using Sdcb.PaddleOCR, using Sdcb.PaddleInference, i using OpenCvSharp z using IronOcr.
  6. Zastąp instancjonowanie i ładowanie modelu PaddleOcrAll z new IronTesseract().
  7. Usuń wszystkie bloki wyboru backendu PaddleConfig (warunki CPU, GPU, OpenVINO).
  8. Zastąp wywołania Cv2.ImRead(path) używając input.LoadImage(path) i OcrInput.
  9. Zastąp operacje przedprzetwarzania OpenCV (CvtColor, GaussianBlur, Threshold, itp.) metodami filtrów OcrInput (Deskew(), DeNoise(), Contrast(), Binarize()).
  10. Zastąp wywołania ocr.Run(mat) z ocr.Read(input).
  11. Zastąp enumerację result.Regions z result.Pages, result.Pages[n].Lines, lub result.Pages[n].Words.
  12. Usuń łańcuchy sortowania .OrderBy(r => r.Rect.Center.Y).ThenBy(r => r.Rect.Center.X) — kolejność czytania jest automatyczna.
  13. Zastąp inicjalizację i parsowanie wyników PaddleOcrTable z ukierunkowaniem na region lub grupowaniem słów za pomocą współrzędnych.
  14. Dodaj result.SaveAsSearchablePdf(path) wszędzie tam, gdzie wymagane jest archiwum przeszukiwalne PDF.
  15. Ponowna ocena rejestracji na cały okres użytkowania usługi: rejestracje singletonów oparte na kosztach konstrukcji PaddleSharp mogą zazwyczaj stać się przejściowe lub ograniczone zakresem.
  16. Usuń pliki modeli z dysku i usuń katalogi modeli z kontekstów kompilacji Docker.
  17. Usuń wszystkie warunkowe bloki .csproj dla specyficznych dla platformy Paddle lub OpenCV pakietów uruchomieniowych.

Po migracji

  • Sprawdź, czy wyniki ekstrakcji tekstu są zgodne z wynikami PaddleSharp lub je przewyższają na reprezentatywnej próbie 20–30 dokumentów z każdego typu dokumentu w potoku.
  • Potwierdź brak żadnych wyjątków ładowania zestawów związanych z OpenCvSharp w logach startowych aplikacji.
  • Przetestuj wdrożenie na każdej platformie docelowej (Windows, Linux, Docker) przy użyciu tego samego artefaktu kompilacji — nie powinno być konieczne wybieranie pakietów specyficznych dla danej platformy.
  • Zweryfikuj, że dokumenty, które wcześniej wymagały ręcznego sortowania wyników, produkują poprawnie uporządkowany tekst przez result.Text.
  • Sprawdź, czy pliki wyjściowe w formacie PDF z możliwością wyszukiwania umożliwiają wyszukiwanie tekstu w programie Adobe Acrobat Reader lub innej przeglądarce plików PDF.
  • Uruchom aplikację pod obciążeniem, aby potwierdzić, że instancje IronTesseract tworzone per-żądanie nie wywołują presji na pamięć porównywalnej do konstrukcji PaddleOcrAll per-żądanie.
  • Sprawdź, czy pakiety językowe zainstalowane jako pakiety NuGet przywracają się poprawnie w CI bez dodatkowych kroków wdrażania plików.
  • Przetestuj wszystkie scenariusze wyodrębniania tabel pod kątem oczekiwanej struktury wierszy/kolumn, stosując podejście oparte na regionach lub grupowaniu współrzędnych.
  • Potwierdź, że czas uruchamiania aplikacji maleje po wyeliminowaniu konstrukcji singletonu PaddleOcrAll ze ścieżki startowej.

Kluczowe korzyści z migracji do IronOCR

Jeden pakiet zastępuje stos czterech pakietów. Po migracji, ślad zależności OCR to pojedyncze odniesienie NuGet IronOcr. Stos czterech pakietów — Sdcb.PaddleOCR, Sdcb.PaddleInference, OpenCvSharp4 i specyficzne dla platformy środowisko uruchomieniowe — staje się jednym wpisem w pliku projektu. Audyty zależności, skany licencji i monitorowanie podatności pokrywają teraz jedną powierzchnię zamiast czterech.

Artefakty wdrożeniowe są jednolite we wszystkich środowiskach. Warunki wyboru backendu — CPU kontra GPU kontra OpenVINO — zostały usunięte. Ten sam artefakt kompilacji jest wdrażany na laptopie programisty, w środowisku CI, kontenerze Linux oraz maszynie wirtualnej w chmurze bez konieczności dokonywania wyboru pakietów specyficznych dla danego środowiska lub rozgałęzień inicjalizacyjnych. Obrazy Dockera zmniejszają się, ponieważ nie ma plików modeli do COPY i nie ma pakietów środowiska uruchomieniowego do zainstalowania.

Rurociągi archiwizacji dokumentów nie wymagają już drugiej biblioteki. result.SaveAsSearchablePdf() eliminuje zależność od biblioteki PDF, którą większość zespołów PaddleSharp dodała, aby tworzyć przeszukiwalne archiwa. Przeprowadzenie OCR i zapisanie pliku PDF z możliwością wyszukiwania to jedno wywołanie API. Dla zespołów przetwarzających tysiące zeskanowanych dokumentów dziennie to uproszczenie eliminuje całą klasę konfliktów między wersjami bibliotek. Wpis na blogu dotyczący plików PDF z funkcją wyszukiwania omawia kwestie związane ze skalą produkcyjną.

Decyzje dotyczące żywotności usług odzwierciedlają wymagania aplikacji, a nie ograniczenia biblioteki. IronTesseract ma lekką konstrukcję. Wzorzec wymuszonego singletonu, wynikający z kosztownego ładowania modeli przez PaddleSharp, nie jest już konieczny. W .NET Core zakres usług można określać na żądanie, co pozwala na wyraźniejsze oddzielenie współbieżnych użytkowników i eliminuje problemy związane z wątkami o współdzielonym stanie. Więcej informacji na temat opcji wdrażania można znaleźć na stronie poświęconej przypadkom użycia ASP.NET OCR.

Rozszerzenie językowe to instalacja pakietu, a nie projekt badawczy. Katalog ponad 125 języków obejmuje skrypty europejskie, azjatyckie, bliskowschodnie oraz specjalistyczne w postaci pakietów NuGet. Dodanie francuskiego, niemieckiego, arabskiego lub japońskiego do rurociągu, który zaczynał tylko od chińskiego, to dotnet add package IronOcr.Languages.French i jedna linia konfiguracji. Bez źródeł plików modeli, bez badań dostępności w górnym biegu, bez ręcznego wdrażania plików.

Przetwarzanie wstępne jest częścią API OCR. Wiedza o OpenCV, której wymagało przetwarzanie wstępne PaddleSharp — zrozumienie jąder filtrów, zarządzanie usuwaniem Mat, wybór parametrów adaptacyjnego progu — nie jest już warunkiem wstępnym dla pracy OCR. OcrInput zapewnia nazwane operacje z rozsądnymi domyślnymi ustawieniami. Zespoły, które nie były specjalistami w zakresie OpenCV, ale utrzymywały kod przetwarzania wstępnego OpenCV, mogą usunąć ten kod bez konieczności jego zastępowania. Strona poświęcona funkcjom przetwarzania wstępnego zawiera listę wszystkich dostępnych filtrów wraz z dokumentacją dotyczącą tego, kiedy należy je stosować.

Zwróć uwagę: Adobe Acrobat, PaddleOCR, i Tesseract są zarejestrowanymi znakami towarowymi ich właścicieli. Ta strona nie jest powiązana ze strony Adobe Inc., Baidu, Google lub PaddlePaddle. 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