Passer au contenu du pied de page
VIDéOS

Migration d'Asprise OCR vers IronOCR

Ce guide accompagne les développeurs .NET à chaque étape du remplacement d'Asprise OCR par IronOCR . Il aborde le remplacement mécanique des packages, les modifications d'espace de noms et les quatre modèles de migration de code qui représentent la majorité de l'utilisation d'Asprise dans les applications .NET de production. Ce produit s'adresse aux développeurs qui ont déjà décidé de migrer et qui ont besoin d'un plan d'action concret.

Pourquoi migrer depuis Asprise OCR?

Asprise OCR a été conçu initialement comme un produit Java. L'interface .NET n'est qu'une surcouche d'un moteur natif d'origine Java, et cette origine influence tous les aspects du comportement de la bibliothèque dans .NET , du déploiement à la conception de l'API en passant par les contraintes de licence.

Dépendance JRE et binaire natif. Asprise OCRfor .NET nécessite des binaires natifs spécifiques à la plateforme (aocr.dll, aocr_x64.dll, libaocr.so, libaocr.dylib) sur chaque machine où l'application s'exécute. Chaque fichier binaire doit correspondre exactement à la plateforme cible et à l'architecture du processus. Un conteneur Docker 64 bits construit avec la DLL 32 bits déclenche BadImageFormatException à l'exécution. Un déploiement Linux manquant libaocr.so de LD_LIBRARY_PATH déclenche DllNotFoundException. Aucune de ces erreurs ne se manifeste lors de la compilation. Chaque nouvelle cible de déploiement (un nouveau serveur, une nouvelle image de conteneur, un agent d'intégration continue) nécessite une extraction manuelle des binaires.

API de constantes de chaîne issue de l'héritage Java. Asprise expose des constantes entières pour le type de reconnaissance et le format de sortie : Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT, Ocr.OUTPUT_FORMAT_XML. Ces constantes correspondent directement à l'API basée sur les entiers du SDK Java. Les développeurs .NET ne bénéficient d'aucune indication IntelliSense sur les valeurs constantes valides, d'aucune sécurité à la compilation sur les combinaisons d'arguments et d'aucun objet résultat fortement typé. L'extraction d'une sortie structurée nécessite l'analyse manuelle des chaînes XML.

Aucune prise en charge asynchrone sans solution de contournement. Asprise ne fournit aucune API asynchrone native. Envelopper les appels synchrones d'Asprise dans Task.Run pour éviter le blocage des threads ASP.NET crée une pression sur le pool de threads et ne résout pas la restriction de licence qui interdit l'exécution concurrente sur les niveaux LITE et STANDARD. Les modèles asynchrones dans les applications .NET modernes (services en arrière-plan, points de terminaison d'API minimaux, Azure Functions) n'ont pas d'équivalent Asprise clair.

Le traitement TIFF multi-images nécessite un fractionnement manuel. Asprise fonctionne avec des fichiers image uniques. Le traitement d'un fichier TIFF multipage nécessite un code externe pour séparer les images en fichiers individuels, puis traiter chaque fichier en boucle. Aucune métadonnée d'image ni numérotation de page n'est conservée dans le fichier de sortie.

La restriction du nombre de threads empêche le déploiement en production. Les licences Lite (environ 299 $) et STANDARD (environ 699 $) limitent contractuellement l'exécution à un seul thread et un seul processus. ASP.NET Core traite toutes les requêtes HTTP sur un pool de threads. Chaque point de terminaison d'API Web qui appelle Asprise sur ces niveaux constitue une violation de licence dès la première requête simultanée. La mise à niveau vers Enterprise supprime cette restriction, mais nécessite de contacter le service commercial. Le prix n'est pas publié ; les estimations varient de 2 000 $ à plus de 5 000 $ selon l'étendue du déploiement.

La gestion des formats de sortie nécessite une analyse de chaîne. Lorsque OUTPUT_FORMAT_XML est spécifié, Asprise renvoie une chaîne XML brute. L'application est chargée de désérialiser cette chaîne de caractères, de valider sa structure et d'extraire les mots et leurs coordonnées. Les scores de confiance par mot sont intégrés dans les attributs XML. Il n'y a pas de modèle objet — seulement de la manipulation de chaînes de caractères.

Le problème fondamental

Asprise requiert une configuration binaire native adjacente à JRE avant que le premier appel OCR puisse s'exécuter. IronOCR ne nécessite rien d'autre qu'un package NuGet :

// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp();                              // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);  // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();                         // Must call or native memory leaks
// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp();                              // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST);  // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine();                         // Must call or native memory leaks
' Asprise: native binary must exist in PATH or application directory
' aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp()                              ' Static init — touches native binary
Dim ocr As New Ocr()
ocr.StartEngine("eng", Ocr.SPEED_FAST)   ' Allocates native engine memory
Dim text As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
ocr.StopEngine()                         ' Must call or native memory leaks
$vbLabelText   $csharpLabel
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
' IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim text As String = New IronTesseract().Read(imagePath).Text
$vbLabelText   $csharpLabel

Comparaison des fonctionnalités IronOCR et d'Asprise OCR

Le tableau ci-dessous récapitule les fonctionnalités les plus pertinentes pour les développeurs qui évaluent cette migration.

Fonction Asprise OCR IronOCR
Plateforme principale Java (hérité) .NET natif
Installation de NuGet Wrapper + DLL natives de la plateforme Paquet unique (IronOcr)
Binaire natif requis à l'exécution Oui (DLL par plateforme) Non
Style d'API .NET Constantes entières, retours de type chaîne Classes et énumérations fortement typées
IDisposable / using modèle Non mis en œuvre Oui (OcrInput)
OCR asynchrone Aucune prise en charge native Oui (ReadAsync)
Multithreading — Niveau Lite/STANDARD Interdit par licence Permis
Multithreading — tous niveaux Enterprise uniquement Tous les niveaux
Prise en charge de l'API Web ASP.NET Core Enterprise requise N'importe quel niveau
Azure Functions / AWS Lambda Enterprise requise N'importe quel niveau
Entrée PDF native Non Oui
Entrée TIFF multi-images Non (séparation manuelle des images) Oui (LoadImageFrames)
Entrée de tableau d'octets et de flux Limité Oui
Prétraitement d'image intégré Non Oui (9+ filtres)
Sortie PDF consultable Non Oui (SaveAsSearchablePdf)
Modèle d'objet de résultat structuré Non (chaîne XML uniquement) Oui (pages, paragraphes, mots, caractères)
Scores de confiance par mot Non (analyse des attributs XML) Oui (result.Confidence)
Coordonnées en pixels du mot analyse des attributs XML Propriétés fortement typées
Nombre de langues 20+ 125+
Sélection de langage fortement typée Non (codes de chaîne) Oui (OcrLanguage enum)
Lecture de codes-barres Oui (type de reconnaissance séparé) Oui (indicateur de configuration)
Exportation hOCR Non Oui
Déploiement multiplateforme Manuel binaire par plateforme NuGet gère toutes les plateformes
Docker / Linux / macOS Configuration manuelle LD_LIBRARY_PATH Fonctionne dès le départ
Compatibilité .NET Limité (pont Java) .NET Framework 4.6.2+, .NET 5-9
Prix ​​d'entrée pour l'utilisation du serveur Enterprise (~2 000 $ et plus) $999 (Lite, toutes fonctionnalités)
Type de licence Par niveau, contactez le service commercial pour les Enterprise Perpétuel (achat unique)

Démarrage rapide : Migration d'Asprise OCR vers IronOCR

Étape 1 : Remplacer le package NuGet

Supprimer Asprise OCR :

dotnet remove package asprise-ocr-api
dotnet remove package asprise-ocr-api
SHELL

Installez IronOCR depuis la page du package NuGet :

dotnet add package IronOcr

Étape 2 : Mise à jour des espaces de noms

Remplacez les espaces de noms Asprise par le namespace IronOCR :

// Before (Asprise)
using asprise.ocr;

// After (IronOCR)
using IronOcr;
// Before (Asprise)
using asprise.ocr;

// After (IronOCR)
using IronOcr;
Imports IronOcr
$vbLabelText   $csharpLabel

Étape 3 : initialisation de la licence

Ajoutez l'assignation de la clé de licence au démarrage de l'application — dans Program.cs avant tout appel OCR, dans Startup.Configure, ou dans un constructeur statique :

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Une clé d'essai gratuite est disponible sur la page de licence d' IronOCR . Lors des phases de développement et d'évaluation, IronOCR fonctionne sans clé et appose un filigrane d'essai sur la sortie.

Exemples de migration de code

Suppression de la configuration du chemin JRE et de l'initialisation du moteur

Les applications d'entreprise exécutées sous Linux ou macOS incluent généralement un code de démarrage qui définit le chemin du JRE ou valide la présence du binaire natif avant tout travail d'OCR. Cette infrastructure n'a pas d'équivalent dans IronOCR.

Approche OCR d'Asprise :

// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
    // Validate native library is reachable before first use
    string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
        ? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
        : RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
            ? "/usr/lib/libaocr.so"
            : "/usr/local/lib/libaocr.dylib";

    if (!File.Exists(nativePath))
        throw new FileNotFoundException(
            $"Asprise native binary not found: {nativePath}. " +
            "Deploy the correct platform binary before starting.");

    // Static global init — must run before any Ocr instance is created
    Ocr.SetUp();
}
// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
    // Validate native library is reachable before first use
    string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
        ? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
        : RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
            ? "/usr/lib/libaocr.so"
            : "/usr/local/lib/libaocr.dylib";

    if (!File.Exists(nativePath))
        throw new FileNotFoundException(
            $"Asprise native binary not found: {nativePath}. " +
            "Deploy the correct platform binary before starting.");

    // Static global init — must run before any Ocr instance is created
    Ocr.SetUp();
}
Imports System
Imports System.IO
Imports System.Runtime.InteropServices

