Comment extraire du texte arabe à partir d'images à l'aide d'outils OCR
Ce guide accompagne les développeurs .NET tout au long d'une migration complète de GdPicture .NET OCR vers IronOCR . Il couvre l'échange de packages, les modifications d'espace de noms et les modèles de code pratiques avant/après pour chaque flux de travail OCR majeur, en mettant l'accent sur l'élimination du cycle de vie de l'identifiant d'image entier qui définit le modèle de gestion des ressources de GdPicture. Aucune lecture préalable de l'article comparatif n'est requise.
Pourquoi migrer depuis GdPicture .NET ?
GdPicture .NET est une plateforme d'imagerie documentaire conçue pour les équipes ayant besoin d'une intégration de scanner, de la prise en charge DICOM, de l'édition de PDF, de l'annotation et de la reconnaissance optique de caractères (OCR) auprès d'un fournisseur unique. Lorsque la reconnaissance optique de caractères (OCR) est la seule exigence, la tarification et l'architecture API de la plateforme créent des frictions qui s'accumulent au fil du temps.
Coût des plugins pour un flux de travail OCR de base. L'extraction de texte à partir de PDF numérisés et la production d'un résultat interrogeable nécessitent trois licences distinctes : le kit de développement logiciel (SDK) principal à environ 4 000 $, le plugin OCR à environ 2 000 $ et le plugin PDF à environ 2 000 $. Cela représente un coût initial de 8 000 $, Plus 20 % de frais de maintenance annuels. Les équipes qui n'ont besoin que de la reconnaissance optique de caractères (OCR) absorbent l'intégralité de la structure tarifaire d'une plateforme d'imagerie documentaire. IronOCR couvre le même flux de travail — OCR d'image, OCR de PDF, prétraitement, sortie PDF interrogeable — depuis un seul package à $999 jusqu'à 2 999 $ perpétuels, sans décisions de licence par fonctionnalité. Consultez la page des licences IronOCR pour obtenir le détail complet des différents niveaux.
Le cycle de vie de l'ID image entier. Chaque image chargée via GdPicture retourne un int. Vous transmettez cet entier aux opérations OCR, puis appelez ReleaseGdPictureImage avec celui-ci lorsque terminé. Ce schéma précède IDisposable. Cela fonctionne si on suit les instructions correctement ; Cela provoque une fuite de mémoire en cas d'échec. Dans les services de production traitant des centaines de documents par jour, un seul appel de libération manqué sur une branche d'erreur entraîne une augmentation de la consommation de mémoire véritablement difficile à diagnostiquer. Le OcrInput d'IronOCR implémente IDisposable — une déclaration using élimine toute la charge de nettoyage.
Espace de noms spécifique à la version. GdPicture intègre le numéro de version majeure dans son espace de noms : using GdPicture14. La mise à niveau vers la prochaine version majeure nécessite la mise à jour de cette directive using dans chaque fichier source qui fait référence aux classes GdPicture. Une application de grande envergure avec une reconnaissance optique de caractères (OCR) répartie sur des dizaines de services transforme cette tâche de recherche et de remplacement en une opération de plusieurs heures sans aucune amélioration fonctionnelle. L'espace de noms d'IronOCR a été IronOcr à travers toutes les versions majeures.
Exigence de dossier de ressources externes. L'OCR de GdPicture nécessite une propriété ResourceFolder pointant vers un répertoire de fichiers de langue .traineddata à l'exécution. Ce chemin fonctionne sur une machine de développement, puis casse sur les serveurs Linux, les conteneurs Docker, et les déploiements de Azure App Service où la structure du répertoire n'existe pas. IronOCR regroupe la prise en charge de la langue anglaise dans le package NuGet; Les langues supplémentaires s'installent sous forme de packages NuGet qui sont inclus dans le résultat de la compilation.
Initialisation à trois composants. Un flux de travail OCR de PDF dans GdPicture nécessite d'instancier GdPictureImaging, GdPictureOCR, et GdPicturePDF — trois composants distincts avec des exigences de suppression individuelles — plus l'enregistrement du gestionnaire de licence et l'affectation du dossier de ressources. IronOCR nécessite une ligne au démarrage et une classe lors de l'appel.
Aucune sécurité multithread native. Les instances OCR de GdPicture ne sont pas compatibles avec le multithreading. Le traitement parallèle des documents nécessite une gestion et une synchronisation rigoureuses des instances afin d'éviter toute corruption d'état. IronOCR est conçu pour une utilisation simultanée : créez un IronTesseract par thread, ou partagez une seule instance sous charge — chaque schéma fonctionne sans code de synchronisation supplémentaire.
Le problème fondamental
GdPicture alloue de la mémoire pour chaque image sous forme de descripteur entier géré à l'exécution. Chaque appel RenderPageToGdPictureImage dans une boucle de traitement TIFF crée une nouvelle allocation qui doit être libérée manuellement :
// GdPicture: every frame = new integer ID = manual release required
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("multi-page.tiff", false);
var frameIds = new List<int>();
try
{
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
int frameId = pdf.RenderPageToGdPictureImage(200, false); // new allocation
if (frameId != 0) frameIds.Add(frameId);
// ... OCR call here ...
}
}
finally
{
foreach (var id in frameIds) _imaging.ReleaseGdPictureImage(id); // manual per-frame release
}
IronOCR élimine complètement le cycle de vie. OcrInput gère l'énumération et le nettoyage des frames :
// IronOCR: the using statement handles everything
using var input = new OcrInput();
input.LoadImageFrames("multi-page.tiff");
var result = new IronTesseract().Read(input);
IronOCR vs GdPicture .NET: Comparaison des fonctionnalités
Le tableau ci-dessous compare les fonctionnalités des deux bibliothèques pour les flux de travail axés sur la reconnaissance optique de caractères (OCR).
| Fonction | GdPicture.NET | IronOCR |
|---|---|---|
| Installation | Plusieurs packages NuGet | dotnet add package IronOcr |
| Activation de la licence | LicenseManager.RegisterKEY() | IronOcr.License.LicenseKey = "..." |
| Espace de noms lors de la mise à niveau majeure | Nécessite de trouver-remplacer (GdPicture14 → suivant) | Inchangé (IronOcr) |
| Initialisation des composants | GdPictureImaging + GdPictureOCR + GdPicturePDF | new IronTesseract() |
| Modèle de mémoire de ressources | Suivi et publication manuels des identifiants numériques | IDisposable / using statement |
| risque de fuite de mémoire | Élevée (manquant ReleaseGdPictureImage) | Aucun (imposé par le compilateur via using) |
| dossier de ressources externes | Requis (_ocr.ResourceFolder = path) | Non requis — inclus dans l'emballage |
| OCR d'image | Oui | Oui |
| OCR PDF | Oui (plugin PDF requis) | Intégré, aucune licence supplémentaire |
| TIFF multipage | Boucle d'images manuelle + nettoyage des ID par image | input.LoadImageFrames() |
| Entrée du flux | Via GdPictureImaging surcharge de flux | input.LoadImage(stream) |
| Sortie PDF consultable | pdf.OcrPage() + pdf.SaveToFile() | result.SaveAsSearchablePdf() |
| Prétraitement de la correction de la courbure | Module d'imagerie de documents requis | input.Deskew() — intégré |
| suppression du bruit | Module d'imagerie de documents requis | input.DeNoise() — intégré |
| Langues | Fichiers de données entraînées basés sur Tesseract dans le dossier | Plus de 125 packages NuGet |
| OCR multilingue | Oui | OcrLanguage.French + OcrLanguage.German |
| Sécurité des threads | Gestion manuelle des instances | Sécurité des threads dès la conception |
| OCR asynchrone | Non intégré | ReadAsync() |
| Lecture de codes-barres | Module de code-barres séparé | ocr.Configuration.ReadBarCodes = true |
| Sortie structurée | Accès par bloc/ligne/mot basé sur l'index | Typé .Pages, .Words, .Characters |
| Score de confiance | GetOCRResultConfidence(resultId) | result.Confidence |
| Multiplateforme | Windows, Linux, macOS | Windows, Linux, macOS, Docker, AWS, Azure |
| Coût d'entrée (OCR à partir de PDF) | Environ 8 000 $ (modules de base + OCR + plugins PDF) | $999–2 999 $ |
| Modèle de tarification | Licence perpétuelle basée sur un plugin + 20 %/an de maintenance | Forfait perpétuel, mises à jour annuelles facultatives |
| soutien commercial | Oui | Oui |
Démarrage rapide : Migration de GdPicture .NET vers IronOCR
Étape 1 : Remplacer le package NuGet
Supprimez les paquets GdPicture :
dotnet remove package GdPicture.NET
dotnet remove package GdPicture.NET.OCR
dotnet remove package GdPicture.NET.PDF
Installez IronOCR depuis la page du package NuGet :
Pour les langues autres que l'anglais, installez le pack de langue correspondant :
Étape 2 : Mise à jour des espaces de noms
Remplacez l'espace de noms GdPicture par l'espace de noms IronOCR :
// Before (GdPicture)
using GdPicture14;
// After (IronOCR)
using IronOcr;
Étape 3 : initialisation de la licence
Placez cette ligne dans Program.cs ou Startup.cs, avant tout appel OCR :
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"Supprimez complètement le bloc d'enregistrement de licence GdPicture :
// Remove this
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
Une clé d'essai gratuite est disponible sur la page produit IronOCR pour évaluer le produit avant l'achat.
Exemples de migration de code
Traitement d'images TIFF multipages
Le traitement des fichiers TIFF multipages dans GdPicture nécessite la sélection de chaque image via l'API PDF/imagerie, son rendu en un nouvel identifiant d'image, l'exécution de la reconnaissance optique de caractères (OCR) et la libération de l'identifiant. Un seul cadre qui n'est pas libéré dans le bloc finally fuit entre 10 et 50 Mo selon le DPI.
Approche GdPicture .NET :
using GdPicture14;
public class GdPictureTiffProcessor
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public string ExtractTextFromTiff(string tiffPath)
{
var text = new StringBuilder();
// Load TIFF through the imaging component
int tiffId = _imaging.CreateGdPictureImageFromFile(tiffPath);
if (tiffId == 0)
throw new Exception($"TIFF load failed: {_imaging.GetStat()}");
// Outer try: release the original TIFF handle
try
{
int frameCount = _imaging.GetPageCount(tiffId);
for (int i = 1; i <= frameCount; i++)
{
// Switch to frame — modifies the existing ID in place
_imaging.SelectPage(tiffId, i);
// Clone frame to a new image ID for OCR
int frameId = _imaging.CloneImage(tiffId);
if (frameId == 0) continue;
// Inner try: release each cloned frame ID
try
{
_ocr.SetImage(frameId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (!string.IsNullOrEmpty(resultId))
{
text.AppendLine($"[Frame {i}] {_ocr.GetOCRResultText(resultId)}");
}
}
finally
{
// Release cloned frame — critical for each iteration
_imaging.ReleaseGdPictureImage(frameId);
}
}
}
finally
{
// Release original TIFF handle
_imaging.ReleaseGdPictureImage(tiffId);
}
return text.ToString();
}
}
Approche IronOCR :
using IronOcr;
public class IronOcrTiffProcessor
{
public string ExtractTextFromTiff(string tiffPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // all frames loaded, all cleanup automatic
var result = new IronTesseract().Read(input);
// Per-frame text is available on result.Pages
foreach (var page in result.Pages)
Console.WriteLine($"[Frame {page.PageNumber}] {page.Text}");
return result.Text;
}
}
LoadImageFrames charge chaque cadre d'un TIFF multipages dans le pipeline OcrInput. Le bloc using gère toute la mémoire associée à chaque cadre en fin de portée. Aucun List<int> à maintenir, pas de blocs try/finally imbriqués requis. Le guide d'entrée TIFF et GIF couvre en détail la sélection des images et la gestion multiformat.
Initialisation du plugin de remplacement d'entrée basé sur le flux
Les applications serveur reçoivent fréquemment des documents sous forme de flux plutôt que de chemins de fichiers, provenant de téléchargements HTTP, de files d'attente de messages ou de données binaires de base de données. GdPicture nécessite le chargement du flux via GdPictureImaging, qui lui-même nécessite la séquence d'initialisation du composant et la configuration du dossier de ressources qui précèdent chaque opération.
Approche GdPicture .NET :
using GdPicture14;
public class GdPictureStreamOcr : IDisposable
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public GdPictureStreamOcr()
{
// Plugin initialization required before stream loading is possible
var lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR"; // path must exist at runtime
}
public string ExtractTextFromStream(Stream documentStream)
{
// Load stream into imaging component to get an image ID
int imageId = _imaging.CreateGdPictureImageFromStream(documentStream);
if (imageId == 0)
throw new Exception($"Stream load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
}
public void Dispose()
{
_ocr?.Dispose();
_imaging?.Dispose();
}
}
Approche IronOCR :
using IronOcr;
public class IronOcrStreamOcr
{
public string ExtractTextFromStream(Stream documentStream)
{
using var input = new OcrInput();
input.LoadImage(documentStream); // stream accepted directly — no imaging component
return new IronTesseract().Read(input).Text;
}
}
L'approche GdPicture nécessite la construction de trois objets et la configuration d'un chemin d'accès au système de fichiers avant que le premier flux puisse être consommé. IronOCR accepte le flux directement sur OcrInput sans configuration préalable. Le guide d'entrée des flux couvre les tableaux d'octets, MemoryStream, et les modèles FileStream pour les architectures de pipeline où les écritures de fichiers temporaires sont indésirables.
OCR asynchrone remplaçant l'interrogation du code d'état
La reconnaissance optique de caractères (OCR) de GdPicture est synchrone. Les applications qui traitent des documents dans les points de terminaison ASP.NET Core ou les services d'arrière-plan doivent envelopper RunOCR dans Task.Run pour éviter de bloquer les threads de requête — et ensuite gérer le cycle de vie de l'ID image à travers la limite du thread. IronOCR offre un support asynchrone de premier ordre via ReadAsync.
Approche GdPicture .NET :
using GdPicture14;
using System.Threading.Tasks;
public class GdPictureAsyncWrapper
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);
public async Task<string> ExtractTextAsync(string imagePath)
{
// Must acquire lock: GdPictureOCR is not thread-safe
await _lock.WaitAsync();
try
{
return await Task.Run(() =>
{
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
throw new Exception($"Load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
});
}
finally
{
_lock.Release();
}
}
}
Approche IronOCR :
using IronOcr;
public class IronOcrAsyncService
{
private readonly IronTesseract _ocr = new IronTesseract();
public async Task<string> ExtractTextAsync(string imagePath)
{
// ReadAsync is natively async — no Task.Run wrapper, no lock required
var result = await _ocr.ReadAsync(imagePath);
return result.Text;
}
public async Task<string> ExtractFromStreamAsync(Stream stream)
{
using var input = new OcrInput();
input.LoadImage(stream);
var result = await _ocr.ReadAsync(input);
return result.Text;
}
}
L'approche GdPicture requiert un SemaphoreSlim pour sérialiser l'accès à l'instance partagée GdPictureOCR, plus un Task.Run pour déplacer le travail de blocage synchrone du thread appelant, plus le cycle de vie complet de l'ID image à l'intérieur de ce lambda. Le ReadAsync d'IronOCR est vraiment non-bloquant et thread-safe. Le guide OCR asynchrone traite de l'intégration avec les intergiciels ASP.NET Core et les services d'arrière-plan hébergés.
Traitement par lots parallèle avec sécurité des fils
Le traitement le plus rapide possible d'un dossier de documents numérisés nécessite une exécution parallèle. GdPicture nécessite une instance GdPictureOCR par thread — partager une seule instance entraîne des échecs non déterministes. Chaque instance par thread nécessite également son propre composant GdPictureImaging et la configuration du dossier de ressources, rendant les approches avec pool de threads impraticables sans un modèle de fabrique.
Approche GdPicture .NET :
using GdPicture14;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class GdPictureParallelBatch
{
private readonly string _resourceFolder = @"C:\GdPicture\Resources\OCR";
public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// Each thread must have its own component instances
Parallel.ForEach(imagePaths, imagePath =>
{
// Create per-thread instances — shared instances cause failures
using var threadImaging = new GdPictureImaging();
using var threadOcr = new GdPictureOCR();
threadOcr.ResourceFolder = _resourceFolder;
// Re-register license per thread (may be required depending on SDK version)
var lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
int imageId = threadImaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
{
results[imagePath] = $"ERROR: {threadImaging.GetStat()}";
return;
}
try
{
threadOcr.SetImage(imageId);
threadOcr.Language = "eng";
string resultId = threadOcr.RunOCR();
results[imagePath] = string.IsNullOrEmpty(resultId)
? $"ERROR: {threadOcr.GetStat()}"
: threadOcr.GetOCRResultText(resultId);
}
finally
{
threadImaging.ReleaseGdPictureImage(imageId);
}
});
return results;
}
}
Approche IronOCR :
using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class IronOcrParallelBatch
{
public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// IronTesseract is thread-safe — one instance handles all threads
var ocr = new IronTesseract();
Parallel.ForEach(imagePaths, imagePath =>
{
try
{
results[imagePath] = ocr.Read(imagePath).Text;
}
catch (Exception ex)
{
results[imagePath] = $"ERROR: {ex.Message}";
}
});
return results;
}
}
L'implémentation parallèle de GdPicture crée trois objets par thread et nécessite un enregistrement de licence par thread. IronOCR gère les lectures concurrentes à partir d'une seule instance IronTesseract sans surcharge de synchronisation. L'exemple de multithreading démontre des benchmarks de débit et des schémas Parallel.ForEach pour les charges de travail de traitement de documents à haut volume.
Saisie de tableaux d'octets et extraction de paragraphes structurés
Les applications qui récupèrent des documents à partir de bases de données ou de systèmes de stockage d'objets fonctionnent souvent avec des tableaux d'octets plutôt qu'avec des chemins de fichiers. GdPicture nécessite la conversion du tableau d'octets en un flux et son chargement via GdPictureImaging. L'extraction de données structurées au niveau du paragraphe à partir du résultat nécessite de naviguer dans la hiérarchie d'index des blocs/lignes.
Approche GdPicture .NET :
using GdPicture14;
public class GdPictureByteArrayOcr
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
{
var paragraphs = new List<string>();
// Byte array must go through MemoryStream to reach CreateGdPictureImageFromStream
using var ms = new MemoryStream(imageBytes);
int imageId = _imaging.CreateGdPictureImageFromStream(ms);
if (imageId == 0)
throw new Exception($"Byte array load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
// Paragraph-level data requires iterating block structure
int blockCount = _ocr.GetOCRResultBlockCount(resultId);
for (int b = 0; b < blockCount; b++)
{
var blockText = new StringBuilder();
int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);
for (int l = 0; l < lineCount; l++)
{
int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);
for (int w = 0; w < wordCount; w++)
{
blockText.Append(_ocr.GetOCRResultBlockLineWordText(resultId, b, l, w));
blockText.Append(" ");
}
}
string text = blockText.ToString().Trim();
if (!string.IsNullOrEmpty(text))
paragraphs.Add(text);
}
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
return paragraphs;
}
}
Approche IronOCR :
using IronOcr;
public class IronOcrByteArrayOcr
{
public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
{
using var input = new OcrInput();
input.LoadImage(imageBytes); // byte array accepted directly
var result = new IronTesseract().Read(input);
// Paragraphs are a first-class typed collection
return result.Paragraphs
.Select(p => p.Text)
.Where(t => !string.IsNullOrWhiteSpace(t))
.ToList();
}
}
IronOCR accepte byte[] directement sur LoadImage sans l'intermédiaire MemoryStream. Le résultat expose .Paragraphs comme une collection typée interrogeable LINQ — aucune triple-boucle bloc/ligne/mot requise. Le guide des résultats de lecture couvre l'accès coordonné, le filtrage de confiance et les modèles de sortie structurés pour les flux de travail de traitement des factures et des formulaires. Pour numériser des zones spécifiques d'un document, voir la reconnaissance optique de caractères (OCR) basée sur les régions .
Référence de mappage de l'API .NET de GdPicture vers IronOCR
| GdPicture.NET | Équivalent d'IronOCR |
|---|---|
using GdPicture14; | using IronOcr; |
LicenseManager.RegisterKEY("key") | IronOcr.License.LicenseKey = "key" |
new GdPictureImaging() | Non requis — interne à OcrInput |
new GdPictureOCR() | new IronTesseract() |
new GdPicturePDF() | Non requis — OcrInput.LoadPdf() gère cela |
_ocr.ResourceFolder = path | Non requis — ressources incluses dans NuGet |
imaging.CreateGdPictureImageFromFile(path) | input.LoadImage(path) |
imaging.CreateGdPictureImageFromStream(stream) | input.LoadImage(stream) |
imaging.CreateGdPictureImageFromBytes(bytes) | input.LoadImage(bytes) |
imaging.CloneImage(tiffId) par cadre | input.LoadImageFrames(tiffPath) |
imaging.ReleaseGdPictureImage(imageId) | using var input = new OcrInput() — automatique |
ocr.SetImage(imageId) | Non requis — OcrInput détient l'image |
ocr.Language = "eng" | ocr.Language = OcrLanguage.English |
ocr.RunOCR() → chaîne resultId | ocr.Read(input) → typé OcrResult |
ocr.GetOCRResultText(resultId) | result.Text |
ocr.GetOCRResultConfidence(resultId) | result.Confidence |
ocr.GetOCRResultBlockCount(resultId) | result.Pages[i].Paragraphs.Count |
ocr.GetOCRResultBlockLineWordText(resultId, b, l, w) | result.Words[i].Text |
imaging.GetStat() / ocr.GetStat() | Exceptions .NET Standard |
GdPictureStatus.OK vérifie après chaque appel | Non requis — les exceptions se propagent |
pdf.OcrPage("eng", resourcePath, "", 200) | result.SaveAsSearchablePdf(outputPath) |
pdf.RenderPageToGdPictureImage(200, false) | Non requis — IronOCR effectue le rendu en interne |
pdf.SelectPage(i) | Non requis — toutes les pages sont traitées par défaut |
pdf.GetPageCount() | result.Pages.Count |
Task.Run(() => ocr.RunOCR()) + SemaphoreSlim | await ocr.ReadAsync(input) |
Problèmes de migration courants et solutions
Problème n° 1 : Variables d'identification d'image restantes dans le code après la refactorisation
GdPicture.NET: Le code existant déclare int imageId en haut des méthodes, le suit via try/finally, et le passe à plusieurs appels GdPicture. Après le remplacement des appels GdPicture, ces variables et leurs appels ReleaseGdPictureImage deviennent du code mort orphelin.
Solution : Supprimez l'intégralité du modèle d'identification de l'image. Remplacez la déclaration, le try, le finally, et l'appel de suppression par un bloc using var input = new OcrInput(). Grep pour ReleaseGdPictureImage pour trouver chaque appel de nettoyage qui doit être supprimé :
grep -rn "ReleaseGdPictureImage\|imageId\|resultId" --include="*.cs" .
// Remove all of this
int imageId = _imaging.CreateGdPictureImageFromFile(path);
try
{
_ocr.SetImage(imageId);
string resultId = _ocr.RunOCR();
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
// Replace with
using var input = new OcrInput();
input.LoadImage(path);
return new IronTesseract().Read(input).Text;
Problème 2 : Chemin du dossier de ressources introuvable dans l'environnement déployé
GdPicture.NET: Le chemin défini dans _ocr.ResourceFolder se résout sur la machine de développement mais échoue en production. Les symptômes courants sont des échecs OCR silencieux retournant des résultats vides, ou des erreurs génériques GdPictureStatus qui ne nomment pas le fichier manquant.
Solution : Supprimez entièrement l'assignation ResourceFolder. La prise en charge de l'anglais est intégrée au package NuGet IronOCR . Les langues supplémentaires s'installent sous forme de packages NuGet . Aucun chemin de système de fichiers n'est disponible pour la configuration ou le déploiement :
Problème 3 : La gestion des erreurs GdPictureStatus est remplacée par des exceptions
GdPicture.NET: Chaque opération retourne ou définit une valeur d'énum GdPictureStatus qui doit être vérifiée immédiatement. Le code est dense avec des gardes if (status != GdPictureStatus.OK). Certains codes d'état sont génériques (par ex., Error, InvalidParameter) et nécessitent de consulter la documentation pour déterminer la cause première.
Solution : IronOCR génère des exceptions .NET typées. Remplacez les contrôles d'état par des blocs try/catch. Les standards IOException et FileNotFoundException couvrent les échecs d'entrée ; IronOcr.Exceptions.OcrException couvre les erreurs spécifiques à l'OCR. Consultez le guide d'installation d'IronTesseract pour connaître les modèles de gestion des erreurs recommandés :
try
{
var result = new IronTesseract().Read(imagePath);
return result.Text;
}
catch (FileNotFoundException ex)
{
_logger.LogError("Input file missing: {Path}", ex.FileName);
throw;
}
catch (IronOcr.Exceptions.OcrException ex)
{
_logger.LogError("OCR processing failed: {Message}", ex.Message);
throw;
}
Problème 4 : Espace de noms GdPicture14 dans plusieurs fichiers
GdPicture.NET: Le numéro de version dans l'espace de noms signifie qu'une directive using GdPicture14; à l'échelle du projet existe dans des dizaines de fichiers. Après la migration, ceux-ci doivent tous être remplacés par using IronOcr;.
Solution : Utilisez une recherche et remplacement global dans tous les fichiers .cs, puis vérifiez qu'aucune référence GdPicture ne subsiste :
# Find all files with GdPicture namespace
grep -rln "using GdPicture" --include="*.cs" .
# After replacing, verify nothing remains
grep -rn "GdPicture14\|GdPictureOCR\|GdPictureImaging\|GdPicturePDF" --include="*.cs" .
Problème 5 : Logique de comptage des images TIFF
GdPicture.NET: Le code qui itère les frames TIFF mélange souvent les appels entre GdPictureImaging.GetPageCount(imageId) et GdPicturePDF.GetPageCount() selon la façon dont le fichier a été chargé. L'index des trames commence à 1.
Solution : input.LoadImageFrames(path) gère automatiquement tous les frames. Si votre code existant ne traite que des frames spécifiques, utilisez input.LoadImageFrames(path, frameNumbers) avec un tableau d'index à partir de zéro. Accédez aux résultats par cadre via result.Pages, qui est également indexé à partir de zéro. Le guide d'entrée TIFF documente explicitement le comportement de l'index.
Problème n° 6 : Le prétraitement nécessite le plugin d'imagerie de documents
GdPicture.NET: Les opérations de redressement et de suppression de taches appartiennent au plugin GdPictureDocumentImaging, qui nécessite un achat de licence supplémentaire. Les équipes qui n'ont pas utilisé le plugin rencontrent souvent des problèmes de précision de reconnaissance optique de caractères (OCR) sur les documents numérisés dont les pages sont déformées ou présentent des artefacts.
Solution : Les méthodes de prétraitement IronOCR font partie du package de base. Ajoutez Deskew() et DeNoise() directement sur OcrInput. Le guide de correction de la qualité d'image couvre tous les filtres disponibles, y compris Contrast(), Sharpen(), Binarize(), et DeepCleanBackgroundNoise() pour les scans sévèrement dégradés :
using var input = new OcrInput();
input.LoadImage("scanned-document.tiff");
input.Deskew(); // no separate plugin license
input.DeNoise();
input.Contrast();
var result = new IronTesseract().Read(input);
Liste de contrôle de migration GdPicture .NET
Pré-migration
Avant d'apporter des modifications, auditez le code source afin de localiser toutes les dépendances de GdPicture :
# Find all GdPicture namespace imports
grep -rn "using GdPicture" --include="*.cs" .
# Find all image ID creation points
grep -rn "CreateGdPictureImageFromFile\|CreateGdPictureImageFromStream\|RenderPageToGdPictureImage\|CloneImage" --include="*.cs" .
# Find all release calls — these map to using block boundaries
grep -rn "ReleaseGdPictureImage" --include="*.cs" .
# Find all resource folder assignments
grep -rn "ResourceFolder" --include="*.cs" .
# Find all OCR result ID accesses
grep -rn "RunOCR\|GetOCRResult\|resultId" --include="*.cs" .
# Find all GdPictureStatus checks
grep -rn "GdPictureStatus\|GetStat()" --include="*.cs" .
# Count GdPicture-dependent files
grep -rln "GdPicture14" --include="*.cs" . | wc -l
Documentez les éléments suivants avant de modifier le code :
- Quels fichiers contiennent des références
GdPictureImaging,GdPictureOCR, etGdPicturePDFCombien existe-t-il de paires distinctes d'identifiants de création/publication d'images ? - Si le plugin d'imagerie de documents (redressement, débruitage) est utilisé
- Quels fichiers de langue
traineddatasont dans le dossier de ressources - Quels scripts de déploiement ou fichiers Docker font référence au chemin du dossier de ressources
Migration de code
- Supprimez tous les packages NuGet GdPicture du fichier projet.
- Installez
IronOcrvia NuGet - Installez des packages
IronOcr.Languages.*pour chaque langue précédemment dans le dossier de ressources - Ajoutez
IronOcr.License.LicenseKey = "..."àProgram.csouStartup.cs - Supprimez l'appel
LicenseManager.RegisterKEY()et l'objet du gestionnaire de licence - Supprimez toutes les déclarations de champ
GdPictureImaginget l'initialisation du constructeur - Supprimez toutes les déclarations de champ
GdPictureOCRet l'assignationResourceFolder - Supprimez toutes les déclarations de champ
GdPicturePDFutilisées pour les flux de travail OCR - Replace each
int imageId = _imaging.CreateGdPictureImage*(...)block with `using var input = new OcrInput(); input.Load*(...) - Remplacez chaque
_ocr.SetImage(imageId); _ocr.Language = "..."; string resultId = _ocr.RunOCR();withvar result = new IronTesseract().Read(input); - Remplacez
_ocr.GetOCRResultText(resultId)parresult.Text - Supprimez tous les appels
_imaging.ReleaseGdPictureImage(imageId) - Remplacez les vérifications
GdPictureStatuspar des blocs try/catch - Remplacez les boucles de cadres TIFF par
input.LoadImageFrames(path) - Remplacez
pdf.OcrPage(...)+pdf.SaveToFile(...)parresult.SaveAsSearchablePdf(outputPath) - Supprimez le chemin d'accès au dossier de ressources des scripts de déploiement et des images Docker.
- Mettez à jour
using GdPicture14;versusing IronOcr;dans tous les fichiers concernés
Après la migration
Après avoir effectué toutes les modifications de code, vérifiez les points suivants avant le déploiement en production :
- L'OCR d'image unique retourne le texte attendu sans
NullReferenceExceptiondes composants supprimés - Le traitement multipages TIFF couvre tous les frames et produit du texte par page via
result.Pages - La reconnaissance optique de caractères (OCR) des fichiers PDF traite toutes les pages sans augmentation de la mémoire nécessaire pour un lot de plus de 50 documents.
- L'entrée de flux accepte
MemoryStreametFileStreamsans écritures de fichiers intermédiaires - La reconnaissance optique de caractères asynchrone s'intègre aux gestionnaires de requêtes ASP.NET Core sans bloquer le pool de threads.
- Le traitement par lots parallèle avec
Parallel.ForEachproduit des résultats précis sur tous les threads - Tous les modules linguistiques (français, allemand, etc.) s'activent correctement via les packages NuGet
- Les filtres de prétraitement (redressement, débruitage) améliorent la précision des documents numérisés
- Le fichier PDF indexable est lisible par les visionneuses PDF et les applications de recherche textuelle.
- Aucune référence d'espace de noms GdPicture ne subsiste dans tout fichier
.csaprès migration - Le profil mémoire indique une utilisation stable sous charge soutenue (aucune fuite d'allocation d'images).
- Le déploiement réussit sur les cibles Linux et Docker sans erreurs de chemin d'accès au système de fichiers
Principaux avantages de la migration vers IronOCR
Sécurité mémoire assurée par le compilateur. Le cycle de vie des identifiants d'image que GdPicture exige des développeurs qu'ils gèrent manuellement disparaît entièrement. OcrInput implémente IDisposable, et les blocs using imposent un nettoyage à la fin de chaque portée — y compris les chemins d'exception. Aucun List<int> à maintenir, pas de blocs finally à se souvenir, aucun incident de mémoire en production provenant d'appels de libération manqués.
Un seul package pour tous les scénarios OCR. L'OCR d'image, l'OCR de PDF, le traitement multipages TIFF, la génération de PDF interrogeable, les filtres de prétraitement, la lecture de codes-barres, et plus de 125 packs linguistiques sont tous disponibles à partir du package NuGet IronOcr et de ses compagnons linguistiques. Il n'existe aucune condition d'accès aux fonctionnalités qui exige l'achat d'une deuxième ou d'une troisième licence avant qu'un flux de travail courant ne devienne possible. Consultez la présentation des fonctionnalités IronOCR pour obtenir la liste complète des capacités.
Async natif et sécurité des threads. ReadAsync est une méthode async authentique, pas un wrapper Task.Run. IronTesseract est sûr à utiliser à travers les threads sans synchronisation. Les services de traitement de documents qui nécessitaient précédemment l'initialisation de composants par thread et la sérialisation des sémaphores se réduisent à une seule instance partagée avec Parallel.ForEach. Le guide OCR asynchrone couvre à la fois les modèles ASP.NET Core et les services hébergés.
Configuration de déploiement nulle. IronOCR ne nécessite aucun chemin de système de fichiers, aucun fichier de langue externe, aucun emplacement binaire natif ni aucun script de déploiement. L'étape de restauration NuGet fournit tout ce dont l'application a besoin. Les images Docker, les déploiements Azure App Service et les serveurs Linux fonctionnent de manière identique à la machine de développement. Les guides de déploiement Docker et Azure présentent des configurations prêtes pour la production.
Espace de noms stable en version. using IronOcr n'a pas changé à travers les versions majeures. Les numéros de version NuGet gèrent le versionnage via le modèle standard de gestion des packages. Les futures mises à jour majeures ne nécessiteront pas une opération de recherche et de remplacement à l'échelle du code source de l'importation de l'espace de noms.
Licences perpétuelles prévisibles. IronOCR est proposé à $999 (Lite), 1 499 $ (Plus), 2 999 $ (Professional), et 5 999 $ (Unlimited) — achats perpétuels uniques qui incluent un an de mises à jour, avec un renouvellement facultatif annuel. Toutes les fonctionnalités sont disponibles à tous les niveaux. Il n'y a pas de plugins par fonctionnalité, pas de frais par page et aucune obligation de maintenance après la première année. Les équipes qui avaient auparavant dépensé plus de 8 000 $ en licences de plugins GdPicture pour un flux de travail basé uniquement sur la reconnaissance optique de caractères (OCR) récupèrent ce montant dès le premier cycle de licence. Les détails complets des tarifs sont disponibles sur la page de licences IronOCR .
