IRONSOFTWAREHOME
VIDÉOS

Comment lire les GIF et TIFF multi-trames en C#

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 août 2026

Ce guide guide les développeurs .NET à travers une migration complète de PaddleSharp OCR(Sdcb.PaddleOCR) à IronOCR. Il s'agit de remplacer la gestion des sessions d'inférence, d'éliminer la dépendance au prétraitement OpenCV, de supprimer la logique de sélection du backend pour CPU, GPU et OpenVINO et de migrer les flux de travail de reconnaissance de tableaux. Chaque section fournit un code avant et après, tiré de modèles spécifiques à PaddleSharp qui n'apparaissent pas dans les comparaisons OCR génériques.

Pourquoi migrer depuis PaddleSharp OCR?

PaddleSharp expose un pipeline d'inférence d'apprentissage profond au niveau de la couche application. Cette architecture vous donne accès aux performances du modèle PaddlePaddle, mais exige que votre application gère ce qui relèverait autrement de l'infrastructure. Les difficultés suivantes incitent la plupart des équipes .NET à rechercher des alternatives.

La configuration du backend d'inférence est un code d'application. Choisir entre les backends CPU, GPU et OpenVINO dans PaddleSharp nécessite de construire et configurer des objets PaddleConfig, de sélectionner le bon package NuGet d'exécution native pour la cible de déploiement, et de détourner conditionnellement votre code d'initialisation en fonction du matériel disponible à l'exécution. Cette logique réside dans votre application, pas dans la bibliothèque, et elle se brise lorsque l'environnement cible change.

OpenCV est une dépendance requise pour l'entrée d'images. PaddleSharp ne peut pas accepter directement un chemin de fichier ou un flux. Chaque image passe par l'Cv2.ImRead() d'OpenCV avant de parvenir au moteur OCR. Ceci force OpenCvSharp4 et un package OpenCvSharp4.runtime.* spécifique à la plateforme dans votre graphique de dépendances. La mise à jour d'un environnement d'exécution sans l'autre provoque des défaillances d'exécution difficiles à reproduire dans différents environnements.

La durée de vie de la session d'inférence nécessite une conception explicite. PaddleOcrAll charge trois binaires de modèle depuis le disque lors de la construction. Ce coût — mesurable en centaines de millisecondes — signifie que l'objet ne peut pas être instancié par demande. Les équipes doivent concevoir une stratégie de cycle de vie : singleton, mise en commun ou mise à l'échelle. Dans ASP.NET Core, cela signifie typiquement un service enregistré avec une analyse minutieuse de la sécurité des threads, car PaddleOcrAll partage l'état natif sous-jacent.

La reconnaissance de tableaux nécessite le téléchargement d'un modèle supplémentaire. L'extraction de documents structurés dans PaddleSharp requiert un modèle de reconnaissance de tableaux dédié, en plus du pipeline standard en trois étapes (détection, classification, reconnaissance). Ce modèle constitue un quatrième fichier à télécharger, à versionner et à configurer. Il n'existe pas d'interface API unifiée ; la reconnaissance des tables utilise un chemin de code distinct avec son propre type de résultat.

Aucun fichier PDF consultable en sortie. PaddleSharp génère des chaînes de caractères. Il ne peut pas écrire de fichiers PDF consultables. Les équipes qui ont besoin d'archiver des documents numérisés sous forme de PDF interrogeables doivent intégrer une bibliothèque PDF distincte, gérer cette dépendance supplémentaire et écrire une couche de conversion. Le fossé en matière de format de sortie est total : pas de hOCR, pas de PDF structuré et consultable, pas de superposition de couche de texte.

La chaîne de dépendances en amont n'appartient pas à la communauté .NET . PaddleSharp encapsule le framework d'inférence PaddlePaddle de Baidu. Par le passé, des modifications du format des modèles entre les versions de PaddleOCR ont provoqué des dysfonctionnements au niveau de la couche de liaison .NET . La plupart des suivis de problèmes, de la documentation et des discussions relatives aux versions sont en chinois. Pour une équipe .NET sans locuteurs mandarin assurant le suivi des projets en amont, les changements majeurs surviennent sans prévenir.

Le problème fondamental