' AppStartup.vb — native binary validation before accepting any requests
Public Module AppStartup
    Public Sub InitializeOcr()
        ' Validate native library is reachable before first use
        Dim nativePath As String = If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows),
                                      Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll"),
                                      If(RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
                                         "/usr/lib/libaocr.so",
                                         "/usr/local/lib/libaocr.dylib"))

        If Not File.Exists(nativePath) Then
            Throw New FileNotFoundException($"Asprise native binary not found: {nativePath}. " &
                                            "Deploy the correct platform binary before starting.")
        End If

        ' Static global init — must run before any Ocr instance is created
        Ocr.SetUp()
    End Sub
End Module
$vbLabelText   $csharpLabel

Approche IronOCR :

// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// That is it. Non binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// That is it. Non binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
' Program.vb — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

' That is it. Non binary validation, no path configuration, no SetUp() call.
' NuGet resolved the correct native runtime during package restore.
$vbLabelText   $csharpLabel

Le modèle Asprise est généralement de 15-30 lignes réparties sur plusieurs fichiers — un validateur de démarrage, un commutateur de plateforme, une exception avec un message de déploiement, et l'appel SetUp(). IronOCR remplace tout cela par une seule tâche. Le guide d'installation d'IronTesseract couvre les options de configuration de déploiement pour les environnements nécessitant des chemins d'accès personnalisés aux données tessdata ou un fonctionnement hors ligne.

Remplacement du format de sortie XML par des objets de résultat structurés

Asprise produit une sortie structurée sous forme de chaîne XML brute lorsque OUTPUT_FORMAT_XML est spécifié. L'extraction du texte, des coordonnées et du niveau de confiance à partir de cette chaîne de caractères nécessite un code d'analyse XML. IronOCR renvoie un graphe d'objets typés.

Approche OCR d'Asprise :

// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    string xmlOutput = ocr.Recognize(
        imagePath,
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_XML);   // Returns raw XML, not an object

    // Parse the XML manually to extract words and coordinates
    var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
    var words = doc.Descendants("word")
        .Select(w => new
        {
            Text       = (string)w.Attribute("text"),
            Confidence = (float)w.Attribute("confidence"),
            X          = (int)w.Attribute("x"),
            Y          = (int)w.Attribute("y"),
        })
        .ToList();

    foreach (var word in words)
        Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
    ocr.StopEngine();
}
// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    string xmlOutput = ocr.Recognize(
        imagePath,
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_XML);   // Returns raw XML, not an object

    // Parse the XML manually to extract words and coordinates
    var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
    var words = doc.Descendants("word")
        .Select(w => new
        {
            Text       = (string)w.Attribute("text"),
            Confidence = (float)w.Attribute("confidence"),
            X          = (int)w.Attribute("x"),
            Y          = (int)w.Attribute("y"),
        })
        .ToList();

    foreach (var word in words)
        Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
    ocr.StopEngine();
}
Imports System.Xml.Linq

' Asprise: structured output is an XML string — must parse manually
Ocr.SetUp()
Dim ocr As New Ocr()
Try
    ocr.StartEngine("eng", Ocr.SPEED_FAST)
    Dim xmlOutput As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_XML) ' Returns raw XML, not an object

    ' Parse the XML manually to extract words and coordinates
    Dim doc As XDocument = XDocument.Parse(xmlOutput)
    Dim words = doc.Descendants("word") _
        .Select(Function(w) New With {
            .Text = CStr(w.Attribute("text")),
            .Confidence = CSng(w.Attribute("confidence")),
            .X = CInt(w.Attribute("x")),
            .Y = CInt(w.Attribute("y"))
        }) _
        .ToList()

    For Each word In words
        Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}")
Next
Finally
    ocr.StopEngine()
End Try
$vbLabelText   $csharpLabel

Approche IronOCR :

// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);

foreach (var page in result.Pages)
{
    foreach (var paragraph in page.Paragraphs)
    {
        foreach (var word in paragraph.Words)
        {
            Console.WriteLine(
                $"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
        }
    }
}
// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);

foreach (var page in result.Pages)
{
    foreach (var paragraph in page.Paragraphs)
    {
        foreach (var word in paragraph.Words)
        {
            Console.WriteLine(
                $"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
        }
    }
}
Imports IronOcr

' IronOCR: structured result is a typed object — no XML parsing
Dim result = New IronTesseract().Read(imagePath)

For Each page In result.Pages
    For Each paragraph In page.Paragraphs
        For Each word In paragraph.Words
            Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%")
        Next
    Next
Next
$vbLabelText   $csharpLabel

Aucune désérialisation XML, aucun transtypage d'attributs, aucune supposition de schéma. Le modèle d'objet OcrResult expose les pages, paragraphes, lignes, mots et caractères avec des propriétés typées. Le guide des résultats de lecture couvre l'intégralité de la hiérarchie et du système de coordonnées, y compris la manière de filtrer par seuil de confiance pour les flux de travail automatisés.

Traitement TIFF multi-images

Asprise accepte les fichiers image uniques. Un fichier TIFF multi-images — courant dans les flux de travail de numérisation de documents — doit être divisé en fichiers d'images individuelles avant qu'Asprise puisse le traiter. IronOCR accepte les TIFF multi-images directement via LoadImageFrames.

Approche OCR d'Asprise :

// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
    int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
    for (int i = 0; i < frameCount; i++)
    {
        tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
        string framePath = $"frame_{i}.png";
        tiff.Save(framePath);
        frameFiles.Add(framePath);
    }
}

// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    foreach (var framePath in frameFiles)
    {
        string pageText = ocr.Recognize(
            framePath,
            Ocr.RECOGNIZE_TYPE_TEXT,
            Ocr.OUTPUT_FORMAT_PLAINTEXT);
        allText.AppendLine(pageText);
    }
}
finally
{
    ocr.StopEngine();
    // Clean up temporary frame files
    foreach (var f in frameFiles)
        File.Delete(f);
}
Console.WriteLine(allText.ToString());
// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
    int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
    for (int i = 0; i < frameCount; i++)
    {
        tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
        string framePath = $"frame_{i}.png";
        tiff.Save(framePath);
        frameFiles.Add(framePath);
    }
}

// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    foreach (var framePath in frameFiles)
    {
        string pageText = ocr.Recognize(
            framePath,
            Ocr.RECOGNIZE_TYPE_TEXT,
            Ocr.OUTPUT_FORMAT_PLAINTEXT);
        allText.AppendLine(pageText);
    }
}
finally
{
    ocr.StopEngine();
    // Clean up temporary frame files
    foreach (var f in frameFiles)
        File.Delete(f);
}
Console.WriteLine(allText.ToString());
Imports System.Drawing
Imports System.Text
Imports System.IO

' Asprise: no multi-frame TIFF support — split frames externally first
' Using an external imaging library (e.g., System.Drawing or Magick.NET)
Dim frameFiles As New List(Of String)()
Using tiff As Image = Image.FromFile("scanned-batch.tiff")
    Dim frameCount As Integer = tiff.GetFrameCount(Imaging.FrameDimension.Page)
    For i As Integer = 0 To frameCount - 1
        tiff.SelectActiveFrame(Imaging.FrameDimension.Page, i)
        Dim framePath As String = $"frame_{i}.png"
        tiff.Save(framePath)
        frameFiles.Add(framePath)
    Next
End Using

