Comparaison de logiciels OCR open source pour factures : trouvez le meilleur outil.
LEADTOOLS expédie des logiciels SDK depuis 1990, et son intégration OCR porte pleinement cet héritage : avant qu'un seul caractère ne soit reconnu, votre application doit localiser deux fichiers binaires sur le disque, valider un couplage entre LEADTOOLS.LIC et LEADTOOLS.LIC.KEY, initialiser une instance RasterCodecs, sélectionner un type de moteur parmi trois options distinctes, appeler engine.Startup() avec un chemin de répertoire d'exécution, et ensuite — et seulement ensuite — commencer le véritable travail de reconnaissance. Chaque machine de production nécessite le déploiement des fichiers de licence vers un emplacement spécifique. Les conteneurs Dockernécessitent le montage ou la validation de ces fichiers. Les pipelines CI/CD nécessitent que les fichiers soient au bon endroit, sinon l'application génère une erreur au démarrage. De plus, si le développeur a acheté le mauvais pack, le module OCR risque de ne pas être inclus, car LEADTOOLS commercialise les fonctionnalités OCR séparément de ses codecs d'imagerie.
Comprendre LEADTOOLS OCR
LEADTOOLS est une plateforme d'imagerie documentaire de LEAD Technologies, une société qui commercialise des logiciels SDK depuis 1990. La fonction OCR est un module parmi d'autres dans une boîte à outils qui comprend également des visionneuses de documents, l'imagerie médicale (DICOM/PACS), la lecture de codes-barres, la reconnaissance de formulaires, les annotations et la manipulation de fichiers PDF. Cette architecture signifie que LEADTOOLS n'est pas une bibliothèque OCR, mais une plateforme d'imagerie qui inclut l'OCR.
Principales caractéristiques architecturales de LEADTOOLS OCR :
- Trois moteurs OCR distincts : le moteur propriétaire LEAD (inclus dans la licence de base), un wrapper Tesseract (nécessite des fichiers tessdata) et un moteur OmniPage (nécessite un accord de licence Kofax distinct et une relation avec un deuxième fournisseur). Le choix du moteur influe à la fois sur le code et sur le coût.
- Déploiement de licence basé sur fichier : Deux fichiers —
LEADTOOLS.LICetLEADTOOLS.LIC.KEY— doivent être lisibles à l'exécution. Le chemin est codé en dur ou résolu au démarrage. La résolution de chemin se comporte différemment dans IIS vs. les hôtes de console, dans Dockervs. le matériel nu, dans les builds de production vs. debug. RasterCodecscomme intermédiaire requis : Le chargement d'image ne va pas directement au moteur OCR. Chaque image — y compris les pages PDF — est chargée via une instanceRasterCodecsd'abord, qui doit être initialisée avant le démarrage du moteur.- Cycle de vie explicite du moteur :
OcrEngineManager.CreateEngine()crée le moteur,engine.Startup()le charge en mémoire (500–2000 ms), etengine.Shutdown()doit être appelé avantDispose(). Ignorer l'appel d'arrêt dans le mauvais ordre produit des erreurs. - Complexité de la tarification des offres groupées : LEADTOOLS ne publie pas ses prix publiquement. Contactez les ventes LEADTOOLS pour un devis basé sur vos besoins spécifiques. Des frais de maintenance annuels sont requis pour recevoir des mises à jour.
- Empreinte de déploiement large : Les déploiements de production incluent plusieurs DLLs LEADTOOLS, un répertoire
OcrRuntime/, des fichiers de licence, et éventuellement un dossiertessdata/si vous utilisez le moteur Tesseract.
La séquence d'initialisation
LEADTOOLS nécessite une configuration spécifique en plusieurs étapes avant que toute reconnaissance puisse avoir lieu. L'ordre n'est pas optionnel — appeler Startup() avant SetLicense() ou avant que RasterCodecs ne soit initialisé entraîne des erreurs d'exécution:
using Leadtools;
using Leadtools.Ocr;
using Leadtools.Codecs;
public class LeadtoolsOcrService : IDisposable
{
private IOcrEngine _ocrEngine;
private RasterCodecs _codecs;
public LeadtoolsOcrService()
{
// Step 1: Locate and validate both license files
RasterSupport.SetLicense(
@"C:\LEADTOOLS\License\LEADTOOLS.LIC",
File.ReadAllText(@"C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY"));
// Step 2: Initialize image codec layer
_codecs = new RasterCodecs();
// Step 3: Select engine type — wrong choice means different behavior
_ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
// Step 4: Load runtime into memory (500–2000ms)
_ocrEngine.Startup(_codecs, null, null,
@"C:\LEADTOOLS\OCR\OcrRuntime");
}
public string ExtractText(string imagePath)
{
using var image = _codecs.Load(imagePath);
using var document = _ocrEngine.DocumentManager.CreateDocument();
var page = document.Pages.AddPage(image, null);
page.Recognize(null); // Recognition is not automatic
return page.GetText(-1);
}
public void Dispose()
{
_ocrEngine?.Shutdown(); // Must call before Dispose
_ocrEngine?.Dispose();
_codecs?.Dispose();
}
}
using Leadtools;
using Leadtools.Ocr;
using Leadtools.Codecs;
public class LeadtoolsOcrService : IDisposable
{
private IOcrEngine _ocrEngine;
private RasterCodecs _codecs;
public LeadtoolsOcrService()
{
// Step 1: Locate and validate both license files
RasterSupport.SetLicense(
@"C:\LEADTOOLS\License\LEADTOOLS.LIC",
File.ReadAllText(@"C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY"));
// Step 2: Initialize image codec layer
_codecs = new RasterCodecs();
// Step 3: Select engine type — wrong choice means different behavior
_ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
// Step 4: Load runtime into memory (500–2000ms)
_ocrEngine.Startup(_codecs, null, null,
@"C:\LEADTOOLS\OCR\OcrRuntime");
}
public string ExtractText(string imagePath)
{
using var image = _codecs.Load(imagePath);
using var document = _ocrEngine.DocumentManager.CreateDocument();
var page = document.Pages.AddPage(image, null);
page.Recognize(null); // Recognition is not automatic
return page.GetText(-1);
}
public void Dispose()
{
_ocrEngine?.Shutdown(); // Must call before Dispose
_ocrEngine?.Dispose();
_codecs?.Dispose();
}
}
Imports Leadtools
Imports Leadtools.Ocr
Imports Leadtools.Codecs
Imports System.IO
Public Class LeadtoolsOcrService
Implements IDisposable
Private _ocrEngine As IOcrEngine
Private _codecs As RasterCodecs
Public Sub New()
' Step 1: Locate and validate both license files
RasterSupport.SetLicense(
"C:\LEADTOOLS\License\LEADTOOLS.LIC",
File.ReadAllText("C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY"))
' Step 2: Initialize image codec layer
_codecs = New RasterCodecs()
' Step 3: Select engine type — wrong choice means different behavior
_ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD)
' Step 4: Load runtime into memory (500–2000ms)
_ocrEngine.Startup(_codecs, Nothing, Nothing,
"C:\LEADTOOLS\OCR\OcrRuntime")
End Sub
Public Function ExtractText(imagePath As String) As String
Using image = _codecs.Load(imagePath)
Using document = _ocrEngine.DocumentManager.CreateDocument()
Dim page = document.Pages.AddPage(image, Nothing)
page.Recognize(Nothing) ' Recognition is not automatic
Return page.GetText(-1)
End Using
End Using
End Function
Public Sub Dispose() Implements IDisposable.Dispose
If _ocrEngine IsNot Nothing Then
_ocrEngine.Shutdown() ' Must call before Dispose
_ocrEngine.Dispose()
End If
If _codecs IsNot Nothing Then
_codecs.Dispose()
End If
End Sub
End Class
Il s'agit de la mise en œuvre minimale viable. Il n'inclut pas la gestion des erreurs pour les échecs de chemin de licence, la validation de l'état du moteur, ou la gestion de la mémoire requise pour le traitement par lots (où oublier de disposer des instances RasterImage accumule la mémoire jusqu'à ce que le processus plante).
Comprendre IronOCR
IronOCR est une bibliothèque OCR .NET commerciale basée sur un moteur LSTM Tesseract 5 optimisé. Il s'agit d'un produit OCR dédié, et non d'une plateforme d'imagerie intégrant l'OCR comme module. L'objectif de cette conception est de supprimer tous les éléments d'infrastructure superflus entre un développeur et le texte reconnu.
Caractéristiques principales d' IronOCR:
- Paquet NuGet unique :
dotnet add package IronOcrinstalle tout ce qui est nécessaire, y compris les dépendances natives, sans répertoire d'exécution supplémentaire, dossier tessdata ou fichier de licence à déployer. - Licence basée sur une chaîne de caractères : une ligne attribue une clé de licence. La clé peut venir d'une variable d'environnement,
appsettings.json, Azure Key Vault, ou AWS Secrets Manager — tout modèle de gestion des secrets déjà utilisé. Aucun fichier sur le disque. - Aucun cycle de vie du moteur :
IronTesseracts'initialise à première utilisation avec chargement paresseux. Il n'y a pas d'appelStartup(), pas d'appelShutdown(), et aucune obligation de supprimer le moteur lui-même entre les opérations. - Saisie PDF native : Les PDF se chargent directement via
OcrInput.LoadPdf(). Pas de boucle de tramage page par page, pas de spécification de l'ordre des octets, pas de suppression manuelle des objets intermédiairesRasterImage. - Prétraitement automatique : Redressement, débruitage, amélioration du contraste, binarisation et normalisation de la résolution sont disponibles en tant qu'appels de méthode unique sur
OcrInput. Elles s'appliquent simultanément à toutes les pages. - 125+ langages via NuGet : Chaque langage est un paquet NuGet séparé (
IronOcr.Languages.French, etc.). Aucun répertoire tessdata à gérer, aucune configuration de chemin. - Thread-safe par défaut : Les instances
IronTesseractsont sûres pour une utilisation concurrente. Le traitement parallèle ne nécessite aucun code de synchronisation. - Licences perpétuelles : $999 Lite / $1,499 Plus / $2,999 Professionnel / $5,999 Illimité, achat unique avec un an de mises à jour incluses.
Comparaison des fonctionnalités
| Fonction | LEADTOOLS OCR | IronOCR |
|---|---|---|
| Complexité de la configuration | Niveau élevé — Séquence d'initialisation en 4 étapes | Faible — un package NuGet |
| Déploiement de licences | Deux fichiers (.LIC + .LIC.KEY) sur chaque machine |
Clé de chaîne, à stocker n'importe où |
| Modèle de tarification | Contactez les ventes LEADTOOLS pour obtenir des tarifs | $5,999 une fois, à perpétuité |
| Prise en charge des fichiers PDF | rastérisation manuelle page par page | LoadPdf() native |
| Prétraitement | Manuel — commandes de traitement d'image séparées | Méthodes de filtrage intégrées |
| cycle de vie du moteur | Nécessite Startup() / Shutdown() manuel |
Automatique, paresseux |
| packages NuGet | Plusieurs (Leadtools, Leadtools.Ocr, Leadtools.Codecs, Leadtools.Pdf) | Un (IronOcr) |
| Sécurité des threads | Nécessite une gestion rigoureuse | Intégré |
Comparaison détaillée des fonctionnalités
| Fonction | LEADTOOLS OCR | IronOCR |
|---|---|---|
| Licence | ||
| mécanisme de licence | Paire de fichiers .LIC + .LIC.KEY |
Clé de chaîne |
| Déploiement de licences | Fichiers sur chaque machine de production | Variable d'environnement ou configuration |
| transparence des prix | Consultation commerciale requise | Publié sur le site web |
| Option perpétuelle | Non (entretien annuel requis) | Oui |
| Configuration et installation | ||
| Packages NuGet requis | 3 à 4 minimum (davantage pour les PDF) | 1 |
| Fichiers d'exécution requis | Oui — répertoire OcrRuntime/ |
Non |
| Initialisation du moteur | Nécessite Startup() manuel avec chemin d'exécution |
None |
| Arrêt du moteur | Nécessite Shutdown() manuel avant Dispose() |
None |
| tessdata management | Requis pour l'option moteur Tesseract | Non |
| Capacités OCR | ||
| Options de moteur | LEAD, Tesseract, OmniPage (sous licence séparée) | IronTesseract (Tesseract 5 LSTM optimisé) |
| Langues | 60–120 (selon le moteur) | Plus de 125 via NuGet |
| Déploiement du langage | tessdata files or engine-bundled | packages de langage NuGet |
| scores de confiance | page.RecognizeStatus |
result.Confidence (pourcentage) |
| Sortie structurée | Page, niveau de zone | Page, paragraphe, ligne, mot, caractère |
| Lecture de codes-barres | Module de code-barres LEADTOOLS séparé | Intégré (ReadBarCodes = true) |
| Gestion des fichiers PDF | ||
| Entrée PDF | Boucle de rastérisation page par page | LoadPdf() native |
| PDF de mot de passe | Nécessite module Leadtools.Pdf (licence supplémentaire) |
Paramètre intégré Password |
| Sortie PDF consultable | Configuration DocumentWriter + document.Save() |
result.SaveAsSearchablePdf() |
| Sélection de la plage de pages | limites de boucle manuelles | LoadPdfPages(path, start, end) |
| Prétraitement | ||
| Déclin | DeskewCommand (manuel par image) |
input.Deskew() |
| Denoise | DespeckleCommand (manuel par image) |
input.DeNoise() |
| Binariser | AutoBinarizeCommand (manuel par image) |
input.Binarize() |
| Amélioration du contraste | ContrastBrightnessCommand (manuel) |
input.Contrast() |
| Amélioration de la résolution | Commandes manuelles de niveaux de gris et de rééchantillonnage | input.EnhanceResolution(300) |
| Déploiement | ||
| Docker | Les fichiers LIC/KEY doivent être montés ou intégrés. | Standard dotnet publish |
| Linux | Prise en charge par les dépendances natives | Prise en charge, dépendances incluses |
| Entrefer | Oui | Oui |
| Complexité CI/CD | Fichiers de licence + chemin d'exécution dans chaque environnement | Clé de licence dans le gestionnaire de secrets |
Architecture des licences : Déploiement de fichiers vs. Clé de chaîne
La différence d'architecture de licence entre LEADTOOLS et IronOCR ne se limite pas à l'ergonomie pour les développeurs ; elle affecte directement les pipelines de déploiement, les stratégies de conteneurisation et la charge opérationnelle.
Approche LEADTOOLS
LEADTOOLS nécessite deux fichiers physiques présents et lisibles au démarrage de l'application. Le code dans les fichiers source .cs confirme le modèle :
// From leadtools-migration-examples.cs
public void InitializeLicense()
{
// Option 1: Absolute paths — deployment dependent
string licPath = @"C:\LEADTOOLS\License\LEADTOOLS.LIC";
string keyPath = @"C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY";
// Option 2: Relative paths — working directory dependent
licPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LEADTOOLS.LIC");
keyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LEADTOOLS.LIC.KEY");
// Read key file content (not the path — the content)
string key = File.ReadAllText(keyPath);
// Set license — silent failure on some error types
RasterSupport.SetLicense(licPath, key);
// Verify license is valid for the module you purchased
if (!RasterSupport.IsLocked(RasterSupportType.Document))
{
throw new InvalidOperationException("Document module not licensed");
}
}
// From leadtools-migration-examples.cs
public void InitializeLicense()
{
// Option 1: Absolute paths — deployment dependent
string licPath = @"C:\LEADTOOLS\License\LEADTOOLS.LIC";
string keyPath = @"C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY";
// Option 2: Relative paths — working directory dependent
licPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LEADTOOLS.LIC");
keyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LEADTOOLS.LIC.KEY");
// Read key file content (not the path — the content)
string key = File.ReadAllText(keyPath);
// Set license — silent failure on some error types
RasterSupport.SetLicense(licPath, key);
// Verify license is valid for the module you purchased
if (!RasterSupport.IsLocked(RasterSupportType.Document))
{
throw new InvalidOperationException("Document module not licensed");
}
}
Imports System
Imports System.IO
Public Sub InitializeLicense()
' Option 1: Absolute paths — deployment dependent
Dim licPath As String = "C:\LEADTOOLS\License\LEADTOOLS.LIC"
Dim keyPath As String = "C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY"
' Option 2: Relative paths — working directory dependent
licPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LEADTOOLS.LIC")
keyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LEADTOOLS.LIC.KEY")
' Read key file content (not the path — the content)
Dim key As String = File.ReadAllText(keyPath)
' Set license — silent failure on some error types
RasterSupport.SetLicense(licPath, key)
' Verify license is valid for the module you purchased
If Not RasterSupport.IsLocked(RasterSupportType.Document) Then
Throw New InvalidOperationException("Document module not licensed")
End If
End Sub
Les modes de défaillance sont multiples et chacun nécessite une réparation distincte. La résolution de chemin se comporte différemment entre IIS et un hôte de console. Les chemins relatifs dans bin/Debug ne correspondent pas aux chemins dans bin/Release ou dans un conteneur Dockersauf si vous les mappez explicitement. Les fichiers LIC et KEY doivent provenir du même téléchargement ; les fichiers provenant de téléchargements différents génèrent une erreur " la clé ne correspond pas au fichier de licence ". Si la licence ne couvre que le bundle Document mais que le code utilise une fonctionnalité du bundle Recognition, IsLocked() renvoie faux et l'application doit gérer la divergence au démarrage.
Erreurs courantes en production :
"License file not found at specified path"— chemin résolu vers le mauvais répertoire"License key does not match license file"— fichiers de téléchargements différents ou corrompus lors du transfert"Document module not licensed"— bundle incorrect acheté"License has expired"— licence d'évaluation expirée ou maintenance interrompue
Approche d'IronOCR
La licence IronOCR est une attribution de chaîne unique. Aucun fichier, aucune résolution de chemin, aucune vérification en deux parties :
// From application startup — store key using any secrets management pattern
IronOcr.License.LicenseKey = "IRONSUITE.YOUR-LICENSE-KEY";
// Production: pull from environment variable
IronOcr.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// Or from ASP.NET configuration
IronOcr.License.LicenseKey = Configuration["IronOCR:LicenseKey"];
// From application startup — store key using any secrets management pattern
IronOcr.License.LicenseKey = "IRONSUITE.YOUR-LICENSE-KEY";
// Production: pull from environment variable
IronOcr.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// Or from ASP.NET configuration
IronOcr.License.LicenseKey = Configuration["IronOCR:LicenseKey"];
' From application startup — store key using any secrets management pattern
IronOcr.License.LicenseKey = "IRONSUITE.YOUR-LICENSE-KEY"
' Production: pull from environment variable
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
' Or from ASP.NET configuration
IronOcr.License.LicenseKey = Configuration("IronOCR:LicenseKey")
La clé peut être stockée dans Azure Key Vault, AWS Secrets Manager, les secrets Kubernetes ou une variable d'environnement Docker. Aucun fichier ne doit être inclus dans l'image Docker. Aucune étape du pipeline CI/CD ne copie les artefacts de licence vers les agents de construction. La page de licences IronOCR présente directement les différents niveaux de licence disponibles, sans intervention commerciale.
Configuration du moteur et verbosité
La différence de code entre LEADTOOLS et IronOCR pour une tâche OCR de base illustre la philosophie API de chaque bibliothèque.
Approche LEADTOOLS
Une implémentation LEADTOOLS minimale fonctionnelle (prise directement de leadtools-vs-ironocr-examples.cs) nécessite dix opérations distinctes avant que le texte ne soit retourné :
using Leadtools;
using Leadtools.Ocr;
using Leadtools.Codecs;
public class LeadtoolsOcrService : IDisposable
{
private IOcrEngine _ocrEngine;
private RasterCodecs _codecs;
public LeadtoolsOcrService()
{
// Step 1: License files
RasterSupport.SetLicense(
@"C:\LEADTOOLS\License\LEADTOOLS.LIC",
File.ReadAllText(@"C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY"));
// Step 2: Codec layer
_codecs = new RasterCodecs();
// Step 3: Engine factory
_ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
// Step 4: Engine startup (500–2000ms blocking call)
_ocrEngine.Startup(_codecs, null, null,
@"C:\LEADTOOLS\OCR\OcrRuntime");
}
public string ExtractText(string imagePath)
{
using var image = _codecs.Load(imagePath); // Step 5: Load via codecs
using var document = _ocrEngine.DocumentManager // Step 6: Create document
.CreateDocument();
var page = document.Pages.AddPage(image, null); // Step 7: Add page
page.Recognize(null); // Step 8: Explicit recognize
return page.GetText(-1); // Step 9: Extract text
}
public void Dispose()
{
_ocrEngine?.Shutdown(); // Step 10: Shutdown before dispose
_ocrEngine?.Dispose();
_codecs?.Dispose();
}
}
using Leadtools;
using Leadtools.Ocr;
using Leadtools.Codecs;
public class LeadtoolsOcrService : IDisposable
{
private IOcrEngine _ocrEngine;
private RasterCodecs _codecs;
public LeadtoolsOcrService()
{
// Step 1: License files
RasterSupport.SetLicense(
@"C:\LEADTOOLS\License\LEADTOOLS.LIC",
File.ReadAllText(@"C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY"));
// Step 2: Codec layer
_codecs = new RasterCodecs();
// Step 3: Engine factory
_ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
// Step 4: Engine startup (500–2000ms blocking call)
_ocrEngine.Startup(_codecs, null, null,
@"C:\LEADTOOLS\OCR\OcrRuntime");
}
public string ExtractText(string imagePath)
{
using var image = _codecs.Load(imagePath); // Step 5: Load via codecs
using var document = _ocrEngine.DocumentManager // Step 6: Create document
.CreateDocument();
var page = document.Pages.AddPage(image, null); // Step 7: Add page
page.Recognize(null); // Step 8: Explicit recognize
return page.GetText(-1); // Step 9: Extract text
}
public void Dispose()
{
_ocrEngine?.Shutdown(); // Step 10: Shutdown before dispose
_ocrEngine?.Dispose();
_codecs?.Dispose();
}
}
Imports Leadtools
Imports Leadtools.Ocr
Imports Leadtools.Codecs
Imports System.IO
Public Class LeadtoolsOcrService
Implements IDisposable
Private _ocrEngine As IOcrEngine
Private _codecs As RasterCodecs
Public Sub New()
' Step 1: License files
RasterSupport.SetLicense(
"C:\LEADTOOLS\License\LEADTOOLS.LIC",
File.ReadAllText("C:\LEADTOOLS\License\LEADTOOLS.LIC.KEY"))
' Step 2: Codec layer
_codecs = New RasterCodecs()
' Step 3: Engine factory
_ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD)
' Step 4: Engine startup (500–2000ms blocking call)
_ocrEngine.Startup(_codecs, Nothing, Nothing,
"C:\LEADTOOLS\OCR\OcrRuntime")
End Sub
Public Function ExtractText(imagePath As String) As String
Using image = _codecs.Load(imagePath) ' Step 5: Load via codecs
Using document = _ocrEngine.DocumentManager ' Step 6: Create document
.CreateDocument()
Dim page = document.Pages.AddPage(image, Nothing) ' Step 7: Add page
page.Recognize(Nothing) ' Step 8: Explicit recognize
Return page.GetText(-1) ' Step 9: Extract text
End Using
End Using
End Function
Public Sub Dispose() Implements IDisposable.Dispose
_ocrEngine?.Shutdown() ' Step 10: Shutdown before dispose
_ocrEngine?.Dispose()
_codecs?.Dispose()
End Sub
End Class
La chaîne DocumentManager.CreateDocument() / Pages.AddPage() / page.Recognize() / page.GetText() n'est pas réductible. Chaque étape correspond à un appel API distinct. Omettre page.Recognize(null) avant page.GetText(-1) renvoie un texte vide — la reconnaissance n'est pas déclenchée automatiquement en ajoutant une page.
Approche d'IronOCR
L'implémentation IronOCR équivalente (issue du même fichier de comparaison) ne comporte qu'une seule ligne pour l'opération de base et aucune gestion du cycle de vie :
using IronOcr;
public class OcrService
{
public string ExtractText(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
}
using IronOcr;
public class OcrService
{
public string ExtractText(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
}
Imports IronOcr
Public Class OcrService
Public Function ExtractText(imagePath As String) As String
Return New IronTesseract().Read(imagePath).Text
End Function
End Class
Pour l'utilisation en production où l'instance IronTesseract est réutilisée sur plusieurs appels :
public class OcrService
{
private readonly IronTesseract _ocr = new IronTesseract();
public string ExtractText(string imagePath)
{
return _ocr.Read(imagePath).Text;
}
}
public class OcrService
{
private readonly IronTesseract _ocr = new IronTesseract();
public string ExtractText(string imagePath)
{
return _ocr.Read(imagePath).Text;
}
}
Imports IronTesseract
Public Class OcrService
Private ReadOnly _ocr As New IronTesseract()
Public Function ExtractText(imagePath As String) As String
Return _ocr.Read(imagePath).Text
End Function
End Class
Pas de Startup(), pas de Shutdown(), pas de couche codec, pas de conteneur de document, pas d'appel explicite de reconnaissance. La documentation de l'API IronTesseract indique la surface totale. Le guide d'installation décrit les options de configuration pour les scénarios de production.
Traitement de PDF
C'est au niveau de la reconnaissance optique de caractères (OCR) des fichiers PDF que le modèle de rastérisation page par page de LEADTOOLS devient le plus visible. LEADTOOLS n'a pas de chemin de reconnaissance PDF natif — chaque page PDF doit être chargée en tant qu'image raster via RasterCodecs, puis ajoutée à un IOcrDocument, puis reconnue individuellement, puis avoir son texte extrait individuellement.
Approche LEADTOOLS
À partir de leadtools-pdf-processing.cs, le flux de travail PDF de base :
public string ExtractTextFromPdf(string pdfPath)
{
var text = new StringBuilder();
// Get page count first — separate call
var pdfInfo = _codecs.GetInformation(pdfPath, true);
int totalPages = pdfInfo.TotalPages;
using var document = _ocrEngine.DocumentManager.CreateDocument();
for (int pageNum = 1; pageNum <= totalPages; pageNum++)
{
// Load each page as a raster image — must dispose each
using var pageImage = _codecs.Load(
pdfPath,
0, // bitsPerPixel
CodecsLoadByteOrder.BgrOrGray,
pageNum, // firstPage
pageNum); // lastPage
var page = document.Pages.AddPage(pageImage, null);
page.Recognize(null);
text.AppendLine(page.GetText(-1));
}
return text.ToString();
}
public string ExtractTextFromPdf(string pdfPath)
{
var text = new StringBuilder();
// Get page count first — separate call
var pdfInfo = _codecs.GetInformation(pdfPath, true);
int totalPages = pdfInfo.TotalPages;
using var document = _ocrEngine.DocumentManager.CreateDocument();
for (int pageNum = 1; pageNum <= totalPages; pageNum++)
{
// Load each page as a raster image — must dispose each
using var pageImage = _codecs.Load(
pdfPath,
0, // bitsPerPixel
CodecsLoadByteOrder.BgrOrGray,
pageNum, // firstPage
pageNum); // lastPage
var page = document.Pages.AddPage(pageImage, null);
page.Recognize(null);
text.AppendLine(page.GetText(-1));
}
return text.ToString();
}
Imports System.Text
Public Function ExtractTextFromPdf(ByVal pdfPath As String) As String
Dim text As New StringBuilder()
' Get page count first — separate call
Dim pdfInfo = _codecs.GetInformation(pdfPath, True)
Dim totalPages As Integer = pdfInfo.TotalPages
Using document = _ocrEngine.DocumentManager.CreateDocument()
For pageNum As Integer = 1 To totalPages
' Load each page as a raster image — must dispose each
Using pageImage = _codecs.Load(pdfPath, 0, CodecsLoadByteOrder.BgrOrGray, pageNum, pageNum)
Dim page = document.Pages.AddPage(pageImage, Nothing)
page.Recognize(Nothing)
text.AppendLine(page.GetText(-1))
End Using
Next
End Using
Return text.ToString()
End Function
Le traitement d'un PDF protégé par mot de passe ajoute une dépendance supplémentaire. À partir de leadtools-pdf-processing.cs :
// Requires Leadtools.Pdf module — additional license
using Leadtools.Pdf;
public string ExtractFromEncryptedPdf(string pdfPath, string password)
{
var pdfFile = new PDFFile(pdfPath);
pdfFile.Password = password;
var loadOptions = new CodecsLoadOptions();
_codecs.Options.Pdf.Load.Password = password;
// ... same page iteration loop follows
}
// Requires Leadtools.Pdf module — additional license
using Leadtools.Pdf;
public string ExtractFromEncryptedPdf(string pdfPath, string password)
{
var pdfFile = new PDFFile(pdfPath);
pdfFile.Password = password;
var loadOptions = new CodecsLoadOptions();
_codecs.Options.Pdf.Load.Password = password;
// ... same page iteration loop follows
}
Imports Leadtools.Pdf
Public Function ExtractFromEncryptedPdf(ByVal pdfPath As String, ByVal password As String) As String
Dim pdfFile As New PDFFile(pdfPath)
pdfFile.Password = password
Dim loadOptions As New CodecsLoadOptions()
_codecs.Options.Pdf.Load.Password = password
' ... same page iteration loop follows
End Function
Le namespace Leadtools.Pdf est un module séparé. Si l'équipe de développement a acheté le module OCR mais pas le module PDF, la prise en charge des PDF chiffrés n'est pas disponible sans l'achat d'une licence séparée.
Créer une sortie PDF consultable nécessite de configurer un DocumentWriter avant de sauvegarder :
// From leadtools-pdf-processing.cs
var pdfOptions = new PdfDocumentOptions
{
DocumentType = PdfDocumentType.Pdf,
ImageOverText = true,
Linearized = false,
Title = Path.GetFileNameWithoutExtension(inputPdfPath)
};
_engine.DocumentWriterInstance.SetOptions(DocumentFormat.Pdf, pdfOptions);
document.Save(outputPdfPath, DocumentFormat.Pdf, null);
// From leadtools-pdf-processing.cs
var pdfOptions = new PdfDocumentOptions
{
DocumentType = PdfDocumentType.Pdf,
ImageOverText = true,
Linearized = false,
Title = Path.GetFileNameWithoutExtension(inputPdfPath)
};
_engine.DocumentWriterInstance.SetOptions(DocumentFormat.Pdf, pdfOptions);
document.Save(outputPdfPath, DocumentFormat.Pdf, null);
Imports System.IO
Dim pdfOptions As New PdfDocumentOptions With {
.DocumentType = PdfDocumentType.Pdf,
.ImageOverText = True,
.Linearized = False,
.Title = Path.GetFileNameWithoutExtension(inputPdfPath)
}
_engine.DocumentWriterInstance.SetOptions(DocumentFormat.Pdf, pdfOptions)
document.Save(outputPdfPath, DocumentFormat.Pdf, Nothing)
Approche d'IronOCR
IronOCR gère nativement les fichiers PDF. Les trois mêmes scénarios — PDF de base, PDF protégé par mot de passe et PDF consultable — se réduisent chacun à deux ou trois lignes :
using IronOcr;
// Basic PDF — all pages, automatic handling
public string ExtractTextFromPdf(string pdfPath)
{
using var input = new OcrInput();
input.LoadPdf(pdfPath);
return new IronTesseract().Read(input).Text;
}
// Password-protected PDF — no additional module required
public string ExtractFromEncryptedPdf(string pdfPath, string password)
{
using var input = new OcrInput();
input.LoadPdf(pdfPath, Password: password);
return new IronTesseract().Read(input).Text;
}
// Sortie PDF consultable — one method call
public void CreateSearchablePdf(string inputPdfPath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadPdf(inputPdfPath);
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf(outputPdfPath);
}
using IronOcr;
// Basic PDF — all pages, automatic handling
public string ExtractTextFromPdf(string pdfPath)
{
using var input = new OcrInput();
input.LoadPdf(pdfPath);
return new IronTesseract().Read(input).Text;
}
// Password-protected PDF — no additional module required
public string ExtractFromEncryptedPdf(string pdfPath, string password)
{
using var input = new OcrInput();
input.LoadPdf(pdfPath, Password: password);
return new IronTesseract().Read(input).Text;
}
// Sortie PDF consultable — one method call
public void CreateSearchablePdf(string inputPdfPath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadPdf(inputPdfPath);
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf(outputPdfPath);
}
Imports IronOcr
' Basic PDF — all pages, automatic handling
Public Function ExtractTextFromPdf(pdfPath As String) As String
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Return New IronTesseract().Read(input).Text
End Using
End Function
' Password-protected PDF — no additional module required
Public Function ExtractFromEncryptedPdf(pdfPath As String, password As String) As String
Using input As New OcrInput()
input.LoadPdf(pdfPath, Password:=password)
Return New IronTesseract().Read(input).Text
End Using
End Function
' Sortie PDF consultable — one method call
Public Sub CreateSearchablePdf(inputPdfPath As String, outputPdfPath As String)
Using input As New OcrInput()
input.LoadPdf(inputPdfPath)
Dim result = New IronTesseract().Read(input)
result.SaveAsSearchablePdf(outputPdfPath)
End Using
End Sub
Le guide d'importation PDF couvre la sélection de la plage de pages, l'importation de flux et l'accès aux résultats par page. L' exemple de PDF consultable illustre le flux de production complet. Pour le prétraitement des PDF numérisés de faible qualité avant la reconnaissance, consultez le guide de correction de la qualité d'image .
Prétraitement : commandes manuelles vs filtres intégrés
LEADTOOLS fournit des commandes de traitement d'image via un namespace Leadtools.ImageProcessing séparé. Ces commandes doivent être appliquées individuellement à chaque instance RasterImage avant que l'image ne soit transmise au moteur OCR.
Approche LEADTOOLS
À partir de leadtools-pdf-processing.cs, prétraitement d'une page PDF :
using Leadtools.ImageProcessing;
public string ProcessLowQualityPdf(string pdfPath)
{
var text = new StringBuilder();
var pdfInfo = _codecs.GetInformation(pdfPath, true);
using var document = _engine.DocumentManager.CreateDocument();
for (int i = 1; i <= pdfInfo.TotalPages; i++)
{
using var pageImage = _codecs.Load(pdfPath, 0,
CodecsLoadByteOrder.BgrOrGray, i, i);
// Each command is a separate instantiation and Run() call
var deskewCommand = new DeskewCommand();
deskewCommand.Run(pageImage);
var despeckleCommand = new DespeckleCommand();
despeckleCommand.Run(pageImage);
if (pageImage.BitsPerPixel > 8)
{
var grayscaleCommand = new GrayscaleCommand(8);
grayscaleCommand.Run(pageImage);
}
var binarizeCommand = new AutoBinarizeCommand();
binarizeCommand.Run(pageImage);
var page = document.Pages.AddPage(pageImage, null);
page.Recognize(null);
text.AppendLine(page.GetText(-1));
}
return text.ToString();
}
using Leadtools.ImageProcessing;
public string ProcessLowQualityPdf(string pdfPath)
{
var text = new StringBuilder();
var pdfInfo = _codecs.GetInformation(pdfPath, true);
using var document = _engine.DocumentManager.CreateDocument();
for (int i = 1; i <= pdfInfo.TotalPages; i++)
{
using var pageImage = _codecs.Load(pdfPath, 0,
CodecsLoadByteOrder.BgrOrGray, i, i);
// Each command is a separate instantiation and Run() call
var deskewCommand = new DeskewCommand();
deskewCommand.Run(pageImage);
var despeckleCommand = new DespeckleCommand();
despeckleCommand.Run(pageImage);
if (pageImage.BitsPerPixel > 8)
{
var grayscaleCommand = new GrayscaleCommand(8);
grayscaleCommand.Run(pageImage);
}
var binarizeCommand = new AutoBinarizeCommand();
binarizeCommand.Run(pageImage);
var page = document.Pages.AddPage(pageImage, null);
page.Recognize(null);
text.AppendLine(page.GetText(-1));
}
return text.ToString();
}
Imports Leadtools.ImageProcessing
Imports System.Text
Public Function ProcessLowQualityPdf(pdfPath As String) As String
Dim text As New StringBuilder()
Dim pdfInfo = _codecs.GetInformation(pdfPath, True)
Using document = _engine.DocumentManager.CreateDocument()
For i As Integer = 1 To pdfInfo.TotalPages
Using pageImage = _codecs.Load(pdfPath, 0, CodecsLoadByteOrder.BgrOrGray, i, i)
' Each command is a separate instantiation and Run() call
Dim deskewCommand As New DeskewCommand()
deskewCommand.Run(pageImage)
Dim despeckleCommand As New DespeckleCommand()
despeckleCommand.Run(pageImage)
If pageImage.BitsPerPixel > 8 Then
Dim grayscaleCommand As New GrayscaleCommand(8)
grayscaleCommand.Run(pageImage)
End If
Dim binarizeCommand As New AutoBinarizeCommand()
binarizeCommand.Run(pageImage)
Dim page = document.Pages.AddPage(pageImage, Nothing)
page.Recognize(Nothing)
text.AppendLine(page.GetText(-1))
End Using
Next
End Using
Return text.ToString()
End Function
Chaque étape de prétraitement nécessite l'instanciation d'une classe de commande et l'appel de .Run() contre l'image. Le développeur gère l'ordre et l'applicabilité de chaque transformation. Si l'image est déjà binaire, AutoBinarizeCommand peut dégrader la qualité. Le contrôle conditionnel BitsPerPixel est la responsabilité du développeur.
Approche d'IronOCR
Le prétraitement IronOCR s'applique à l'objet OcrInput et affecte toutes les pages chargées simultanément :
using IronOcr;
public string ProcessLowQualityPdf(string pdfPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(pdfPath);
// Applied to all pages
input.Deskew();
input.DeNoise();
input.Binarize();
input.Contrast();
input.EnhanceResolution(300);
var result = ocr.Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
return result.Text;
}
using IronOcr;
public string ProcessLowQualityPdf(string pdfPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(pdfPath);
// Applied to all pages
input.Deskew();
input.DeNoise();
input.Binarize();
input.Contrast();
input.EnhanceResolution(300);
var result = ocr.Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
return result.Text;
}
Imports IronOcr
Public Function ProcessLowQualityPdf(pdfPath As String) As String
Dim ocr = New IronTesseract()
Using input As New OcrInput()
input.LoadPdf(pdfPath)
' Applied to all pages
input.Deskew()
input.DeNoise()
input.Binarize()
input.Contrast()
input.EnhanceResolution(300)
Dim result = ocr.Read(input)
Console.WriteLine($"Confidence: {result.Confidence}%")
Return result.Text
End Using
End Function
Cinq étapes de prétraitement, appliquées uniformément sur toutes les pages, sans boucle par page. Le prétraitement automatique d'IronOCR s'exécute également au niveau de chaque appel Read() par défaut, traitant les problèmes courants de numérisation sans aucun appel de filtre explicite. Le tutoriel sur les filtres d'image couvre l'intégralité du catalogue de filtres. L' exemple de numérisation de faible qualité illustre le prétraitement avant et après application sur des documents difficiles.
Référence de mappage d'API
| API LEADTOOLS | Équivalent d'IronOCR |
|---|---|
RasterSupport.SetLicense(licPath, key) |
IronOcr.License.LicenseKey = "key" |
RasterCodecs |
OcrInput |
_codecs.Load(path) |
input.LoadImage(path) ou input.LoadPdf(path) |
_codecs.GetInformation(path, true).TotalPages |
Automatique — aucun comptage de pages nécessaire |
OcrEngineManager.CreateEngine(OcrEngineType.LEAD) |
new IronTesseract() |
engine.Startup(_codecs, null, null, runtimePath) |
Non requis |
engine.Shutdown() |
Non requis |
engine.DocumentManager.CreateDocument() |
Non requis |
document.Pages.AddPage(image, null) |
input.LoadImage(path) |
page.Recognize(null) |
ocr.Read(input) (la reconnaissance fait partie de Read) |
page.GetText(-1) |
result.Text |
page.RecognizeStatus |
result.Confidence |
OcrZone avec Bounds = new LeadRect(x, y, w, h) |
new CropRectangle(x, y, w, h) passé à input.LoadImage() |
OcrZoneType.Text |
Par défaut — aucune spécification de type requise |
page.Zones.Add(zone) |
input.LoadImage(path, cropRect) |
DeskewCommand().Run(image) |
input.Deskew() |
DespeckleCommand().Run(image) |
input.DeNoise() |
AutoBinarizeCommand().Run(image) |
input.Binarize() |
PdfDocumentOptions { ImageOverText = true } |
Géré par result.SaveAsSearchablePdf() |
_engine.DocumentWriterInstance.SetOptions(...) |
Non requis |
document.Save(path, DocumentFormat.Pdf, null) |
result.SaveAsSearchablePdf(path) |
CodecsLoadByteOrder.BgrOrGray |
Non requis — géré automatiquement |
_codecs.Options.Pdf.Load.Password = password |
input.LoadPdf(path, Password: password) |
Quand les équipes envisagent de passer de LEADTOOLS OCRà IronOCR
Le projet OCR uniquement qui ne nécessite pas le kit d'outils d'imagerie
LEADTOOLS est judicieux sur les plans financier et architectural lorsqu'une équipe a besoin de plusieurs modules — visionneuses de documents, imagerie médicale, reconnaissance de formulaires et OCR — fonctionnant ensemble au sein d'une plateforme intégrée. Lorsque l'objectif est l'extraction de texte à partir d'images et de fichiers PDF, le calcul change. Les coûts de licence LEADTOOLS nécessitent une rencontre commerciale pour des devis — contactez LEADTOOLS pour les prix actuels. Un entretien annuel est requis en plus du coût de la licence. IronOCR à $2,999 pour le niveau Professionnel couvre 10 développeurs sans besoin de renouvellement pour une utilisation continue. Les équipes qui arrivent au terme d'un cycle de renouvellement LEADTOOLS et qui réévaluent le coût découvrent souvent que le module OCR était le seul élément du pack qu'elles utilisaient.
Déploiements conteneurisés et sans serveur
Le système de licences basé sur les fichiers de LEADTOOLS devient un point de friction majeur dans les architectures de déploiement modernes. Un conteneur Dockernécessite deux fichiers de licence physiques, soit intégrés à l'image (et exposés dans l'historique des couches), soit montés lors de l'exécution avec une coordination de volumes dans chaque environnement d'orchestration. Azure Functions et AWS Lambda ne disposent d'aucun mécanisme évident pour le déploiement des fichiers de licence sans recourir à des solutions de contournement. LEADTOOLS exécute également un démarrage moteur bloquant qui charge les fichiers d'exécution en mémoire, ajoutant 500 à 2000 ms au temps de démarrage à froid — ce qui est significatif pour les fonctions sans serveur où la latence affecte directement l'expérience utilisateur. IronOCR se déploie comme une référence NuGet standard, définit une clé de licence à partir d'une variable d'environnement et s'initialise de manière différée lors de la première utilisation. Le guide de déploiement Docker et le guide de déploiement AWS couvrent les spécificités des scénarios conteneurisés courants.
Le problème du mauvais paquet
La structure modulaire de LEADTOOLS crée une catégorie de problèmes IronOCR n'a pas : l'achat du mauvais niveau. La reconnaissance optique de caractères (OCR) n'est pas incluse dans tous les packs LEADTOOLS. La prise en charge des PDF protégés par mot de passe nécessite un module PDF distinct qui n'est pas inclus dans toutes les licences axées sur la reconnaissance optique de caractères (OCR). L'option de moteur à plus haute précision nécessite un accord distinct avec le fournisseur, en plus de l'achat de LEADTOOLS. Les équipes qui pensaient que leur achat couvrait une fonctionnalité dont elles avaient besoin — et qui ont découvert le contraire seulement au moment de l'exécution en production — doivent faire face à un cycle de renégociation avec les ventes avant que la fonctionnalité puisse être activée. Les licences IronOCR couvrent toutes les fonctionnalités à chaque niveau. Il n'existe pas de module PDF séparé, pas d'extension pour les documents protégés par mot de passe, pas de fournisseur secondaire pour un moteur de plus grande précision.
Complexité de la maintenance et de la gestion des ressources
Le cycle de vie du moteur LEADTOOLS ne se limite pas à une simple cérémonie d'installation ; il crée une surface de maintenance continue. Le moteur doit être démarré, utilisé, arrêté, puis mis au rebut dans le bon ordre ; Tout écart par rapport à cette séquence engendre des erreurs. Les fuites de mémoire dans les implémentations de traitement par lots LEADTOOLS sont généralement dues à des objets image intermédiaires non supprimés, à des conteneurs de documents restés ouverts après traitement, ou à des instances du moteur créées plusieurs fois sans nettoyage adéquat. Les processeurs de lots en production incluent souvent des appels forcés au ramasse-miettes entre les blocs de documents comme mécanisme de compensation ; ce comportement indique que le modèle objet sous-jacent est incompatible avec l'environnement d'exécution. Les équipes qui ont débogué une augmentation de la consommation de mémoire dans un service de traitement de documents à 2 h du matin découvrent souvent que la cause première réside dans le modèle de suppression des objets LEADTOOLS. IronOCR utilise les portées de suppression standard de .NET . Seul le conteneur d'entrée nécessite une suppression explicite. Le moteur lui-même est sans état et compatible avec le multithreading.
Cohérence du déploiement multi-environnements
Les environnements de développement, de préproduction et de production nécessitent tous des fichiers de licence LEADTOOLS situés aux mêmes emplacements, Plus qu'un répertoire d'exécution à l'emplacement exact attendu par l'application au démarrage. Toute différence entre environnements (par exemple, un serveur de préproduction dont le chemin du répertoire d'exécution diffère de celui de production d'une seule lettre de lecteur) génère une erreur spécifique à cet environnement et requiert une modification du code ou de la configuration pour être corrigée. La clé de licence d'IronOCR et son unique package NuGet se comportent de manière identique dans tous les environnements. La clé de licence est la seule valeur spécifique à l'environnement, et elle suit les mêmes modèles de gestion des secrets que toutes les équipes .NET utilisent déjà pour les chaînes de connexion aux bases de données et les clés API.
Considérations courantes en matière de migration
Retrait du moteur
Le code LEADTOOLS enveloppe le moteur dans une classe de service qui implémente IDisposable précisément parce que le cycle de vie doit être géré. La migration supprime entièrement cette exigence :
// LEADTOOLS: Service class required for lifecycle management
public class LeadtoolsService : IDisposable
{
private IOcrEngine _engine;
private RasterCodecs _codecs;
public LeadtoolsService()
{
RasterSupport.SetLicense(licPath, key);
_codecs = new RasterCodecs();
_engine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
_engine.Startup(_codecs, null, null, runtimePath);
}
public string Process(string path)
{
using var image = _codecs.Load(path);
using var doc = _engine.DocumentManager.CreateDocument();
var page = doc.Pages.AddPage(image, null);
page.Recognize(null);
return page.GetText(-1);
}
public void Dispose()
{
_engine?.Shutdown();
_engine?.Dispose();
_codecs?.Dispose();
}
}
// IronOCR: Non lifecycle to manage
public class OcrService
{
private readonly IronTesseract _ocr = new IronTesseract();
public string Process(string path) => _ocr.Read(path).Text;
}
// LEADTOOLS: Service class required for lifecycle management
public class LeadtoolsService : IDisposable
{
private IOcrEngine _engine;
private RasterCodecs _codecs;
public LeadtoolsService()
{
RasterSupport.SetLicense(licPath, key);
_codecs = new RasterCodecs();
_engine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
_engine.Startup(_codecs, null, null, runtimePath);
}
public string Process(string path)
{
using var image = _codecs.Load(path);
using var doc = _engine.DocumentManager.CreateDocument();
var page = doc.Pages.AddPage(image, null);
page.Recognize(null);
return page.GetText(-1);
}
public void Dispose()
{
_engine?.Shutdown();
_engine?.Dispose();
_codecs?.Dispose();
}
}
// IronOCR: Non lifecycle to manage
public class OcrService
{
private readonly IronTesseract _ocr = new IronTesseract();
public string Process(string path) => _ocr.Read(path).Text;
}
Imports System
' LEADTOOLS: Service class required for lifecycle management
Public Class LeadtoolsService
Implements IDisposable
Private _engine As IOcrEngine
Private _codecs As RasterCodecs
Public Sub New()
RasterSupport.SetLicense(licPath, key)
_codecs = New RasterCodecs()
_engine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD)
_engine.Startup(_codecs, Nothing, Nothing, runtimePath)
End Sub
Public Function Process(path As String) As String
Using image = _codecs.Load(path)
Using doc = _engine.DocumentManager.CreateDocument()
Dim page = doc.Pages.AddPage(image, Nothing)
page.Recognize(Nothing)
Return page.GetText(-1)
End Using
End Using
End Function
Public Sub Dispose() Implements IDisposable.Dispose
If _engine IsNot Nothing Then
_engine.Shutdown()
_engine.Dispose()
End If
If _codecs IsNot Nothing Then
_codecs.Dispose()
End If
End Sub
End Class
' IronOCR: Non lifecycle to manage
Public Class OcrService
Private ReadOnly _ocr As New IronTesseract()
Public Function Process(path As String) As String
Return _ocr.Read(path).Text
End Function
End Class
L'instance IronTesseract est thread-safe et peut être partagée en tant que singleton. Il n'est pas nécessaire d'implémenter IDisposable sur la classe de service pour le bénéfice du moteur.
Migration OCR basée sur les zones
La configuration de zone LEADTOOLS utilise OcrZone avec les limites LeadRect et nécessite d'effacer les zones détectées automatiquement avant d'ajouter des zones personnalisées. IronOCR utilise CropRectangle passé directement à LoadImage() :
// LEADTOOLS zone setup
var zone = new OcrZone
{
Bounds = new LeadRect(x, y, width, height),
ZoneType = OcrZoneType.Text,
CharacterFilters = OcrZoneCharacterFilters.None,
RecognitionModule = OcrZoneRecognitionModule.Auto
};
page.Zones.Clear(); // Must clear auto-detected zones first
page.Zones.Add(zone);
// IronOCR equivalent
using var input = new OcrInput();
input.LoadImage(imagePath, new CropRectangle(x, y, width, height));
var text = new IronTesseract().Read(input).Text;
// LEADTOOLS zone setup
var zone = new OcrZone
{
Bounds = new LeadRect(x, y, width, height),
ZoneType = OcrZoneType.Text,
CharacterFilters = OcrZoneCharacterFilters.None,
RecognitionModule = OcrZoneRecognitionModule.Auto
};
page.Zones.Clear(); // Must clear auto-detected zones first
page.Zones.Add(zone);
// IronOCR equivalent
using var input = new OcrInput();
input.LoadImage(imagePath, new CropRectangle(x, y, width, height));
var text = new IronTesseract().Read(input).Text;
Imports Leadtools
Imports IronOcr
' LEADTOOLS zone setup
Dim zone As New OcrZone With {
.Bounds = New LeadRect(x, y, width, height),
.ZoneType = OcrZoneType.Text,
.CharacterFilters = OcrZoneCharacterFilters.None,
.RecognitionModule = OcrZoneRecognitionModule.Auto
}
page.Zones.Clear() ' Must clear auto-detected zones first
page.Zones.Add(zone)
' IronOCR equivalent
Using input As New OcrInput()
input.LoadImage(imagePath, New CropRectangle(x, y, width, height))
Dim text As String = New IronTesseract().Read(input).Text
End Using
Le guide OCR basé sur les régions couvre les modèles d'extraction mono-régionaux et multi-régionaux. L' exemple de découpage de région illustre l'extraction d'en-têtes de factures comme cas d'utilisation pratique.
Nettoyage des packages NuGet
LEADTOOLS nécessite plusieurs packages. La migration les supprime tous et en ajoute un :
# Remove LEADTOOLS packages
dotnet remove package Leadtools
dotnet remove package Leadtools.Ocr
dotnet remove package Leadtools.Codecs
dotnet remove package Leadtools.Pdf
# Add IronOCR
dotnet add package IronOcr
# Remove LEADTOOLS packages
dotnet remove package Leadtools
dotnet remove package Leadtools.Ocr
dotnet remove package Leadtools.Codecs
dotnet remove package Leadtools.Pdf
# Add IronOCR
dotnet add package IronOcr
La réduction de l'empreinte du déploiement est substantielle. Absents de la sortie de build : LEADTOOLS.LIC, LEADTOOLS.LIC.KEY, le répertoire OcrRuntime/, plusieurs DLLs LEADTOOLS, et tout dossier tessdata/ de l'option de moteur Tesseract. Il ne reste plus qu'une seule référence de paquetage. Le package NuGet IronOCR inclut toutes les dépendances natives.
Accès au score de confiance
LEADTOOLS expose la qualité de reconnaissance via page.RecognizeStatus en tant qu'énumération (OcrPageRecognizeStatus.Done indique la complétion, mais pas le niveau de précision). IronOCR fournit un pourcentage direct via result.Confidence :
var result = new IronTesseract().Read("document.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");
// Branch on quality threshold
if (result.Confidence < 60)
{
// Apply additional preprocessing and retry
using var input = new OcrInput();
input.LoadImage("document.jpg");
input.Deskew();
input.DeNoise();
input.EnhanceResolution(300);
result = new IronTesseract().Read(input);
}
var result = new IronTesseract().Read("document.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");
// Branch on quality threshold
if (result.Confidence < 60)
{
// Apply additional preprocessing and retry
using var input = new OcrInput();
input.LoadImage("document.jpg");
input.Deskew();
input.DeNoise();
input.EnhanceResolution(300);
result = new IronTesseract().Read(input);
}
Imports System
Imports IronOcr
Dim result = New IronTesseract().Read("document.jpg")
Console.WriteLine($"Confidence: {result.Confidence}%")
' Branch on quality threshold
If result.Confidence < 60 Then
' Apply additional preprocessing and retry
Using input As New OcrInput()
input.LoadImage("document.jpg")
input.Deskew()
input.DeNoise()
input.EnhanceResolution(300)
result = New IronTesseract().Read(input)
End Using
End If
Le guide des scores de confiance couvre la sélection des seuils et les modèles de nouvelle tentative basés sur la qualité.
Fonctionnalités supplémentaires d'IronOCR
Outre les points de comparaison abordés ci-dessus, IronOCR inclut des fonctionnalités qui sont soit absentes de LEADTOOLS OCR, soit nécessitent l'achat de modules supplémentaires :
- Lecture de code-barres pendant l'OCR : Réglez
ocr.Configuration.ReadBarCodes = trueet les codes-barres sont extraits en même temps que le texte en un seul passageRead(). Aucune licence supplémentaire pour le module de codes-barres LEADTOOLS n'est requise. Consultez le guide de lecture des codes-barres et l'exemple de reconnaissance optique de caractères (OCR) de codes-barres . - Extraction de données structurées :
result.Pages,result.Paragraphs,result.Lines,result.Words, etresult.Charactersexposent toute la hiérarchie du document avec des boîtes de délimitation et des scores de confiance par élément. Le guide des résultats de lecture couvre l'intégralité du modèle de sortie. - Exportation hOCR :
result.SaveAsHocrFile()produit du HTML avec données de position intégrées pour l'analyse de mise en page en aval. Consultez le guide d'exportation hOCR . - Prise en charge de plus de 125 langues : chaque langue est un package NuGet . Aucun répertoire tessdata, aucune configuration de chemin de fichier. Consultez l' index complet des langues et le guide multilingue .
- OCR asynchrone :
await ocr.ReadAsync(input)pour le traitement de documents non-bloquant dans ASP.NET et les services en arrière-plan. Consultez le guide sur la reconnaissance optique de caractères asynchrone . - Reconnaissance de documents spécialisée : Prise en charge intégrée des passeports, des plaques d'immatriculation, des chèques MICR et de l'écriture manuscrite. Consultez la page des fonctionnalités spécialisées .
- Suivi de progression :
ocr.Configuration.ProgressCallbackrapporte la progression page par page pour les travaux par lots de longue durée. Consultez le guide de suivi des progrès .
Compatibilité .NET et préparation à l'avenir
IronOCR cible .NET 6, .NET 7, .NET 8, .NET 9 et .NET Standard 2.0 — ce dernier couvrant .NET Framework 4.6.2 et versions ultérieures. La prise en charge multiplateforme couvre Windows (x86 et x64), Linuxx64, macOS, Azure App Service, AWS Lambda et Docker, avec toutes les dépendances natives regroupées dans le package NuGet . Aucune configuration spécifique à la plateforme n'est requise ; Le package sélectionne le binaire natif approprié lors de l'exécution. LEADTOOLS prend en charge le déploiement .NET multiplateforme, mais requiert des fichiers d'exécution spécifiques à chaque plateforme et la configuration de chemin correspondante pour chaque environnement cible. Pour les équipes ciblant les conteneurs Linuxou les machines de développement macOS parallèlement aux serveurs de production Windows, le déploiement en un seul package d'IronOCR élimine la couche de configuration par plateforme.
Conclusion
LEADTOOLS OCR est une technologie éprouvée, intégrée à une plateforme d'imagerie complète et bénéficiant de 35 années de développement. Pour les organisations qui ont déjà standardisé leurs besoins sur LEADTOOLS pour la visualisation de documents, l'imagerie médicale ou la reconnaissance de formulaires, l'ajout de la reconnaissance optique de caractères (OCR) à cet investissement existant est une décision raisonnable : les coûts d'intégration sont déjà couverts et l'interface API unifiée a de la valeur.
Pour les équipes dont le besoin est l'extraction de texte à partir d'images et de fichiers PDF, le calcul est différent. La séquence d'initialisation en quatre étapes de LEADTOOLS, le déploiement de licences basé sur des fichiers, la couche de codec séparée et le cycle de vie explicite du moteur ne sont pas des complexités qui garantissent la précision ou les capacités de l'OCR. Il s'agit de frais d'infrastructure que chaque développeur de l'équipe doit comprendre, que chaque environnement de déploiement doit prendre en charge et que chaque pipeline CI/CD doit intégrer. L'achat d'un pack inadapté (module OCR sans module PDF, ou moteur LEAD sans le niveau de précision OmniPage) engendre des défaillances silencieuses qui apparaissent en production plutôt qu'au moment de l'achat.
Le package NuGet unique d'IronOCR, sa licence basée sur les chaînes de caractères et son chemin de reconnaissance en une seule ligne éliminent ces frais généraux sans sacrifier les fonctionnalités essentielles pour la reconnaissance optique de caractères en production : prétraitement automatique, prise en charge native du format PDF, gestion des documents protégés par mot de passe, extraction de la sortie structurée, prise en charge de plus de 125 langues et traitement parallèle sécurisé pour les threads. La différence de prix — $2,999 à perpétuité vs. les frais de licence et de maintenance pluriannuels de LEADTOOLS — est significative. C'est la différence entre l'achat ponctuel d'un outil d'ingénierie et un abonnement continu nécessitant une justification budgétaire annuelle.
Le problème initial — fichiers de licence sur chaque machine de production, confusion des bundles et procédure d'initialisation avant même la lecture d'un caractère — reflète les coûts réels de déploiement et d'exploitation. Les équipes évaluant les deux options devraient exécuter la séquence d'initialisation de LEADTOOLS en fonction de leur stratégie de conteneurisation, de leur pipeline CI/CD et de leur approche de gestion des secrets avant de s'engager. La réponse permet souvent de clarifier le choix.
Questions Fréquemment Posées
Qu'est-ce que LEADTOOLS OCR ?
LEADTOOLS OCR est une solution d'OCR utilisée par les développeurs et les entreprises pour extraire du texte à partir d'images et de documents. Il s'agit de l'une des nombreuses options d'OCR évaluées aux côtés d'IronOCR pour le développement d'applications .NET.
Comment IronOCR se compare-t-il à LEADTOOLS OCR for .NET developers ?
IronOCR est une bibliothèque OCR .NET native de NuGet qui utilise IronTesseract comme moteur principal. Par rapport à LEADTOOLS OCR, elle offre un déploiement plus simple (pas d'installateurs SDK), une tarification forfaitaire et une API C# propre sans interopérabilité COM ou dépendances cloud.
IronOcr est-il plus facile à configurer que LEADTOOLS OCR ?
IronOCR s'installe via un seul package NuGet. Il n'y a pas d'installateur SDK, de fichiers de licence à copier, de composants COM à enregistrer ou de binaires d'exécution séparés à gérer. L'ensemble du moteur d'OCR est inclus dans le package.
Quelles sont les différences de précision entre LEADTOOLS OCR et IronOcr ?
IronOcr atteint une grande précision de reconnaissance pour les documents commerciaux standard, les factures, les reçus et les formulaires numérisés. Pour les documents très dégradés ou les scripts peu courants, la précision varie en fonction de la qualité de la source. IronOCR comprend des filtres de prétraitement d'image pour améliorer la reconnaissance sur des entrées de faible qualité.
IronOCR prend-il en charge l'extraction de texte au format PDF ?
Oui. IronOCR extrait le texte des PDF natifs et des images PDF numérisées en un seul appel. Il prend également en charge les fichiers TIFF multipages, les images et les flux. Pour les PDF numérisés, l'OCR est appliquée page par page avec des objets de résultat par page.
Comment la licence de LEADTOOLS OCR se compare-t-elle à celle d'IronOcr ?
IronOCR utilise une licence perpétuelle forfaitaire sans frais par page ou par scan. Les organisations qui traitent de gros volumes de documents paient le même coût de licence, quel que soit le volume. Les détails et la tarification au volume se trouvent sur la page de licence d'IronOCR.
Quelles langues IronOCR prend-il en charge ?
IronOcr prend en charge 127 langues via des packs linguistiques NuGet distincts. L'ajout d'une langue nécessite une seule commande "dotnet add package IronOcr.Languages.{Language}". Il n'est pas nécessaire de placer manuellement des fichiers ou de configurer des chemins d'accès.
Comment installer IronOCR dans un projet .NET ?
Installation via NuGet : 'Install-Package IronOcr' dans la console du Package Manager ou 'dotnet add package IronOcr' dans le CLI. Les packs de langues supplémentaires sont installés de la même manière. Aucun programme d'installation du SDK n'est nécessaire.
IronOCR est-il adapté à Docker et aux déploiements conteneurisés, contrairement à LEADTOOLS OCR ?
Oui. IronOCR fonctionne dans les conteneurs Docker via son package NuGet. La clé de licence est définie via une variable d'environnement. Aucun fichier de licence, chemin d'accès au SDK ou montage de volume n'est nécessaire pour le moteur OCR lui-même.
Puis-je essayer IronOCR avant de l'acheter, par rapport à LEADTOOLS OCR ?
Oui. Le mode d'essai d'IronOcr traite les documents et renvoie les résultats de l'OCR avec un filigrane en surimpression sur la sortie. Vous pouvez vérifier la précision sur vos propres documents avant d'acheter une licence.
IronOCR prend-il en charge la lecture de codes-barres parallèlement à l'extraction de texte ?
IronOCR se concentre sur l'extraction de texte et l'OCR. Pour la lecture de codes-barres, Iron Software propose IronBarcode comme bibliothèque d'accompagnement. Les deux sont disponibles individuellement ou dans le cadre de l'offre groupée Iron Suite.
Est-il facile de migrer de LEADTOOLS OCR à IronOCR ?
La migration de LEADTOOLS OCR vers IronOcr implique généralement le remplacement des séquences d'initialisation par l'instanciation d'IronTesseract, la suppression de la gestion du cycle de vie de COM et la mise à jour des appels d'API. La plupart des migrations réduisent considérablement la complexité du code.

