Migration de XImage.OCR vers IronOCR
Ce guide s'adresse aux développeurs .NET qui migrent une intégration XImage.OCR existante vers IronOCR. Elle couvre le processus de consolidation des paquets, les modifications apportées aux espaces de noms et aux API, ainsi que des exemples concrets de migration de code pour les scénarios où l'architecture fragmentée de XImage.OCR crée le plus de friction. Aucune lecture préalable de l'article comparatif n'est requise.
Pourquoi migrer depuis XImage.OCR OCR
XImage.OCR est un wrapper commercial de Tesseract proposé par RasterEdge qui répartit ses fonctionnalités sur une chaîne de paquets NuGet coordonnés. L'architecture fonctionne à petite échelle, mais engendre des coûts de maintenance croissants à mesure que les applications se développent.
Le nombre de paquets augmente avec chaque langue. Ajouter une langue signifie ajouter un paquet NuGet. Une application en cinq langues transporte six packages dans son .csproj. Une application en dix langues en vaut onze. Chaque paquet doit être épinglé à la même version que le noyau — une contrainte qui entraîne des échecs d'exécution silencieux lorsqu'un développeur met à jour seulement une partie de la chaîne. IronOCR propose un seul package pour plus de 125 langues.
La synchronisation des versions est un risque constant. Les dotnet outdated mettent à jour les packages avidement. Lorsque RasterEdge.XImage.OCR avance à 12.5.0 mais que XImage.OCR.Language.French reste à 12.4.0, l'erreur apparaît à l'exécution, pas à la compilation, et le message indique rarement la synchronisation des versions comme cause. Les équipes utilisant des pipelines CI/CD apprennent à ajouter un verrouillage de version explicite pour chaque paquet XImage.OCR — une charge supplémentaire qui ne sert à rien d'autre qu'à compenser la fragmentation du modèle.
Aucun prétraitement intégré ne limite la précision sur les documents réels. XImage.OCR transmet les images directement au moteur Tesseract sous-jacent. Un scan à 150 DPI avec deux degrés d'inclinaison est transmis à Tesseract sans modification. Le niveau de précision maximal pour ce type de données est de 60 à 75 %, quel que soit le wrapper Tesseract utilisé. IronOCR fournit un pipeline de pré-traitement — Deskew(), DeNoise(), Contrast(), Binarize(), Sharpen() — qui corrige ces problèmes avant que la reconnaissance ne s'exécute.
Le format structuré nécessite un analyseur syntaxique manuel. XImage.OCR renvoie une chaîne de caractères simple. L'extraction des positions des mots, des limites de ligne ou du niveau de confiance par mot nécessite d'analyser vous-même cette chaîne. IronOCR renvoie un objet OcrResult avec Pages, Paragraphs, Lines, Words, et les données par caractère avec des coordonnées de pixels et des scores de confiance intégrés.
Les formats de sortie se limitent au texte brut. La création d'un PDF consultable à partir d'un résultat XImage.OCR nécessite le SDK PDF RasterEdge — un deuxième achat commercial. IronOCR produit des PDF recherchables via result.SaveAsSearchablePdf() sans dépendances supplémentaires.
Le déploiement multiplateforme n'est pas pris en charge. XImage.OCR est destiné à Windows. Les conteneurs Linux, les environnements de développement macOS et les déploiements cloud natifs sur Azure ou AWS nécessitent une bibliothèque différente. IronOCR fonctionne sous Windows, Linux, macOS, Docker, Azure App Service et AWS Lambda à partir du même package.
Le problème fondamental
XImage.OCR nécessite un package NuGet par langue. Dix langues signifient onze packages, tous version verrouillée les uns aux autres :
<!-- XImage.OCR: 11 packages to support 10 languages — every version must match -->
<PackageReference Include="RasterEdge.XImage.OCR" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.English" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.German" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.French" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Spanish" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Italian" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Portuguese" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.ChineseSimplified" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Japanese" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Korean" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Arabic" Version="12.4.0" />
IronOCR remplace l'ensemble du bloc par une seule ligne :
<!-- IronOCR: One package. 125+ languages. Non version coordination. -->
<PackageReference Include="IronOcr" Version="2024.x.x" />
IronOCR vs XImage.OCR : comparaison des fonctionnalités
Le tableau ci-dessous présente les fonctionnalités les plus pertinentes pour la décision de migration.
| Fonction | XImage.OCR | IronOCR |
|---|---|---|
| Packages NuGet en anglais uniquement | 2 (base + pack linguistique) | 1 |
| Packages NuGet pour 10 langues | 11 | 1 |
| Synchronisation des versions requise | Oui — tous les paquets doivent correspondre | Non |
| Langues disponibles | ~15 sous forme de paquets distincts | Plus de 125 outils inclus |
| Prétraitement intégré | None | Redresser, réduire le bruit, contraster, binariser, accentuer, mettre à l'échelle, dilater, éroder, inverser |
| Suppression approfondie du bruit | None | Oui (DeepCleanBackgroundNoise()) |
| Entrée PDF native | Nécessite le SDK PDF de RasterEdge | Oui (input.LoadPdf()) |
| Sortie PDF consultable | Nécessite le SDK PDF de RasterEdge | Oui (result.SaveAsSearchablePdf()) |
| Fichier TIFF multipages en entrée | Limité | Oui (input.LoadImageFrames()) |
| Entrée de tableau d'octets | Manuel via MemoryStream | Oui (input.LoadImage(bytes)) |
| Entrée du flux | Manuel | Oui (input.LoadImage(stream)) |
| Sortie structurée | Chaîne de caractères simple | Pages, paragraphes, lignes, mots, caractères avec leurs coordonnées |
| Scores de confiance par mot | Non disponible | Oui |
| Lecture de codes-barres | Non disponible | Oui (ocr.Configuration.ReadBarCodes = true) |
| Exportation hOCR | Non disponible | Oui |
| Sécurité des threads | Non compatible avec les fils | Sécurité totale des threads |
| Modèle de mémoire (parallèle) | Une instance de gestionnaire par thread | Instance unique partagée |
| Multiplateforme | Windows principalement | Windows, Linux, macOS, Docker, Azure, AWS |
| Compatibilité .NET | .NET Standard 2.0, .NET Framework 4.5+ | .NET Framework 4.6.2+, .NET Core, .NET 5/6/7/8/9 |
| Type de licence | Commercial (RasterEdge) | Perpétuelle (Lite $999, Pro 1 499 $, Enterprise 2 999 $) |
| soutien commercial | Assistance RasterEdge | Oui, par niveau de licence |
Guide de démarrage rapide : migration de XImage.OCR vers IronOCR
Étape 1 : Remplacer les paquets NuGet
Supprimez tous les paquets XImage.OCR. Le nombre de commandes correspond au nombre de packs de langues que vous avez installés :
dotnet remove package RasterEdge.XImage.OCR
dotnet remove package XImage.OCR.Language.English
dotnet remove package XImage.OCR.Language.German
dotnet remove package XImage.OCR.Language.French
# Repeat for every language pack in your project
Installez IronOCR depuis NuGet :
Étape 2 : Mise à jour des espaces de noms
Remplacer les importations de l'espace de noms RasterEdge par l'espace de noms unique IronOCR :
// Before (XImage.OCR)
using RasterEdge.XImage.OCR;
using RasterEdge.Imaging.Basic;
// After (IronOCR)
using IronOcr;
Étape 3 : initialisation de la licence
Ajouter l'initialisation de la licence une fois au démarrage de l'application, avant tout appel OCR :
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"Stockez la clé dans une variable d'environnement ou un gestionnaire de secrets plutôt que de l'intégrer en dur :
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");Imports System
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")Exemples de migration de code
Consolidation de l'initialisation multi-packages
La première tâche de migration consiste à regrouper le bloc d'initialisation de XImage.OCR — activation de la licence, création du gestionnaire et attribution de la langue basée sur des chaînes de caractères — dans l'équivalent IronOCR.
Approche XImage.OCR :
// Requires: RasterEdge.XImage.OCR + one XImage.OCR.Language.* package per language
// Language strings must exactly match installed package names or OCR fails at runtime
RasterEdge.XImage.OCR.License.LicenseManager.SetLicense("your-ximage-license-key");
var ocrHandler = new OCRHandler();
// String codes — typo "enh" instead of "eng" silently fails or throws at runtime
ocrHandler.Languages = new[] { "eng", "deu", "fra", "spa", "ita" };
// Process returns a plain string — no structure, no confidence
string extractedText = ocrHandler.Process("document.png");
Console.WriteLine(extractedText);
Approche IronOCR :
// Requires: IronOcr (single package — all languages included)
IronOcr.License.LicenseKey = "YOUR-IRONOCR-LICENSE-KEY";
var ocr = new IronTesseract();
// Type-safe enum — compiler catches typos, no runtime surprises
ocr.Language = OcrLanguage.English + OcrLanguage.German +
OcrLanguage.French + OcrLanguage.Spanish + OcrLanguage.Italian;
using var input = new OcrInput();
input.LoadImage("document.png");
var result = ocr.Read(input);
Console.WriteLine(result.Text);
Console.WriteLine($"Confidence: {result.Confidence}%");
Les codes de langue basés sur des chaînes dans XImage.OCR ("eng", "deu") échouent à l'exécution lorsque le package NuGet correspondant est absent ou à la mauvaise version. L'énum OcrLanguage dans IronOCR rend impossible la compilation de combinaisons de langues invalides. Le guide de configuration de IronTesseract couvre les options de configuration de l'engine, et le guide des langues multiples documente comment les combinaisons de langues primaires et secondaires fonctionnent pour les documents multilingues.
Unification de la gestion des formats d'image
XImage.OCR traite chaque source d'image différemment en fonction du format. Les tableaux d'octets, les flux et les chemins d'accès aux fichiers nécessitent chacun des chemins de code légèrement différents. IronOCR les accepte tous à travers les mêmes méthodes OcrInput.
Approche XImage.OCR :
// XImage.OCR: different handling per image source type
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
// File path — works directly
string resultFromFile = ocrHandler.Process("invoice.jpg");
// Byte array — must write to temp file first, then process
byte[] imageBytes = File.ReadAllBytes("invoice.jpg");
string tempPath = Path.GetTempFileName() + ".jpg";
File.WriteAllBytes(tempPath, imageBytes);
try
{
string resultFromBytes = ocrHandler.Process(tempPath);
Console.WriteLine(resultFromBytes);
}
finally
{
File.Delete(tempPath); // Manuel cleanup — easy to forget
}
// Multi-page TIFF — must split frames manually
// Non built-in TIFF frame iteration in base XImage.OCR
Approche IronOCR :
// IronOCR: unified OcrInput accepts all source types identically
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
// File path
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg");
var result = ocr.Read(input);
Console.WriteLine($"From file: {result.Text}");
}
// Byte array — no temp file needed
byte[] imageBytes = File.ReadAllBytes("invoice.jpg");
using (var input = new OcrInput())
{
input.LoadImage(imageBytes);
var result = ocr.Read(input);
Console.WriteLine($"From bytes: {result.Text}");
}
// Multi-page TIFF — all frames processed in one call
using (var input = new OcrInput())
{
input.LoadImageFrames("scanned-archive.tiff");
var result = ocr.Read(input);
Console.WriteLine($"TIFF pages: {result.Pages.Count}");
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
}
Le modèle de fichier temporaire pour les tableaux d'octets dans XImage.OCR est une source courante de surchargement du disque et de fuites de fichiers dans les chemins d'erreur. Le LoadImage(byte[]) d'IronOCR élimine entièrement le fichier intermédiaire. Le guide d'entrée d'images et le guide d'entrée TIFF/GIF couvrent tous les types de sources pris en charge, y compris les flux et le traitement multi-images.
Optimisation du format de sortie
XImage.OCR renvoie une chaîne de caractères simple. La génération d'un PDF consultable nécessite un deuxième produit RasterEdge. IronOCR génère du texte brut, des PDF consultables et des données structurées à partir du même objet de résultat, sans aucun package supplémentaire.
Approche XImage.OCR :
// XImage.OCR: plain text output only
// Searchable PDF requires purchasing the RasterEdge PDF SDK separately
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
string plainText = ocrHandler.Process("scanned-contract.jpg");
// To produce a searchable PDF from this text, you would need:
// 1. Purchase RasterEdge PDF SDK (separate commercial license)
// 2. Create a PDF document programmatically
// 3. Embed the extracted text as invisible text layer over the image
// 4. Manage the PDF document lifecycle manually
// Non built-in path from OCR result to searchable PDF in XImage.OCR alone
Console.WriteLine(plainText);
Approche IronOCR :
// IronOCR: plain text, searchable PDF, and structured data from one result
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("scanned-contract.jpg");
var result = ocr.Read(input);
// Plain text
Console.WriteLine(result.Text);
// Searchable PDF — no extra package required
result.SaveAsSearchablePdf("searchable-contract.pdf");
// Structured data: paragraphs with bounding box coordinates
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}");
}
}
// Per-word confidence for quality gating
var lowConfidenceWords = result.Pages
.SelectMany(p => p.Words)
.Where(w => w.Confidence < 70)
.ToList();
Console.WriteLine($"Words below 70% confidence: {lowConfidenceWords.Count}");
L'appel SaveAsSearchablePdf() intègre le texte reconnu comme une couche cachée sous l'image originale, rendant le document entièrement accessible à la recherche textuelle sans altérer son apparence visuelle. Le guide pratique au format PDF consultable couvre les options de plage de pages et les paramètres de résolution (DPI). Pour les modèles d'extraction de données structurées, le guide de lecture des résultats documente toute la hiérarchie OcrResult incluant les coordonnées de mots et l'accès aux niveaux de confiance. L'exemple de PDF consultable fournit une implémentation fonctionnelle complète.
Traitement par lots de documents
XImage.OCR n'est pas thread-safe. Chaque thread de travail concurrent doit créer sa propre instance OCRHandler, multipliant la consommation de mémoire par le nombre de threads. IronOCR utilise une instance unique partagée entre tous les threads.
Approche XImage.OCR :
// XImage.OCR: one handler per thread — memory multiplies with concurrency
// 4 threads processing English documents: 4 x ~100MB = ~400MB for OCR alone
// 4 threads processing 5 languages: 4 x ~250MB = ~1GB just for OCR handlers
var results = new ConcurrentDictionary<string, string>();
string[] documentPaths = Directory.GetFiles("./incoming", "*.png");
Parallel.ForEach(documentPaths,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
documentPath =>
{
// Each thread must create and dispose its own handler
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
try
{
string text = ocrHandler.Process(documentPath);
results[documentPath] = text;
}
finally
{
// Manuel disposal required — no using statement support shown
ocrHandler.Dispose();
}
});
foreach (var kvp in results)
Console.WriteLine($"{Path.GetFileName(kvp.Key)}: {kvp.Value.Length} chars");
Approche IronOCR :
// IronOCR: single IronTesseract instance shared across all threads
// Memory stays flat regardless of thread count
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract(); // Create once outside the parallel loop
var results = new ConcurrentDictionary<string, string>();
string[] documentPaths = Directory.GetFiles("./incoming", "*.png");
Parallel.ForEach(documentPaths, documentPath =>
{
// OcrInput is created per thread — IronTesseract instance is shared
using var input = new OcrInput();
input.LoadImage(documentPath);
input.Deskew(); // Preprocessing runs per-document, not per-thread engine
input.DeNoise();
var result = ocr.Read(input);
results[documentPath] = result.Text;
});
foreach (var kvp in results)
Console.WriteLine($"{Path.GetFileName(kvp.Key)}: {kvp.Value.Length} chars");
Le modèle de gestionnaire par thread de XImage.OCR signifie qu'un travail par lots à quatre threads chargeant cinq langues occupe environ 1 Go de mémoire de gestionnaire OCR avant de traiter un seul document. L'instance partagée d'IronOCR limite l'utilisation de la mémoire à l'empreinte d'une seule instance, quel que soit le niveau de parallélisme. L'exemple de multithreading illustre le modèle dans son intégralité, et le guide d'optimisation de la vitesse couvre le réglage de la configuration pour les charges de travail par lots axées sur le débit.
Extraction combinée de BarCode et de texte
XImage.OCR ne dispose pas de fonctionnalité de lecture de BarCodes. Les documents contenant à la fois du texte et des BarCodes nécessitent deux bibliothèques distinctes et deux passes distinctes. IronOCR extrait les deux en une seule opération de lecture.
Approche XImage.OCR :
// XImage.OCR: text only — barcodes require a separate library and second pass
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
// Pass 1: text extraction with XImage.OCR
string documentText = ocrHandler.Process("warehouse-label.png");
Console.WriteLine($"Text: {documentText}");
// Pass 2: barcode reading requires a completely separate library
// e.g., ZXing.Net, Dynamsoft Barcode Reader, or another commercial SDK
// - Additional NuGet package required
// - Additional license required
// - Additional code for result merging
// Non combined text + barcode result object exists in XImage.OCR
Approche IronOCR :
// IronOCR: text and barcodes from a single Read() call
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
ocr.Configuration.ReadBarCodes = true; // Enable barcode extraction
using var input = new OcrInput();
input.LoadImage("warehouse-label.png");
var result = ocr.Read(input);
// Text and barcodes in one result object
Console.WriteLine($"Document text:\n{result.Text}");
if (result.Barcodes.Any())
{
Console.WriteLine($"\nBarcodes found: {result.Barcodes.Count}");
foreach (var barcode in result.Barcodes)
Console.WriteLine($" [{barcode.BarcodeType}] {barcode.Value}");
}
Définir ReadBarCodes = true ajoute la détection de codes-barres au passage de reconnaissance sans nécessiter une deuxième bibliothèque ou une deuxième lecture. Le guide pratique sur la lecture des codes-barres et l'exemple d'OCR de codes-barres couvrent les formats de codes-barres pris en charge et les options de configuration pour les documents à contenu mixte.
Référence de mappage de l'API XImage.OCR vers IronOCR
| XImage.OCR | Équivalent d'IronOCR |
|---|---|
new OCRHandler() | new IronTesseract() |
RasterEdge.XImage.OCR.License.LicenseManager.SetLicense("key") | IronOcr.License.LicenseKey = "key" |
ocrHandler.Language = "eng" | ocr.Language = OcrLanguage.English |
ocrHandler.Languages = new[] { "eng", "deu" } | ocr.Language = OcrLanguage.English + OcrLanguage.German |
ocrHandler.Process(imagePath) | ocr.Read(input).Text (après input.LoadImage(path)) |
ocrHandler.Process(image) (de l'objet) | input.LoadImage(bytes) ou input.LoadImage(stream) |
ocrHandler.ProcessRegion(path, rect) | input.LoadImage(path, new CropRectangle(x, y, w, h)) |
ocrHandler.SetVariable("tessedit_char_whitelist", "0-9") | ocr.Configuration.WhiteListCharacters = "0123456789" |
result (chaîne simple) | result.Text |
result.MeanConfidence | result.Confidence |
| Aucun équivalent | result.Pages / result.Paragraphs / result.Lines |
| Aucun équivalent | result.Words (avec .X, .Y, .Confidence) |
| Aucun équivalent | result.SaveAsSearchablePdf("output.pdf") |
| Aucun équivalent | input.Deskew() |
| Aucun équivalent | input.DeNoise() |
| Aucun équivalent | input.Contrast() |
| Aucun équivalent | input.Binarize() |
| Aucun équivalent | input.Sharpen() |
| Aucun équivalent | input.LoadImageFrames("file.tiff") (multi-cadre) |
| Nécessite le SDK PDF de RasterEdge | input.LoadPdf(pdfPath) |
| Nécessite le SDK PDF de RasterEdge | result.SaveAsSearchablePdf("output.pdf") |
| Non disponible | ocr.Configuration.ReadBarCodes = true |
Instances OCRHandler par thread | Instance partagée unique IronTesseract |
Problèmes de migration courants et solutions
Problème n° 1 : Échecs d'exécution après une mise à jour partielle du package
XImage.OCR : Exécuter dotnet outdated ou dotnet restore avec un cache de packages obsolète peut faire avancer RasterEdge.XImage.OCR vers une nouvelle version tout en laissant les packs de langues à la version précédente. L'échec se produit lors de l'exécution, lors du premier appel OCR, avec un message d'erreur qui n'identifie pas clairement la non-correspondance de version comme cause première. Trouver la divergence nécessite de vérifier manuellement toutes les entrées PackageReference.
Solution : après avoir supprimé les paquets XImage.OCR et installé IronOCR, il n'y a plus de synchronisation des versions à gérer. Le package unique IronOcr transporte tout. Si vous avez besoin de packs de langues au-delà des valeurs par défaut intégrées, installez indépendamment les packages IronOcr.Languages.* — ils n'ont pas besoin de correspondance de version avec le noyau :
Problème n° 2 : les codes de langue dans les chaînes de caractères provoquent des échecs silencieux de l'OCR
XImage.OCR : Les codes de langue sont des chaînes ("eng", "deu", "fra"). Une faute de frappe dans un code de langue — "engg", "ger" au lieu de "deu" — retombe soit silencieusement sur une langue par défaut ou lance une exception d'exécution selon la version de XImage.OCR. Aucun de ces résultats n'est détecté lors de la compilation.
Solution : IronOCR utilise l'énum OcrLanguage. Les valeurs non valides sont des erreurs de compilation, pas des surprises à l'exécution. Migrer les tableaux de chaînes vers des expressions énumérées :
// Before (XImage.OCR) — typos compile fine, fail at runtime
ocrHandler.Languages = new[] { "eng", "deu", "fra" };
// After (IronOCR) — typos are compile errors
ocr.Language = OcrLanguage.English + OcrLanguage.German + OcrLanguage.French;
Consultez le guide sur les langues multiples pour savoir comment combiner les langues principales et secondaires dans des documents contenant du contenu multilingue.
Problème n° 3 : fichiers temporaires laissés sur le disque suite au traitement des tableaux d'octets
XImage.OCR : Le traitement d'images à partir de tableaux d'octets nécessite l'écriture d'un fichier temporaire car OCRHandler.Process() accepte un chemin de fichier, pas un tampon. Les chemins d'exception qui sautent le bloc finally laissent ces fichiers temporaires sur le disque. Dans les applications à haut débit, cela s'accumule rapidement.
Solution: OcrInput.LoadImage() accepts byte[] directly. Aucun fichier temporaire n'est créé :
// Before (XImage.OCR) — temp file required
string tempPath = Path.GetTempFileName() + ".png";
File.WriteAllBytes(tempPath, imageBytes);
try { text = ocrHandler.Process(tempPath); }
finally { File.Delete(tempPath); }
// After (IronOCR) — direct byte array loading, no disk I/O
using var input = new OcrInput();
input.LoadImage(imageBytes);
var result = ocr.Read(input);
string text = result.Text;
Problème n° 4 : épuisement de la mémoire sous charge parallèle
XImage.OCR : Le traitement en parallèle nécessite un OCRHandler par thread. Huit threads traitant des documents en cinq langues chargent huit instances distinctes du moteur, chacune contenant les cinq packs de langues. Avec environ 50 Mo par langue et par instance, huit threads consomment à eux seuls environ 2 Go de mémoire du moteur OCR avant même que les données des documents n'entrent en jeu.
Solution : Une seule instance IronTesseract gère tous les threads. Créez un OcrInput par document (il est jetable et léger), réutilisez IronTesseract pendant toute la durée de l'application :
// Single instance — shared safely across all threads
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English + OcrLanguage.German +
OcrLanguage.French + OcrLanguage.Spanish + OcrLanguage.Italian;
Parallel.ForEach(documentPaths, path =>
{
using var input = new OcrInput(); // Per-document, lightweight
input.LoadImage(path);
var result = ocr.Read(input); // Thread-safe call on shared instance
ProcessResult(result.Text);
});
Problème n° 5 : le pipeline CI/CD se bloque après une restauration partielle
XImage.OCR : un agent CI/CD doté d'un cache de paquets préchauffé contient souvent des packs de langues OCR mis en cache dans une ancienne version. Lorsque seul le package principal a été mis à jour dans le fichier de projet, la restauration aboutit mais le runtime charge des assemblages non correspondants. La compilation réussit ; le déploiement échoue.
Solution : après la migration vers IronOCR, le pipeline CI/CD restaure un paquet. Ajoutez une étape de validation pour vérifier que la version attendue est bien présente :
# In your CI pipeline — verify single package restore
dotnet restore
dotnet list package | grep IronOcr
# Non version coordination logic needed — only one package to check
Problème n° 6 : données structurées manquantes pour l'analyse en aval
XImage.OCR : Renvoie une chaîne de caractères simple. Les applications qui ont besoin de connaître la position des WORDs, le regroupement des lignes ou le niveau de confiance par WORD doivent analyser la chaîne à l'aide d'heuristiques basées sur les espaces ou d'une logique personnalisée. La précision de cette analyse se dégrade sur les documents comportant des mises en page à plusieurs colonnes, des tableaux ou du texte pivoté.
Solution : L'OcrResult d'IronOCR expose directement toute la hiérarchie du document. Aucune analyse de chaînes de caractères n'est nécessaire :
var result = ocr.Read(input);
// Direct access to structured data — no string manipulation
foreach (var page in result.Pages)
{
foreach (var line in page.Lines)
{
// Line text, bounding box, and per-word data all available
Console.WriteLine($"Line [{line.X},{line.Y}]: {line.Text}");
foreach (var word in line.Words)
Console.WriteLine($" Word '{word.Text}' confidence: {word.Confidence}%");
}
}
Pour l'API complète des données structurées, consultez le guide pratique sur les résultats de lecture et la page des fonctionnalités des résultats OCR.
Liste de contrôle pour la migration vers XImage.OCR
Pré-migration
Vérifiez le code source pour identifier tous les points de contact XImage.OCR avant d'apporter des modifications :
# Find all XImage.OCR namespace imports
grep -r "RasterEdge.XImage.OCR\|Yiigo.Image.Ocr\|XImage.OCR" --include="*.cs" .
# Find all OCRHandler usages
grep -r "OCRHandler\|ocrHandler" --include="*.cs" .
# Find all string-based language assignments
grep -r "\.Language\s*=\s*\"" --include="*.cs" .
grep -r "\.Languages\s*=\s*new\[\]" --include="*.cs" .
# Find all XImage.OCR package references in project files
grep -r "RasterEdge.XImage.OCR\|XImage.OCR.Language" --include="*.csproj" .
# Count distinct language packs installed
grep "XImage.OCR.Language" --include="*.csproj" -r . | wc -l
Notez les types de sources d'images utilisés (chemins d'accès aux fichiers, tableaux d'octets, flux, TIFF) et identifiez tous les emplacements qui utilisent des fichiers temporaires pour le traitement des tableaux d'octets. Il s'agit de cibles de nettoyage hautement prioritaires.
Migration de code
- Supprimez toutes les références de packages
RasterEdge.XImage.OCRetXImage.OCR.Language.*de chaque fichier.csproj - Ajoutez la référence de package
IronOcr(dotnet add package IronOcr) - Remplacez
using RasterEdge.XImage.OCRparusing IronOcrdans tous les fichiers - Ajoutez
IronOcr.License.LicenseKey = ...au démarrage de l'application (une fois par processus) - Remplacez
new OCRHandler()parnew IronTesseract() - Remplacez les assignations de langues de chaînes (
"eng","deu") par les valeurs d'énumOcrLanguage - Remplacez
ocrHandler.Process(path)parinput.LoadImage(path)+ocr.Read(input).Text - Remplacez les motifs de tableau d'octets vers fichier temporaire par
input.LoadImage(byte[]) - Remplacez la division manuelle de cadres TIFF multi-pages par
input.LoadImageFrames("file.tiff") - Supprimez l'instanciation
OCRHandlerpar thread des bouclesParallel.ForEach— utilisez une instance partagée uniqueIronTesseract - Ajoutez des appels de prétraitement (
input.Deskew(),input.DeNoise()) après chaqueLoadImage()pour les documents provenant de sources de qualité variable - Remplacez la gestion des résultats de chaînes simples par
result.Textpour le texte ouresult.SaveAsSearchablePdf()pour la sortie PDF - Remplacez
ocrHandler.SetVariable("tessedit_char_whitelist", ...)parocr.Configuration.WhiteListCharacters = ... - Mettez à jour le pipeline CI/CD : supprimez les étapes de restauration multi-packages, supprimez la logique de synchronisation des versions, vérifiez la restauration d'un package unique
IronOcr
Après la migration
- Vérifiez que l'extraction de texte de base produit un résultat correct à partir d'une image de test dont la qualité est confirmée
- Vérifier que les documents multilingues renvoient du texte pour toutes les langues configurées
- Tester que les chemins d'entrée de tableaux d'octets produisent un résultat correct sans création de fichiers temporaires sur le disque
- Confirmez que les documents TIFF multi-pages renvoient le compte de pages correct dans
result.Pages - Exécutez un traitement par lots en parallèle sous charge et mesurez la mémoire maximale — celle-ci devrait être nettement inférieure à la référence XImage.OCR
- Vérifiez que le fichier PDF généré s'ouvre correctement dans Adobe Acrobat ou un lecteur de PDF et que le texte est sélectionnable
- Testez le prétraitement sur un scan de mauvaise qualité ou déformé et comparez la précision du texte extrait par rapport à la référence XImage.OCR
- Vérifiez que l'initialisation de la clé de licence s'exécute avant le premier appel OCR et ne génère pas d'exception
- Vérifiez que la restauration CI/CD réussit dans un environnement propre, sans paquets mis en cache
- Vérifiez que la sortie de données structurées (
result.Words,result.Paragraphs) correspond à la mise en page de document attendue
Principaux avantages de la migration vers IronOCR
Un package unique remplace tout un graphe de dépendances. Chaque package XImage.OCR.Language.*, le package noyau RasterEdge.XImage.OCR, et la surcharge de synchronisation de version entre eux s'effondrent en une seule commande dotnet add package IronOcr. Le nombre d'entrées .csproj passe de onze à un. L'étape de restauration CI/CD passe d'une opération multi-paquets comportant onze points de défaillance indépendants à une restauration à partir d'un seul paquet. Cette simplification a des effets cumulés : moins de paquets à auditer pour détecter les failles de sécurité, moins d'entrées à mettre à jour lorsque la compatibilité .NET change, et aucune logique de coordination des versions à maintenir dans les pipelines de mise à jour automatisés. La page produit IronOCR et le centre de documentation fournissent la référence complète des fonctionnalités et du déploiement.
Les améliorations en matière de précision du prétraitement sont immédiates. La migration n'est pas un simple remplacement à l'identique, mais une mise à niveau de la précision. Tout document traité par XImage.OCR avec une précision dégradée en raison de biais, de bruit ou de basse résolution dispose désormais d'un chemin direct d'amélioration via input.Deskew(), input.DeNoise() et input.Contrast(). Pas de bibliothèque externe de traitement d'images, pas d'expertise en traitement d'images au sein de l'équipe de développement, pas de dépendance distincte à licencier et à maintenir. Ajouter trois lignes après LoadImage() récupère 20 à 35 points de pourcentage de précision sur les documents numérisés qui étaient auparavant acceptés comme "suffisamment bons". Le guide de correction de qualité d'image et la page des fonctionnalités de prétraitement couvrent l'effet de chaque filtre sur différents scénarios de qualité de document.
Les PDF consultables et les données structurées éliminent les coûts liés à un deuxième SDK. Les deux demandes les plus courantes des utilisateurs de XImage.OCR — la sortie de PDF consultables et les données au niveau des mots avec coordonnées — nécessitent toutes deux des produits RasterEdge supplémentaires qui impliquent des licences commerciales distinctes. Après la migration, result.SaveAsSearchablePdf() produit des documents recherchables de qualité archivage sans packages supplémentaires, et result.Words fournissent des données structurées avec des boîtes englobantes et des scores de confiance. La fonctionnalité qui nécessitait auparavant deux licences est désormais disponible avec une seule. La documentation complète sur le format de sortie se trouve sur la page des fonctionnalités des résultats OCR .
Le traitement parallèle évolue sans pénalités de mémoire. Le modèle de gestion par thread de XImage.OCR rend la mise à l'échelle coûteuse. Doubler le nombre de threads double la mémoire consommée par les instances du moteur OCR. Le modèle d'instance partagée d'IronOCR signifie que la mémoire reste limitée à l'empreinte d'une seule instance, quel que soit le parallélisme. Un serveur traitant des lots de documents avec huit threads simultanés consomme la même mémoire pour le moteur OCR qu'un serveur traitant un document à la fois. Cela se traduit directement par des coûts d'hébergement réduits et une capacité de débit accrue sur une infrastructure fixe.
Le déploiement multiplateforme s'ouvre sans modifications de code. Le même package IronOcr et le même code d'application s'exécutent sur Windows, Linux, macOS, Docker, Azure App Service et AWS Lambda. Aucun code conditionnel à la plateforme, aucune variante de package spécifique à la plateforme, aucun test de déploiement par environnement de la couche OCR. Les équipes qui conteneurisent leurs charges de travail, exécutent des environnements de développement macOS ou déploient sur une infrastructure cloud basée sur Linux bénéficient d'une compatibilité immédiate. Les guides de déploiement Docker , Azure et Linux documentent la configuration pour chaque environnement cible.
Plus de 125 langues disponibles : la couverture linguistique est désormais illimitée. XImage.OCR ne propose qu'une quinzaine de langues dans ses offres commerciales. Les distributions standard de tessdata incluent plus de 100 langues sans frais. IronOCR regroupe plus de 125 langues et les expose via des packages IronOcr.Languages.* optionnels qui suivent un modèle d'installation propre sans la contrainte de verrouillage de version. Les 24 langues officielles de l'UE, toutes les principales langues CJK, l'arabe, l'hébreu et les systèmes d'écriture spécialisés sont tous disponibles. L' index des langues répertorie toutes les langues prises en charge avec le nom du paquet correspondant.