' Now process each frame individually — sequential on LITE/STANDARD
Dim allText As New StringBuilder()
Ocr.SetUp()
Dim ocr As New Ocr()
Try
    ocr.StartEngine("eng", Ocr.SPEED_FAST)
    For Each framePath As String In frameFiles
        Dim pageText As String = ocr.Recognize(framePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
        allText.AppendLine(pageText)
    Next
Finally
    ocr.StopEngine()
    ' Clean up temporary frame files
    For Each f As String In frameFiles
        File.Delete(f)
    Next
End Try
Console.WriteLine(allText.ToString())
$vbLabelText   $csharpLabel

Approche IronOCR :

// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff");  // All frames, one call

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

// Access each page independently with its page number
foreach (var page in result.Pages)
    Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff");  // All frames, one call

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

// Access each page independently with its page number
foreach (var page in result.Pages)
    Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
Imports IronOcr

' IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
Using input As New OcrInput()
    input.LoadImageFrames("scanned-batch.tiff") ' All frames, one call

    Dim result = New IronTesseract().Read(input)

    ' Access each page independently with its page number
    For Each page In result.Pages
        Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
    Next
End Using
$vbLabelText   $csharpLabel

L'approche Asprise nécessite une dépendance à l'imagerie externe, une gestion des fichiers temporaires, un nettoyage manuel et un traitement séquentiel par image. IronOCR traite toutes les images en une seule passe. Le guide d'importation TIFF et GIF traite de la sélection de la plage d'images pour les fichiers TIFF volumineux lorsque seules certaines pages sont nécessaires.

Génération de PDF consultables

Asprise ne propose aucune fonctionnalité de sortie PDF consultable, quel que soit le niveau de licence. La création d'un PDF avec du texte OCR intégré à partir d'un document numérisé nécessite une bibliothèque PDF externe, une passe OCR séparée pour obtenir les positions du texte et une construction manuelle de la superposition. IronOCR génère des PDF consultables directement à partir du résultat de la reconnaissance.

Approche OCR d'Asprise :

// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    recognizedText = ocr.Recognize(
        "scanned-contract.jpg",
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_PLAINTEXT);   // Only plain text — no position data
}
finally
{
    ocr.StopEngine();
}

// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
    ocr.StartEngine("eng", Ocr.SPEED_FAST);
    recognizedText = ocr.Recognize(
        "scanned-contract.jpg",
        Ocr.RECOGNIZE_TYPE_TEXT,
        Ocr.OUTPUT_FORMAT_PLAINTEXT);   // Only plain text — no position data
}
finally
{
    ocr.StopEngine();
}

// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
' Asprise: no searchable PDF output — external PDF library required
' Step 1: OCR the document to get text
Ocr.SetUp()
Dim ocr As New Ocr()
Dim recognizedText As String
Try
    ocr.StartEngine("eng", Ocr.SPEED_FAST)
    recognizedText = ocr.Recognize( _
        "scanned-contract.jpg", _
        Ocr.RECOGNIZE_TYPE_TEXT, _
        Ocr.OUTPUT_FORMAT_PLAINTEXT)   ' Only plain text — no position data
Finally
    ocr.StopEngine()
End Try

' Step 2: Use an external PDF library to embed text over the image
' (iTextSharp, PdfSharp, or similar — adds another dependency and license)
' Text positioning requires coordinate data Asprise cannot provide in plain text mode
' ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone")
$vbLabelText   $csharpLabel

Approche IronOCR :

// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");

// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
    var batchResult = new IronTesseract().Read(imagePath);
    string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
    batchResult.SaveAsSearchablePdf(outputPath);
    Console.WriteLine($"Converted: {outputPath}");
}
// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");

// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
    var batchResult = new IronTesseract().Read(imagePath);
    string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
    batchResult.SaveAsSearchablePdf(outputPath);
    Console.WriteLine($"Converted: {outputPath}");
}
Imports System.IO
Imports IronOcr

' IronOCR: searchable PDF in two lines — no external PDF library
Dim result = New IronTesseract().Read("scanned-contract.jpg")
result.SaveAsSearchablePdf("searchable-contract.pdf")

' Batch: convert a folder of scanned images to searchable PDFs
For Each imagePath In Directory.GetFiles("scans", "*.jpg")
    Dim batchResult = New IronTesseract().Read(imagePath)
    Dim outputPath As String = Path.ChangeExtension(imagePath, ".searchable.pdf")
    batchResult.SaveAsSearchablePdf(outputPath)
    Console.WriteLine($"Converted: {outputPath}")
Next
$vbLabelText   $csharpLabel

Le PDF consultable contient l'image originale comme couche visuelle avec le texte OCR invisible superposé aux coordonnées correctes — le format standard pour les flux de travail d'archivage et de conformité. Consultez le guide pratique PDF consultable et l' exemple de PDF consultable pour connaître les options disponibles, notamment la sortie PDF/A pour l'archivage à long terme.

OCR asynchrone dans les applications Web

Asprise ne possède pas d'API asynchrone. Les développeurs l'intègrent dans les applications asynchrones .NET en enveloppant les appels synchrones dans Task.Run, ce qui consomme des threads du pool de threads et n'élimine pas le blocage. IronOCR fournit un chemin asynchrone natif.

Approche OCR d'Asprise :

// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    string tempPath = Path.GetTempFileName();
    await using (var fs = new FileStream(tempPath, FileMode.Create))
        await fileStream.CopyToAsync(fs);

    // Task.Run wraps synchronous Asprise — occupies a thread pool thread
    // Two concurrent requests still violate LITE/STANDARD license
    return await Task.Run(() =>
    {
        Ocr ocr = new Ocr();
        try
        {
            ocr.StartEngine("eng", Ocr.SPEED_FAST);
            return ocr.Recognize(
                tempPath,
                Ocr.RECOGNIZE_TYPE_TEXT,
                Ocr.OUTPUT_FORMAT_PLAINTEXT);
        }
        finally
        {
            ocr.StopEngine();
            File.Delete(tempPath);
        }
    });
}
// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    string tempPath = Path.GetTempFileName();
    await using (var fs = new FileStream(tempPath, FileMode.Create))
        await fileStream.CopyToAsync(fs);

    // Task.Run wraps synchronous Asprise — occupies a thread pool thread
    // Two concurrent requests still violate LITE/STANDARD license
    return await Task.Run(() =>
    {
        Ocr ocr = new Ocr();
        try
        {
            ocr.StartEngine("eng", Ocr.SPEED_FAST);
            return ocr.Recognize(
                tempPath,
                Ocr.RECOGNIZE_TYPE_TEXT,
                Ocr.OUTPUT_FORMAT_PLAINTEXT);
        }
        finally
        {
            ocr.StopEngine();
            File.Delete(tempPath);
        }
    });
}
Imports System.IO
Imports System.Threading.Tasks