La sélection et l'initialisation d'un backend dans PaddleSharp nécessitent un code de configuration qui relève de l'infrastructure, et non de la logique 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: Non backend selection. Non 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 vs PaddleSharp OCR: comparaison des fonctionnalités

Voici une comparaison directe des capacités sur les aspects les plus importants lors de la migration :

FonctionPaddleSharp OCRIronOCR
Packages NuGet requis3 à 4 minimum1
Méthode de saisie d'imagesOpenCV Cv2.ImRead()Chemin direct, flux ou tableau d'octets
Entrée PDF (native)NonOui
PDF protégé par mot de passeNonOui
TIFF multipageVia OpenCVNatif
Sortie PDF consultableNonOui (result.SaveAsSearchablePdf())
Exportation hOCRNonOui
Sélection du backend (CPU/GPU/OpenVINO)Manuel PaddleConfigAutomatique
Pipeline de prétraitementOpérations manuelles OpenCVIntégré (Deskew, DeNoise, Contrast, etc.)
Gestion du cycle de vie des sessions d'inférenceManuel (construction coûteuse)Léger IronTesseract
Modèle de reconnaissance de tableauxTéléchargement et chemin d'accès au code séparésinput.LoadImage() + résultat structuré
Langues prises en charge~10-20125+
Installation linguistiqueTéléchargement du fichier modèlePaquet NuGet
Multilingue simultanéLimitéOui (OcrLanguage.French + OcrLanguage.German)
OCR basé sur la régionPas de fonctionnalités intégréesCropRectangle
Lecture de codes-barres lors de la reconnaissance optique de caractères (OCR)NonOui (ocr.Configuration.ReadBarCodes = true)
scores de confiancePar régionAu mot, à la ligne, à la page
Hiérarchie de sortie structuréeListe des régions platesPages → Paragraphes → Lignes → WORDs → Caractères
Déploiement multiplateformeComplexe (packages d'exécution de la plateforme)NuGet unique, toutes plateformes
Déploiement de DockerPlusieurs couches, packages d'exécutionUne seule couche
Soutien commercialTickets GitHub (principalement en chinois)Assistance par e-mail
Modèle de licenceApache 2.0Perpetual ($999 Lite, $1,499 Pro, $2,999 Enterprise)

Guide de démarrage rapide : migration de PaddleSharp OCRvers IronOCR

Étape 1 : Remplacer le package NuGet

Supprimer PaddleSharp et sa dépendance OpenCV :

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

Installez IronOCR depuis NuGet :

dotnet add package IronOcr

Étape 2 : Mise à jour des espaces de noms

Remplacer les espaces de noms PaddleSharp par l'espace de noms unique IronOCR :

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

// After (IronOCR)
using IronOcr;
C#

Étape 3 : initialisation de la licence

Ajoutez l'initialisation de la licence une fois au démarrage de l'application — dans Program.cs, Startup.cs ou votre racine de composition :

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

Exemples de migration de code

Remplacement du cycle de vie des sessions d'inférence

L'PaddleOcrAll de PaddleSharp est coûteux à construire car il charge trois binaires de modèle de manière synchrone à l'instanciation. Les applications de production doivent le traiter comme un objet à longue durée de vie, ce qui implique un modèle d'injection de dépendances spécifique. La chaîne de libération nécessite également une attention particulière, car les ressources natives sous-jacentes doivent être libérées dans le bon ordre.

Approche OCR de PaddleSharp :

// 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#

Approche 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#

Le shift d'un singleton forcé à une durée de vie flexible est significatif. Le coût de construction de PaddleSharp détermine votre choix de service pour toute la durée de vie du produit ; IronOCR vous permet de faire votre choix en fonction des besoins de votre application en matière de threading et d'isolation des requêtes. Le guide d'installation d'IronTesseract couvre les options de configuration applicables au niveau de l'instance.

Migration du pipeline de prétraitement OpenCV

Les équipes PaddleSharp traitant des numérisations de mauvaise qualité mettent généralement en place un pipeline de prétraitement OpenCV avant d'invoquer le moteur OCR. Ce pipeline nécessite une connaissance de l'interface API d'OpenCV, qui est nettement plus étendue que ce dont toute tâche de prétraitement OCR a réellement besoin. Les opérations courantes — redressement, réduction du bruit, étirement du contraste — nécessitent plusieurs opérations Mat et une gestion soigneuse de la mémoire avec des blocs using pour éviter les fuites de mémoire natives.

Approche OCR de PaddleSharp :

// 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#

Approche 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#

Aucune allocation Mat. Aucune connaissance des paramètres de seuil adaptatif. Pas de calculs mathématiques personnalisés pour la rotation de redressement. Le même pipeline de prétraitement qui nécessitait 30 à 50 lignes de code OpenCV se résume désormais à quatre appels de méthode. Le guide de correction de la qualité d'image répertorie tous les filtres disponibles avec des exemples avant/après. Pour les documents avec beaucoup de bruit de fond, input.DeepCleanBackgroundNoise() va plus loin que DeNoise() sans aucun paramètre supplémentaire.

Pour les équipes dont les exigences de prétraitement ne sont pas standard, l'assistant de filtrage fournit un outil interactif permettant d'évaluer des combinaisons de filtres sur vos types de documents spécifiques avant de valider le code.

Élimination de la sélection du backend

PaddleSharp expose le backend d'inférence comme une préoccupation au niveau de l'application. Un déploiement devant s'exécuter sur une machine virtuelle cloud équipée uniquement d'un processeur utilise un code d'initialisation différent de celui destiné à une station de travail GPU ou à un périphérique de bord compatible avec Intel OpenVINO. Cette logique conditionnelle se retrouve généralement dans le code de démarrage de l'application, les vérifications des variables d'environnement ou les indicateurs de fonctionnalités — un travail d'infrastructure qui n'a rien à voir avec la lecture de texte à partir d'images.

Approche OCR de PaddleSharp :

// 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#

Approche IronOCR :

using IronOcr;

// Non backend selection. Non switch statement. Non 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#

Le modèle Parallel.ForEach ici est sûr en termes de threads dès le départ. Chaque instance d'IronTesseract est indépendante sans état natif partagé. Pour les équipes dont le déploiement de PaddleSharp nécessite du temps pour gérer les conditions du backend, cette simplification constitue également une amélioration de la fiabilité du déploiement : le même artefact de build s'exécute partout sans code de détection du matériel. Le guide d'optimisation de la vitesse couvre les options de configuration pour les scénarios sensibles au débit.

Migration de la reconnaissance de tableaux

L'extraction de tableaux dans PaddleSharp nécessite un modèle de reconnaissance de tableaux dédié — un quatrième fichier de modèle en plus de l'ensemble standard de détection, de classification et de reconnaissance. Le modèle de table utilise un appel API distinct et renvoie sa propre structure de résultats. Les équipes chargées de la mise en place de pipelines de traitement des factures, des formulaires ou des feuilles de calcul gèrent deux chemins d'initialisation parallèles et deux stratégies d'analyse des résultats.

Approche OCR de PaddleSharp :

// 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#

Approche 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#

Pour les documents dont la structure du tableau doit être extraite sous forme de lignes et de colonnes, IronOCR offre une fonctionnalité dédiée à l'extraction de tableaux :

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#

Un téléchargement de modèle supprimé. Un chemin d'initialisation supprimé. La hiérarchie structurée des résultats dans IronOCR — avec des coordonnées X/Y au niveau des mots — fournit les données de position nécessaires pour reconstruire les lignes et les colonnes d'un tableau sans modèle de reconnaissance distinct. Le guide de lecture du tableau et le guide des résultats de lecture couvrent l'intégralité de l'API de sortie structurée.

Fichiers PDF consultables à partir de documents numérisés

PaddleSharp produit des chaînes de texte et rien d'autre. La création d'une archive de documents permettant la recherche de texte dans des PDF numérisés nécessite l'intégration d'une bibliothèque PDF distincte, l'écriture d'une couche de superposition de texte et la gestion conjointe de ces deux bibliothèques. Les équipes qui ont accepté cette contrainte constatent souvent que c'est ce qui déclenche la migration : l'effort d'intégration des deux bibliothèques dépasse celui nécessaire pour changer de fournisseur d'OCR.

Approche OCR de PaddleSharp :

// 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#

Approche 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#

Pas de bibliothèque PDF. Pas de mappage de coordonnées. Pas de positionnement des calques de texte. Le format de sortie PDF consultable d'IronOCR intègre une couche de texte invisible par-dessus l'image d'origine, produisant ainsi un fichier à la fois fidèle visuellement au document numérisé et entièrement consultable par recherche textuelle. Le guide pratique au format PDF consultable couvre la sélection des pages, les options de qualité et le contrôle des métadonnées.

Référence de mappage de l'API OCR PaddleSharp vers IronOCR

PaddleSharp OCRIronOCR
Sdcb.PaddleOCR (namespace)IronOcr (namespace)
Sdcb.PaddleInference (namespace)Non nécessaire — configuration automatique
PaddleOcrAllIronTesseract
new PaddleOcrAll(det, cls, rec)new IronTesseract()
LocalFullModels.ChineseV3.DetectionModelPas d'équivalent — pas de sélection de modèle
LocalFullModels.ChineseV3.ClassifierModelPas d'équivalent — pas de sélection de modèle
LocalFullModels.ChineseV3.RecognitionModelPas d'équivalent — pas de sélection de modèle
PaddleConfig.FromModelDir()Pas d'équivalent — pas d'objet de configuration
config.EnableGpu(memMB, deviceId)Pas d'équivalent — le backend est automatique
config.EnableMkldnn()Pas d'équivalent — le backend est automatique
config.SetCpuMathLibraryNumThreads(n)Pas d'équivalent — géré en interne
Cv2.ImRead(path) (chargement OpenCV)input.LoadImage(path)
ocr.Run(mat)ocr.Read(input) ou ocr.Read("file.jpg")
result.Regionsresult.Pages[0].Words ou result.Pages[0].Lines
region.Textword.Text, line.Text, paragraph.Text
region.Rect.Center.X/.Yword.X, word.Y
region.Score (confiance)word.Confidence, result.Confidence
Changement de langue au niveau du modèleocr.Language = OcrLanguage.French
Modèle de tableau (téléchargement séparé)Hiérarchie structurée des résultats intégrée
Cv2.CvtColor(..., GRAY)input.Binarize() ou input.Contrast()
Cv2.GaussianBlur(...)input.DeNoise()
Aucun fichier PDF consultableresult.SaveAsSearchablePdf("output.pdf")

Problèmes de migration courants et solutions

Problème n° 1 : la dépendance OpenCV ne se décharge pas

PaddleSharp OCR : OpenCvSharp4.runtime.win et des packages similaires d'exécution spécifiques aux plateformes installent des DLLs natives non gérées. Ces DLL peuvent empêcher un nettoyage correct dans certains scénarios d'hébergement — en particulier le recyclage du pool d'applications IIS — et provoquer des échecs de chargement d'assembly lorsque le mauvais package d'exécution de la plateforme est référencé au moment de la compilation. Leur suppression nécessite à la fois la suppression du package NuGet et l'effacement de tous les binaires natifs mis en cache dans le répertoire de sortie.

Solution : Après avoir supprimé les packages OpenCvSharp4 et OpenCvSharp4.runtime.*, nettoyez le répertoire de sortie de construction avant de reconstruire :

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

IronOCR regroupe ses dépendances natives en interne et gère le cycle de vie non géré. Aucune sélection de package d'exécution spécifique à une plateforme n'est requise. Le guide d'installation d'IronTesseract documente les exigences de la plateforme qu'IronOCR gère automatiquement.

Problème n° 2 : fichiers de modèle restés sur le disque après la migration

PaddleSharp OCR : Les fichiers de modèle téléchargés par PaddleSharp (détection, classification, reconnaissance et modèles de table) sont généralement stockés dans un répertoire models/ relatif à l'application ou dans un chemin configuré. Ces fichiers ne sont pas supprimés lors de la désinstallation du package NuGet. Dans une image Docker, ils ajoutent une taille de couche inutile. Dans un pipeline de déploiement, des fichiers de modèle obsolètes situés dans d'anciens chemins d'accès peuvent provoquer des échecs au démarrage si un code d'initialisation résiduel y fait référence.

Solution : Supprimer explicitement les répertoires de modèles dans le cadre de la migration. Vérifiez la configuration de démarrage pour détecter toute référence de chemin d'accès :

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

Une fois les références au modèle supprimées et IronOCR initialisé, supprimez le répertoire du modèle du référentiel et du contexte de build Docker.

Problème n° 3 : la durée de vie du singleton n'est plus respectée après la migration

PaddleSharp OCR : PaddleOcrAll a été enregistré comme singleton car son coût de construction rendait impraticable l'instanciation par demande. Le code de migration qui intègre IronOCR dans le même enregistrement singleton introduit un partage d'état inutile entre les requêtes. Bien qu'IronTesseract soit sûr en termes de threads lorsqu'il est utilisé de manière concurrente, il n'est pas nécessaire de partager une seule instance — chaque instance est indépendante.

Solution : Évaluez si l'enregistrement du singleton a une utilité autre que la performance. Pour la plupart des applications ASP.NET Core, l'enregistrement transitoire est le choix le plus judicieux avec 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#

Pour les scénarios de traitement par lots à haut débit où vous souhaitez une réutilisation explicite des instances, un modèle singleton ou poolé fonctionne toujours — mais il s'agit d'un choix de performance, et non d'une exigence de correction.

Problème n° 4 : le classement des régions de résultats n'est plus nécessaire

PaddleSharp OCR : result.Regions retourne des régions de texte détectées dans l'ordre de détection, ce qui ne correspond pas nécessairement à l'ordre de lecture (de gauche à droite, de haut en bas). Les équipes appliquent généralement un tri par .Rect.Center.Y puis .Rect.Center.X avant de joindre le texte des régions — un modèle qui apparaît dans presque toutes les implémentations d'extraction de texte de PaddleSharp. La transposition littérale de ce modèle vers IronOCR génère du code redondant.

Solution : IronOCR renvoie les résultats par ordre de lecture par défaut. Supprimer le tri :

// 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#

Problème n° 5 : les paquets conditionnels du backend interrompent la restauration

PaddleSharp OCR : Certains réglages PaddleSharp font référence sous condition à différents packages Sdcb.PaddleInference.runtime.* basés sur l'environnement cible (CUDA pour GPU, MKL pour OpenVINO, uniquement CPU). Cela apparaît parfois comme des conditions .csproj ou comme des fichiers de projet distincts par cible de déploiement. La matrice de build qui en résulte rompt les pipelines CI lorsque le mauvais ensemble de paquets est restauré.

Solution : Après avoir supprimé les packages PaddleSharp, examinez le fichier .csproj pour les blocs PackageReference conditionnels faisant référence à des packages Sdcb.* ou OpenCvSharp* et supprimez-les entièrement :

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

IronOCR utilise une seule référence de package IronOcr sans conditionnel de plateforme. Le même package s'installe correctement sous Windows, Linux et macOS.

Problème n° 6 : la structure des résultats du tableau n'a pas d'équivalent direct

PaddleSharp OCR : PaddleOcrTable renvoie une structure basée sur des cellules avec des indices de ligne et de colonne par cellule reconnue. Le code qui consomme cette structure construit généralement un tableau à deux dimensions indexé par (row, column). IronOCR ne fournit pas une structure d'index de cellules identique — il fournit des coordonnées de mots et de lignes qui nécessitent un regroupement spatial pour reconstruire une grille de cellules.

Solution : Reconstruire la structure du tableau à partir des coordonnées des mots d'IronOCR en utilisant le regroupement par position Y pour les lignes et le tri par position X pour les colonnes. Pour les formats de tableau courants, le guide pratique de lecture des tableaux propose une approche de regroupement spatial. Pour des factures structurées avec des positions de champs connues, l'OCR basé sur des régions avec CropRectangle est un modèle plus propre qu'une extraction de table pleine page :

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#

Liste de contrôle pour la migration vers PaddleSharp OCR

Pré-migration

Vérifiez toutes les références à PaddleSharp dans le code source avant de supprimer les paquets :

# 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

Répertoriez les fichiers modèles sur le disque et notez leurs chemins d'accès. Inventoriez toutes les cibles de déploiement et si certaines ont des conditionnels NuGet spécifiques à GPU ou OpenVINO dans .csproj. Notez que certains services sont enregistrés en tant que singleton en raison du coût de construction de PaddleSharp.

Migration de code

  1. Supprimez tous les packages NuGet Sdcb.PaddleOCR, Sdcb.PaddleInference, OpenCvSharp4 et OpenCvSharp4.runtime.* de chaque fichier de projet.
  2. Installez le package NuGet IronOcr.
  3. Installez les packages NuGet de langue pour les langues requises (par exemple, IronOcr.Languages.ChineseSimplified).
  4. Ajoutez IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; au démarrage de l'application.
  5. Remplacez toutes les déclarations using Sdcb.PaddleOCR, using Sdcb.PaddleInference et using OpenCvSharp par using IronOcr.
  6. Remplacez l'instanciation PaddleOcrAll et le chargement du modèle par new IronTesseract().
  7. Supprimez tous les blocs de sélection de backend PaddleConfig (CPU, GPU, conditionnels OpenVINO).
  8. Remplacez les appels Cv2.ImRead(path) par input.LoadImage(path) en utilisant OcrInput.
  9. Remplacez les opérations de prétraitement OpenCV (CvtColor, GaussianBlur, Threshold, etc.) par des méthodes de filtrage OcrInput (Deskew(), DeNoise(), Contrast(), Binarize()).
  10. Remplacez les appels ocr.Run(mat) par ocr.Read(input).
  11. Remplacez l'énumération result.Regions par result.Pages, result.Pages[n].Lines ou result.Pages[n].Words.
  12. Retirez les chaînes de tri .OrderBy(r => r.Rect.Center.Y).ThenBy(r => r.Rect.Center.X) — l'ordre de lecture est automatique.
  13. Remplacez l'initialisation PaddleOcrTable et l'analyse des résultats par le ciblage basé sur les régions OcrInput ou le regroupement de mots basé sur les coordonnées.
  14. Ajoutez result.SaveAsSearchablePdf(path) partout où une archive PDF recherchable est requise.
  15. Réévaluer les enregistrements de durée de vie des services : les enregistrements singleton pilotés par le coût de construction de PaddleSharp peuvent généralement devenir transitoires ou limités à une portée.
  16. Supprimez les fichiers de modèle du disque et retirez les répertoires de modèle des contextes de build Docker.
  17. Supprimez tous les blocs conditionnels .csproj pour les packages d'exécution Paddle ou OpenCV spécifiques à la plateforme.

Après la migration

  • Vérifiez que les résultats de l'extraction de texte égalent ou dépassent ceux de PaddleSharp sur un échantillon représentatif de 20 à 30 documents de chaque type de document dans le pipeline.
  • Confirmez qu'il n'y a pas d'exceptions de chargement d'assemblage liées à OpenCvSharp dans les journaux de démarrage de l'application.
  • Testez le déploiement sur chaque plateforme cible (Windows, Linux, Docker) en utilisant le même artefact de build — aucune sélection de package spécifique à la plateforme ne devrait être nécessaire.
  • Vérifiez que les documents nécessitant précédemment un tri manuel des résultats produisent un texte correctement ordonné via result.Text.
  • Vérifiez que les fichiers PDF générés sont consultables dans Adobe Acrobat Reader ou dans le lecteur PDF de votre choix.
  • Exécutez l'application sous charge pour confirmer que les instances IronTesseract créées par demande ne produisent pas de pression mémoire comparable à la construction PaddleOcrAll par demande.
  • Vérifiez que les packs de langues installés sous forme de paquets NuGet se restaurent correctement en CI sans étapes de déploiement de fichiers supplémentaires.
  • Testez tous les scénarios d'extraction de tableaux par rapport à la structure attendue des lignes et des colonnes en utilisant l'approche par région ou par regroupement de coordonnées.
  • Confirmez que le temps de démarrage de l'application diminue après avoir éliminé la construction PaddleOcrAll singleton du chemin de démarrage.

Principaux avantages de la migration vers IronOCR

Un package remplace une pile de quatre packages. Après la migration, l'empreinte de dépendance de l'OCR est une seule référence NuGet IronOcr. La pile de quatre packages — Sdcb.PaddleOCR, Sdcb.PaddleInference, OpenCvSharp4 et un runtime spécifique à la plateforme — devient une seule entrée dans le fichier de projet. Les audits de dépendance, les analyses de licence et la surveillance des vulnérabilités couvrent désormais une seule surface au lieu de quatre.

Les artefacts de déploiement sont uniformes dans tous les environnements. Les conditions de sélection du backend — CPU, GPU ou OpenVINO — ont disparu. Le même artefact de build se déploie sur un ordinateur portable de développeur, un exécuteur CI, un conteneur Linux et une machine virtuelle cloud sans sélection de paquets spécifique à l'environnement ni branchement d'initialisation. Les images Docker se réduisent car il n'y a pas de fichiers de modèle à COPY et aucun package d'exécution de plateforme à installer.

Les pipelines d'archives de documents ne nécessitent plus une seconde bibliothèque. result.SaveAsSearchablePdf() élimine la dépendance à la bibliothèque PDF que la plupart des équipes PaddleSharp avaient ajoutée pour produire des archives recherchables. Le passage en OCR et l'écriture au format PDF consultable constituent un seul appel d'API. Pour les équipes traitant des milliers de documents numérisés par jour, cette simplification élimine toute une catégorie de conflits de versions entre bibliothèques. L'article de blog sur les PDF consultables aborde les considérations relatives à l'échelle de production.

Les décisions sur la durée de vie du service reflètent les besoins de l'application, et non les contraintes de la bibliothèque. IronTesseract a une construction légère. Le modèle singleton forcé induit par le chargement coûteux des modèles de PaddleSharp n'est plus nécessaire. Les services peuvent être délimités par requête dans .NET Core, ce qui permet une isolation plus nette entre les utilisateurs simultanés et élimine les problèmes liés au threading en état partagé. Pour en savoir plus sur les options de déploiement, consultez la page des cas d'utilisation d'ASP.NET OCR.

L'extension linguistique est une installation de package, pas un projet de recherche. Le catalogue de plus de 125 langues couvre les scripts européens, asiatiques, du Moyen-Orient et spécialisés sous forme de packages NuGet. Ajouter le français, l'allemand, l'arabe ou le japonais à un pipeline qui a commencé uniquement en chinois est dotnet add package IronOcr.Languages.French et une ligne de configuration. Pas de recherche de fichiers de modèle, pas de recherche de disponibilité en amont, pas de déploiement manuel de fichiers.

Le prétraitement fait partie de l'API OCR. Les connaissances OpenCV que le prétraitement de PaddleSharp nécessitait — comprendre les noyaux de filtre, gérer l'élimination Mat, sélectionner les paramètres de seuil adaptatif — ne sont plus une condition préalable pour le travail d'OCR. OcrInput fournit des opérations nommées avec des valeurs par défaut raisonnables. Les équipes qui n'étaient pas spécialisées dans OpenCV mais qui maintenaient du code de prétraitement OpenCV peuvent supprimer ce code sans le remplacer. La page des fonctionnalités de prétraitement répertorie tous les filtres disponibles, accompagnés d'une documentation indiquant quand les appliquer.

Veuillez noter: Adobe Acrobat, PaddleOCR et Tesseract sont des marques déposées de leurs propriétaires respectifs. Ce site n'est pas affilié, approuvé ou sponsorisé par Adobe Inc., Baidu, Google ou PaddlePaddle. Tous les noms de produits, logos et marques sont la propriété de leurs propriétaires respectifs. Les comparaisons sont à titre informatif uniquement et reflètent les informations publiquement disponibles au moment de l'écriture.

Articles connexes

Key in blue circle

Obtenez votre clé d'essai de 30 jours instantanément.

Your trial license will be sent to your email address

Aucune restriction. 100 % débloqué. Pas de carte bancaire.

bullet_checkedAucune carte de crédit ou création de compte requiseAucune restriction. 100 % débloqué. Pas de carte bancaire.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Obtenez Votre Consultation sans Engagement
Remplissez le formulaire ci-dessous ou envoyez un email à sales@ironsoftware.com
Vos informations seront toujours gardées confidentielles.
De confiance par des millions d'ingénieurs dans le monde entier
Logos des clients d'Iron Software
Obtenez votre clé d'essai 30 jours gratuitement.
Aucune carte de crédit ou création de compte requise