' Asprise: no async API — must offload to Task.Run
' This blocks a thread pool thread during the entire OCR operation
' On LITE/STANDARD, concurrent Task.Run calls = license violation
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
    Dim tempPath As String = Path.GetTempFileName()
    Await Using fs As New FileStream(tempPath, FileMode.Create)
        Await fileStream.CopyToAsync(fs)
    End Using

    ' Task.Run wraps synchronous Asprise — occupies a thread pool thread
    ' Two concurrent requests still violate LITE/STANDARD license
    Return Await Task.Run(Function()
                              Dim ocr As New Ocr()
                              Try
                                  ocr.StartEngine("eng", Ocr.SPEED_FAST)
                                  Return ocr.Recognize(tempPath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
                              Finally
                                  ocr.StopEngine()
                                  File.Delete(tempPath)
                              End Try
                          End Function)
End Function
$vbLabelText   $csharpLabel

Approche IronOCR :

// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    using var input = new OcrInput();
    input.LoadImage(fileStream);       // Stream input directly — no temp file

    var ocr = new IronTesseract();
    var result = await ocr.ReadAsync(input);
    return result.Text;
}
// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
    using var input = new OcrInput();
    input.LoadImage(fileStream);       // Stream input directly — no temp file

    var ocr = new IronTesseract();
    var result = await ocr.ReadAsync(input);
    return result.Text;
}
Imports System.IO
Imports System.Threading.Tasks

' IronOCR: native async, concurrent requests permitted on all tiers
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
    Using input As New OcrInput()
        input.LoadImage(fileStream) ' Stream input directly — no temp file

        Dim ocr As New IronTesseract()
        Dim result = Await ocr.ReadAsync(input)
        Return result.Text
    End Using
End Function
$vbLabelText   $csharpLabel

La version IronOCR élimine l'écriture de fichiers temporaires, l'enveloppe Task.Run, et le comportement de blocage des threads. Plusieurs requêtes concurrentes créent chacune leur propre instance IronTesseract — la classe est sans état et chaque instance est indépendante. Le guide OCR asynchrone couvre les modèles ReadAsync et le support des jetons d'annulation pour les opérations de lot longue durée dans les services hébergés.

Référence de mappage de l'API Asprise OCRvers IronOCR

Asprise OCR Équivalent d'IronOCR
asprise.ocr espace de noms IronOcr espace de noms
Ocr.SetUp() Non requis
new Ocr() new IronTesseract()
ocr.StartEngine("eng", Ocr.SPEED_FAST) Non requis
ocr.StartEngine("eng+fra", speed) ocr.Language = OcrLanguage.English + OcrLanguage.French
ocr.Recognize(path, type, format) ocr.Read(path) ou ocr.Read(input)
Ocr.RECOGNIZE_TYPE_TEXT Comportement par défaut
Ocr.RECOGNIZE_TYPE_BARCODE ocr.Configuration.ReadBarCodes = true
Ocr.RECOGNIZE_TYPE_ALL ocr.Configuration.ReadBarCodes = true
Ocr.OUTPUT_FORMAT_PLAINTEXT result.Text
Ocr.OUTPUT_FORMAT_XML result.Pages / result.Pages[n].Words
Ocr.OUTPUT_FORMAT_PDF result.SaveAsSearchablePdf(path)
Ocr.SPEED_FASTEST ocr.Configuration.TesseractEngineMode réglage
Ocr.SPEED_FAST Configuration par défaut
Ocr.SPEED_SLOW Paramètres de configuration de plus haute précision
ocr.StopEngine() Non requis — OcrInput est IDisposable
result.StartsWith("ERROR:") vérification Gestion standard des exceptions .NET (try/catch)
DLL native de la plateforme (aocr_x64.dll) Package d'exécution NuGet (automatique)
Fichier temporaire manuel pour l'entrée de flux input.LoadImage(stream) directement
Bibliothèque externe pour TIFF multi-images input.LoadImageFrames(path)
Bibliothèque externe pour PDF consultable result.SaveAsSearchablePdf(path)

Problèmes de migration courants et solutions

Problème 1 : Exception DllNotFoundException après la suppression des binaires natifs

Asprise OCR : Supprimer le package NuGet Asprise sans supprimer les références binaires natives (dans les règles de copie des fichiers de projet, les instructions Docker COPY, ou les scripts de déploiement) peut provoquer la réapparition de DllNotFoundException à partir d'une configuration obsolète pointant vers un binaire inexistant.

Solution : Recherchez les artefacts de déploiement pour toute référence aux réglages aocr, libaocr, ou LD_LIBRARY_PATH et supprimez-les. IronOCR ne requiert aucune configuration particulière. Dans le Dockerfile :

# Remove: COPY aocr_x64.dll /app/
# Remove: ENV LD_LIBRARY_PATH=/app
# IronOCR: nothing to add — NuGet handles native runtime packaging
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish

Pour un déploiement multiplateforme, le guide de déploiement Docker couvre les exigences relatives à l'image de base pour IronOCR sur les conteneurs Linux.

Problème 2: La suppression manquante de Ocr.SetUp() perturbe le démarrage

Asprise OCR : Ocr.SetUp() effectue l'initialisation native globale. Certaines bases de code l'appellent dans un constructeur statique ou Startup.Configure. Après migration, supprimer l'espace de noms Asprise résout l'erreur de compilation, mais si SetUp() est enveloppé dans un try/catch qui supprime l'exception, le code peut compiler et s'exécuter silencieusement sans rien initialiser.

Solution : Recherchez tous les appels SetUp() et supprimez le bloc d'initialisation entier. Remplacez le hook de démarrage équivalent par l'attribution de la clé de licence IronOCR :

grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
SHELL
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();

// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();

// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Problème 3 : Le code d'analyse de la sortie XML n'a pas de remplacement direct

Asprise OCR : Le code qui analyse les chaînes OUTPUT_FORMAT_XML en utilisant XDocument, XmlReader, ou des modèles regex n'a pas de structure XML équivalente dans IronOCR. Le schéma XML produit par Asprise ne correspond pas directement au modèle objet d'IronOCR.

Solution : Remplacez le code d'analyse XML par un accès direct aux propriétés sur OcrResult. La cartographie est la suivante :

// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
    .Descendants("word")
    .Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });

// IronOCR object model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
    .SelectMany(p => p.Paragraphs)
    .SelectMany(para => para.Words)
    .Select(w => new { w.Text, w.X });
// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
    .Descendants("word")
    .Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });

// IronOCR object model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
    .SelectMany(p => p.Paragraphs)
    .SelectMany(para => para.Words)
    .Select(w => new { w.Text, w.X });
Imports System.Xml.Linq
Imports IronOcr

' Asprise XML parsing (remove)
Dim words = XDocument.Parse(xmlOutput) _
    .Descendants("word") _
    .Select(Function(w) New With {Key .Text = CType(w.Attribute("text"), String), Key .X = CType(w.Attribute("x"), Integer)})

' IronOCR object model (replace with)
Dim result = New IronTesseract().Read(imagePath)
Dim words = result.Pages _
    .SelectMany(Function(p) p.Paragraphs) _
    .SelectMany(Function(para) para.Words) _
    .Select(Function(w) New With {w.Text, w.X})
$vbLabelText   $csharpLabel

Le guide des résultats de lecture couvre l'intégralité de la hiérarchie des objets, y compris les données au niveau des caractères avec leurs cadres de délimitation.

Problème 4 : Les wrappers Task.Run provoquent l'épuisement du pool de threads

Asprise OCR : Les applications web à haute concurrence enveloppant Asprise dans Task.Run peuvent épuiser le pool de threads lorsque le volume d'OCR augmente. Chaque Task.Run en file d'attente conserve un thread du pool de threads pendant toute la durée de l'opération OCR.

Solution : Remplacez Task.Run(() =&gt; { asprise... }) modèles avec appels asynchrones IronOCR natifs. Chaque instance IronTesseract est indépendante — créez-en une par requête :

// Remove: await Task.Run(() => { ocr.Recognize(...) });

// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
// Remove: await Task.Run(() => { ocr.Recognize(...) });

// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
Imports IronTesseract

Using input As New OcrInput()
    input.LoadImage(stream)
    Dim result = Await (New IronTesseract()).ReadAsync(input)
    Return result.Text
End Using
$vbLabelText   $csharpLabel

Problème 5 : Validation du code de langage basé sur les chaînes de caractères

Asprise OCR : Les codes de langue sont passés sous forme de chaînes ("eng", "fra", "eng+fra"). Les applications qui valident ces chaînes à l'exécution — en vérifiant par rapport à une liste codée en dur, en lisant depuis la configuration — doivent être mises à jour lorsque le format des chaînes change pour l'enum OcrLanguage.

Solution : Remplacez les paramètres de langue de chaîne par les valeurs enum OcrLanguage. La sélection de langue dirigée par la configuration s'aligne clairement sur Enum.Parse :

// Asprise string-based (remove)
string language = config["OcrLanguage"];  // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);

// IronOCR enum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]);  // e.g. "English"
var result = ocr.Read(input);
// Asprise string-based (remove)
string language = config["OcrLanguage"];  // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);

// IronOCR enum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]);  // e.g. "English"
var result = ocr.Read(input);
' Asprise string-based (remove)
Dim language As String = config("OcrLanguage")  ' e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST)

' IronOCR enum-based (replace with)
' For single language from config:
Dim ocr As New IronTesseract()
ocr.Language = [Enum].Parse(Of OcrLanguage)(config("OcrLanguage"))  ' e.g. "English"
Dim result = ocr.Read(input)
$vbLabelText   $csharpLabel

Le guide des langues multiples répertorie toutes les valeurs enum OcrLanguage valides et leurs packages de langue NuGet correspondants.

Problème n°6 : La logique de vérification du niveau de licence n'est plus nécessaire

OCR Asprise : Certains codes sources en production intègrent des contrôles d'exécution qui détectent le niveau de licence Asprise et sérialisent le travail d'OCR lors d'une exécution inférieure à la Enterprise. Ces protections empêchent les violations de licence, mais complexifient le processus et réduisent le débit.

Solution : Supprimer toutes les protections de détection de niveau et de sérialisation. IronOCR n'impose aucune restriction de thread à aucun niveau. Les modèles ConcurrentQueue, SemaphoreSlim, ou à répartiteur monofilaire utilisés pour sérialiser les appels Asprise ne servent à rien après migration :

// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();

// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
    var text = new IronTesseract().Read(path).Text;
    results[path] = text;
});
// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();

// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
    var text = new IronTesseract().Read(path).Text;
    results[path] = text;
});
Imports System.Threading.Tasks

' IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, Sub(path)
    Dim text = (New IronTesseract()).Read(path).Text
    results(path) = text
End Sub)
$vbLabelText   $csharpLabel

Liste de contrôle de migration OCR d'entreprise

Pré-migration

Avant d'écrire tout code de remplacement, auditez le code source pour toute utilisation d'Asprise :

# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .

# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .

# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .

# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .

# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .

# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .

# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .

# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .

# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .

# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .

# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
SHELL

Inventaire des résultats :

  • Comptez les fichiers important asprise.ocr — ils nécessitent tous des mises à jour de l'espace de noms
  • Listez chaque emplacement d'appel StartEngine — chacun devient un appel Read
  • Identifier le code d'analyse de la sortie XML — chaque bloc nécessite un remplacement du modèle objet
  • Notez la présence de protections de niveau de licence ou de dispositifs de sérialisation — ceux-ci sont supprimables
  • Localiser les scripts de déploiement binaires natifs et la configuration du conteneur

Migration de code

  1. Supprimez le package NuGet asprise-ocr-api de tous les projets
  2. Installez le package NuGet IronOcr dans chaque projet effectuant une OCR
  3. Remplacez using asprise.ocr par using IronOcr dans tous les fichiers
  4. Ajoutez IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY" au démarrage de l'application
  5. Supprimez les appels Ocr.SetUp() de tout le code de démarrage et d'initialisation
  6. Remplacez chaque bloc Ocr.StartEngine / Recognize / StopEngine par new IronTesseract().Read(path).Text
  7. Remplacez les blocs d'analyse OUTPUT_FORMAT_XML par les parcours d'objets result.Pages
  8. Remplacez les solutions de contournement OUTPUT_FORMAT_PDF par result.SaveAsSearchablePdf(path)
  9. Remplacez le code de séparation TIFF multi-images par input.LoadImageFrames(tiffPath)
  10. Remplacez les enveloppes basées sur les flux Task.Run par await ocr.ReadAsync(input)
  11. Supprimez SemaphoreSlim ou les gardes de sérialisation qui protégeaient Asprise d'une utilisation concurrente
  12. Supprimez les instructions de copie binaire native des fichiers .csproj et Dockerfiles
  13. Supprimez les paramètres LD_LIBRARY_PATH de la configuration environnementale et des scripts CI
  14. Remplacez les codes de langue de chaîne ("eng", "eng+fra") par les valeurs enum OcrLanguage
  15. Remplacez les vérifications result.StartsWith("ERROR:") par des blocs try/catch

Après la migration

  • Vérifiez que dotnet build se termine sans avertissements concernant les bibliothèques natives manquantes
  • Confirmez qu'aucun DllNotFoundException ou BadImageFormatException ne se produit au démarrage dans tous les environnements cibles (Windows, Linux, Docker)
  • Effectuez une reconnaissance optique de caractères (OCR) sur une image représentative et vérifiez que le texte produit correspond à la référence avant migration.
  • Tester le traitement TIFF multi-images et vérifier que toutes les pages sont renvoyées avec les numéros de page corrects.
  • Générer un PDF consultable et vérifier que le texte est sélectionnable et consultable dans une visionneuse PDF.
  • Envoyer simultanément des requêtes HTTP à tout point de terminaison d'API utilisant la reconnaissance optique de caractères (OCR) et confirmer que toutes les requêtes sont terminées sans erreur.
  • Vérifier que les points de terminaison asynchrones renvoient des résultats sans blocage en cas de charge concurrente
  • Vérifier que l'extraction de données structurées (coordonnées des mots et niveau de confiance) produit un résultat correct sur un document connu.
  • Vérifiez l'utilisation de la mémoire de l'application au fil du temps pour confirmer l'absence de fuites de mémoire natives (qui étaient auparavant causées par des appels StopEngine() manqués)
  • Exécutez l'application sous Linux ou dans un conteneur Docker pour confirmer que le déploiement multiplateforme fonctionne sans configuration binaire.

Principaux avantages de la migration vers IronOCR

Le déploiement se résume à une seule référence NuGet . Après la migration, chaque cible de déploiement (postes de travail de développement, serveurs de préproduction, conteneurs Linux, agents d'intégration continue) installe le même package avec la même commande. Il n'y a pas de logique de détection de plateforme, pas de source binaire spécifique à l'architecture et pas de configuration de chemin d'exécution. Une image Docker qui nécessitait auparavant des instructions de copie binaire manuelles ne nécessite maintenant rien au-delà de dotnet restore. Les guides de déploiement Linux et Azure contiennent des notes spécifiques à l'environnement, le cas échéant.

Tous les niveaux de licence débloquent le déploiement de niveau serveur. La licence Lite $999 prend en charge les API Web ASP.NET Core, les services Windows, les fonctions Azure, AWS Lambda et toute autre charge de travail .NET multi-threadée. La fonctionnalité de gestion des threads de niveau ENTREPRISE, facturée entre 2 000 et plus de 5 000 dollars par Asprise, est incluse dans tous les niveaux IronOCR . Les équipes qui migrent d'Asprise Enterprise vers IronOCR Lite réduisent leurs coûts de licence OCR tout en bénéficiant de fonctionnalités Enterprise ne fournissait pas : PDF natif, sortie structurée, génération de PDF consultables et 125 langues.

Les résultats OCR structurés remplacent l'analyse de chaînes XML. Le modèle d'objet OcrResult expose une hiérarchie de document complète : pages, paragraphes, lignes, mots et caractères, chacun avec des coordonnées de boîtes englobantes précises en pixels et des scores de confiance. Le code qui analysait auparavant les chaînes XML Asprise avec XDocument ou des expressions régulières permet désormais un accès direct aux propriétés. La page présentant les résultats de la reconnaissance optique de caractères (OCR) aborde les systèmes de coordonnées et explique comment filtrer les résultats par niveau de confiance pour les contrôles qualité automatisés.

Le prétraitement intégré élimine les dépendances d'imagerie externes. Le pipeline de prétraitement disponible via OcrInputDeskew, DeNoise, Contrast, Binarize, Sharpen, Dilate, Erode, Scale, Invert, et DeepCleanBackgroundNoise — élimine la bibliothèque d'imagerie externe que nécessitent les intégrations Asprise. La suppression de cette dépendance élimine une préoccupation de licence, réduit l'empreinte de construction et place la configuration de prétraitement directement adjacente à la configuration OCR dans le même fichier de code. La page des fonctionnalités de prétraitement et le guide de correction de qualité d'image couvrent quand appliquer chaque filtre et les gains de précision mesurables que chacun fournit sur les scans de faible qualité.

Async natif et véritable parallélisme améliorent le débit. ReadAsync s'intègre dans le modèle standard async/await sans blocage du pool de threads. Le traitement par lots en parallèle avec Parallel.ForEach ou PLINQ s'adapte linéairement avec les cœurs disponibles. Un lot de documents qu'Asprise Lite/STANDARD a forcé à exécuter de manière séquentielle — 100 documents à 2 secondes chacun prennent plus de 3 minutes — s'exécute en environ 25 secondes sur une machine à 8 cœurs avec IronOCR. L'exemple de multithreading montre des modèles de débit parallèle et comment utiliser ConcurrentBag pour la collecte de résultats thread-safe.

125+ langues sans distribution binaire. Les packs de langue s'installent comme des packages NuGet — dotnet add package IronOcr.Languages.Arabic, dotnet add package IronOcr.Languages.Japanese — et se déploient avec l'application comme toute autre dépendance. Aucun dossier tessdata à remplir manuellement, aucun fichier binaire de langue à localiser et aucune configuration de chemin d'accès requise sur la machine cible. L' index des langues répertorie les plus de 125 modules linguistiques disponibles.

Veuillez noterAsprise OCR, PDFSharp, Tesseract et iText sont des marques déposées de leurs propriétaires respectifs. Ce site n'est pas affilié, approuvé ou sponsorisé par Asprise, Google, empira Software GmbH, ou iText Group. Tous les noms de produits, logos et marques sont la propriété de leurs propriétaires respectifs. Les comparaisons sont à titre informatif uniquement et reflètent les informations publiquement disponibles au moment de l'écriture.

Questions Fréquemment Posées

Pourquoi devrais-je migrer d'Asprise OCR SDK vers IronOCR ?

Parmi les motivations communes, citons l'élimination de la complexité de l'interopérabilité COM, le remplacement de la gestion des licences basée sur les fichiers, l'absence de facturation à la page, l'activation du déploiement Docker/conteneur et l'adoption d'un flux de travail NuGet-natif qui s'intègre à l'outillage .NET standard.

Quels sont les principaux changements de code lors de la migration d'Asprise OCR SDK vers IronOCR ?

Remplacer les séquences d'initialisation d'Asprise OCR par l'instanciation d'IronTesseract, supprimer la gestion du cycle de vie de COM (modèles explicites Create/Load/Close) et mettre à jour les noms des propriétés des résultats. Le résultat est une réduction significative du nombre de lignes de code.

Comment installer IronOCR pour commencer la migration ?

Exécutez "Install-Package IronOcr" dans la console du Package Manager ou "dotnet add package IronOcr" dans le CLI. Les packs de langues sont des paquets distincts : 'dotnet add package IronOcr.Languages.French' pour le français, par exemple.

IronOCR offre-t-il la même précision d'OCR qu'Asprise OCR SDK pour les documents commerciaux standard ?

IronOcr atteint un niveau de précision élevé pour les contenus commerciaux standard, notamment les factures, les contrats, les reçus et les formulaires dactylographiés. Les filtres de prétraitement d'image (désalignement, suppression du bruit, amélioration du contraste) améliorent encore la reconnaissance sur des données dégradées.

Comment IronOCR gère-t-il les données linguistiques qu'Asprise OCR SDK installe séparément ?

Les données linguistiques de l'IronOcr sont distribuées sous forme de packages NuGet. 'dotnet add package IronOcr.Languages.German' installe la prise en charge de l'allemand. Il n'y a pas de placement manuel de fichiers ou de chemins d'accès aux répertoires.

La migration d'Asprise OCR SDK vers IronOCR nécessite-t-elle des changements au niveau de l'infrastructure de déploiement ?

IronOcr nécessite moins de changements d'infrastructure que le SDK OCR d'Asprise. Il n'y a pas de chemin binaire pour le SDK, de placement de fichier de licence ou de configuration de serveur de licence. Le paquet NuGet contient le moteur OCR complet, et la clé de licence est une chaîne de caractères définie dans le code de l'application.

Comment configurer les licences IronOCR après la migration ?

Attribuer IronOcr.License.LicenseKey = "YOUR-KEY" dans le code de démarrage de l'application. Dans Docker ou Kubernetes, stockez la clé dans une variable d'environnement et lisez-la au démarrage. Utilisez License.IsValidLicense pour valider avant d'accepter le trafic.

IronOcr peut-il traiter les PDF de la même manière qu'Asprise OCR ?

Oui, IronOCR lit aussi bien les PDF natifs que les PDF numérisés. Instanciez IronTesseract, appelez ocr.Read(input) où l'input est un chemin PDF ou OcrPdfInput, et itérez les pages OcrResult. Aucun pipeline de rendu PDF séparé n'est nécessaire.

Comment IronOcr gère-t-il le threading dans le cadre d'un traitement à haut volume ?

IronTesseract est sûr pour l'instanciation par thread. Créez une instance par thread dans un Parallel.ForEach ou un Task pool, exécutez l'OCR simultanément et disposez de chaque instance lorsque vous avez terminé. Aucun état global ou verrouillage n'est nécessaire.

Quels formats de sortie IronOCR prend-il en charge après l'extraction du texte ?

IronOCR renvoie des résultats structurés comprenant le texte, les coordonnées des mots, les scores de confiance et la structure des pages. Les options d'exportation comprennent le texte brut, le PDF interrogeable et les objets de résultats structurés pour le traitement en aval.

La tarification d'IronOCR est-elle plus prévisible que celle d'Asprise OCR SDK pour la mise à l'échelle des charges de travail ?

IronOCR utilise des licences perpétuelles forfaitaires sans frais par page ou par volume. Que vous traitiez 10 000 ou 10 millions de pages, le coût de la licence reste constant. Les options de licence en volume et en équipe sont disponibles sur la page de tarification d'IronOcr.

Qu'advient-il de mes tests existants après la migration d'Asprise OCR SDK vers IronOCR ?

Les tests qui vérifient le contenu du texte extrait doivent continuer à passer après la migration. Les tests qui valident les modèles d'appel d'API ou le cycle de vie des objets COM devront être mis à jour pour refléter le modèle d'initialisation et de résultat plus simple d'IronOcr.

Kannaopat Udonpant
Ingénieur logiciel
Avant de devenir ingénieur logiciel, Kannapat a obtenu un doctorat en ressources environnementales à l'université d'Hokkaido au Japon. Pendant qu'il poursuivait son diplôme, Kannapat est également devenu membre du laboratoire de robotique de véhicules, qui fait partie du département de bioproduction. En 2022, il a utilisé ses compé...
Lire la suite

Équipe de soutien Iron

Nous sommes en ligne 24 heures sur 24, 5 jours sur 7.
Chat
Email
Appelez-moi