IRONSOFTWAREHOME
VIDÉOS

Migration de TesseractOcrMaui vers IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 août 2026

Ce guide présente une migration complète de TesseractOcrMauivers IronOCR, avec des exemples de code avant/après pour chaque étape. Il s'adresse aux développeurs qui ont déjà décidé de s'affranchir des contraintes de la plateforme MAUI et qui ont besoin d'une transition systématique vers une bibliothèque fonctionnant de manière identique dans les applications mobiles, les API côté serveur, les workers en arrière-plan et les fonctions cloud. Aucune lecture préalable de l'article comparatif n'est requise.

Pourquoi migrer depuis TesseractOcrMaui

TesseractOcrMaui a été conçu pour combler une lacune réelle : les wrappers .NET Tesseract existants ne pouvaient pas résoudre seuls les problèmes d'interopérabilité avec les plateformes mobiles. Pour un prototype MAUI pur sans empreinte serveur, il comble cette lacune. Les problèmes apparaissent dès que le produit dépasse ce champ d'application restreint.

Les frameworks cibles uniquement MAUI empêchent le partage de code. TesseractOcrMauifournit des cibles pour net8.0-ios, net8.0-android, et net8.0-windows — tous des monikers de plateforme MAUI. Le package ne contient pas de net8.0, pas de netstandard2.1, aucune cible compatible serveur. Le fait de le référencer à partir d'une bibliothèque de classes, d'un projet .NET Core ou d'une fonction Azure génère une erreur de compilation. Il n'existe aucune solution de contournement : l'architecture du package ne permet pas son exécution en dehors d'un hôte MAUI. Chaque fois que le besoin d'OCR se présente dans un contexte non-MAUI, une deuxième bibliothèque doit être introduite et maintenue en parallèle.

Couplage obligatoire de l'injection de dépendance avec MAUI. L'appel AddTesseractOcr() dans MauiProgram.cs connecte ITesseract au fournisseur de service MAUI. Il n'y a pas de méthode factory, pas de point d'entrée statique et pas de constructeur en dehors de ce graphe DI. Cela signifie que la logique OCR ne peut pas être extraite dans une bibliothèque de classes portable — chaque classe qui utilise ITesseract dans son constructeur est verrouillée à l'hôte de l'application MAUI pour toute sa durée de vie.

Aucune entrée PDF à aucun niveau. Les documents PDF sont le format le plus courant pour les contrats, factures et documents d'identité numérisés. TesseractOcrMauigénère NotSupportedException pour toute entrée PDF. Le traitement d'un PDF nécessite l'ajout d'une bibliothèque de rendu PDF distincte, l'écriture d'un code d'extraction d'images page par page, la gestion des fichiers temporaires dans le cache de l'appareil et leur nettoyage après chaque appel. Cela représente plus de 100 lignes de code d'infrastructure avant qu'un seul appel OCR ne s'exécute — et cela ne fonctionne toujours que sur MAUI.

Pas de prétraitement intégré pour les images du monde réel. Les appareils photo des mobiles produisent des images présentant une rotation, du bruit de capteur et une résolution (DPI) variable selon les modèles d'appareils. TesseractOcrMauitransmet les images directement au moteur Tesseract sans aucun prétraitement. Les équipes qui ont besoin d'une plus grande précision doivent ajouter SkiaSharp ou ImageSharp, implémenter manuellement des algorithmes de redressement et de débruitage, écrire un système de gestion des fichiers temporaires et tester le tout sur différentes variantes d'appareils iOS et Android. La plupart l'ignorent. La précision des captures réelles sur mobile en pâtit par conséquent.

Risque lié à la maintenance par un seul développeur sur une dépendance de production. TesseractOcrMauiest maintenu par un seul développeur. Il n'y a pas d'entreprise derrière ce projet, pas de SLA, pas d'engagement en matière de correctifs de sécurité, et pas de procédure d'escalade au-delà d'un ticket GitHub. Pour les applications de production dans les secteurs réglementés — finance, santé, juridique —, une bibliothèque gérée par des bénévoles et comptant environ 33 900 téléchargements NuGet au total ne constitue pas une dépendance acceptable.

Le problème fondamental

TesseractOcrMaui ne se compile qu'au sein d'un projet MAUI. Dès qu'un autre type de projet nécessite l'OCR, l'architecture s'effondre :

// TesseractOcrMaui: wired to MAUI host — cannot escape to a shared library
// This code compiles only inside a .NET MAUI application
public class OcrService
{
    private readonly ITesseract _tesseract; // resolved from MAUI DI — no other source exists

    public OcrService(ITesseract tesseract) { _tesseract = tesseract; }

    public async Task<string> ReadAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng"); // traineddata must be bundled as MauiAsset
        var result = await _tesseract.RecognizeTextAsync(imagePath);
        return result.Success ? result.RecognizedText : string.Empty;
    }
    // Cannot reference this class from ASP.NET Core, Azure Functions, or Docker
}
C#
// IronOCR: plain instantiable class — compiles in any .NET project type
public class OcrService
{
    private readonly IronTesseract _ocr = new IronTesseract(); // no DI, no MAUI host

    public string Read(string imagePath)
    {
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return _ocr.Read(input).Text;
    }
    // Place this in a netstandard2.1 library — reference from MAUI, API, and Functions together
}
C#

IronOCR vs TesseractOcrMaui: comparaison des fonctionnalités

Le tableau ci-dessous présente les différences de fonctionnalités pertinentes pour les équipes évaluant cette migration.

FonctionTesseractOcrMauiIronOCR
.NET MAUI (iOS)OuiOui (IronOcr.iOS)
.NET MAUI (Android)OuiOui (IronOcr.Android)
.NET MAUI (Windows)OuiOui
ASP.NET CoreNonOui
Azure FunctionsNonOui
AWS LambdaNonOui
Docker / Conteneurs LinuxNonOui
Applications consoleNonOui
WPF / WinFormsNonOui
Bibliothèque de classes .NET partagéeNonOui
Entrée PDF (native)NonOui
Fichier PDF protégé par mot de passeNonOui
Entrée du fluxNonOui
Entrée de tableau d'octetsNonOui
Entrée TIFF multipageNonOui
Sortie PDF consultableNonOui
Exportation hOCRNonOui
redressement automatiqueNonOui
Débruitage automatiqueNonOui
Amélioration du contrasteNonOui
BinarisationNonOui
OCR basé sur la régionNonOui
Lecture de codes-barres lors de la reconnaissance optique de caractères (OCR)NonOui
Coordonnées au niveau du motNonOui
Multilingue simultanéNonOui
Langues prises en chargeDonnées d'entraînement regroupées manuellementPlus de 125 packages NuGet
Sécurité du filManuelIntégré
Soutien commercialAucun (développeur unique)Oui (Iron Software)
Licence d'utilisationApache 2.0 (gratuit)Perpétuel à partir de $999
Téléchargements NuGet~33 900Plus de 5,3 millions

Guide de démarrage rapide : migration de TesseractOcrMauivers IronOCR

Étape 1 : Remplacer le package NuGet

Supprimer TesseractOcrMauidu projet MAUI :

dotnet remove package TesseractOcrMaui
SHELL

Installez IronOCR. Pour les projets MAUI, ajoutez les paquets spécifiques à la plateforme en plus du paquet principal :

dotnet add package IronOcr, IronOcr.Android, IronOcr.iOS

Pour les projets côté serveur (ASP.NET Core, Azure Functions, console) :

dotnet add package IronOcr

La page du package NuGet IronOCR répertorie tous les packages de plateformes disponibles.

Étape 2 : Mise à jour des espaces de noms

Remplacez les espaces de noms TesseractOcrMauipar l'espace de noms IronOCR :

// Before (TesseractOcrMaui)
using TesseractOcrMaui;
using TesseractOcrMaui.Results;
using Microsoft.Maui.Storage;

// After (IronOCR)
using IronOcr;
C#

Étape 3 : initialisation de la licence

Ajoutez l'initialisation de la licence au démarrage de l'application. Dans une application MAUI, cela se fait dans MauiProgram.cs; dans ASP.NET Core, cela se fait dans Program.cs :

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

Exemples de migration de code

Remplacement de l'enregistrement de l'injection de dépendances MAUI

TesseractOcrMaui nécessite l'enregistrement du moteur OCR via le fournisseur de services MAUI. La suppression de cet enregistrement constitue la première étape architecturale, car c'est ce qui lie tout le code OCR ultérieur à l'hôte MAUI.

Approche de TesseractOcrMaui:

// MauiProgram.cs — OCR engine registered here; nowhere else resolves it
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();

        // Binds OCR to MAUI DI — no standalone path exists after this
        builder.Services.AddTesseractOcr();

        return builder.Build();
    }
}

// Any class that needs OCR must receive ITesseract from the MAUI container
public class InvoicePageViewModel
{
    private readonly ITesseract _tesseract;

    public InvoicePageViewModel(ITesseract tesseract)
    {
        _tesseract = tesseract; // fails to construct outside MAUI host
    }

    public async Task<string> ScanInvoiceAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var result = await _tesseract.RecognizeTextAsync(imagePath);
        return result.RecognizedText ?? string.Empty;
    }
}
C#

Approche IronOCR :

// MauiProgram.cs — license only; no DI registration needed
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();

        // One-line initialization — works for all project types
        IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

        return builder.Build();
    }
}

// Non constructor injection needed — IronTesseract instantiates directly
public class InvoicePageViewModel
{
    public string ScanInvoice(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return ocr.Read(input).Text;
    }
}
C#

Supprimer AddTesseractOcr() élimine le couplage DI de MAUI. La classe IronTesseract a un constructeur public sans paramètres et ne possède aucune dépendance à la plateforme — elle peut être instanciée n'importe où. Consultez le guide d'installation d'IronTesseract pour connaître les options d'initialisation, notamment le mode du moteur et la configuration de la langue.

Déplacement de la logique OCR vers une bibliothèque de classes partagée

Avec TesseractOcrMaui, le partage de la logique OCR entre différents types de projets est structurellement impossible. Avec IronOCR, le chemin de migration est simple : extrayez le service dans une bibliothèque de classes .NET Standard 2.1 ou net8.0 et référencez-le depuis chaque projet dans la solution.

Approche de TesseractOcrMaui:

// This service CANNOT be extracted to a shared library.
// It compiles only in a project that references TesseractOcrMaui,
// which only has MAUI platform targets.
//
// Result: every non-MAUI project must use a different OCR library,
// duplicating language config, error handling, and accuracy tuning.

public class DocumentOcrService
{
    private readonly ITesseract _tesseract; // MAUI DI only

    public DocumentOcrService(ITesseract tesseract)
    {
        _tesseract = tesseract;
    }

    public async Task<string> ProcessDocumentAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var result = await _tesseract.RecognizeTextAsync(imagePath);
        return result.Success ? result.RecognizedText : string.Empty;
    }
    // Server team writes their own version using a different library
    // Two codebases, two accuracy profiles, two maintenance tracks
}
C#

Approche IronOCR :

// Place this in: MyCompany.OcrCore (net8.0 or netstandard2.1 class library)
// Reference from: MyCompany.MauiApp, MyCompany.Api, MyCompany.BatchWorker

using IronOcr;

namespace MyCompany.OcrCore
{
    public class DocumentOcrService
    {
        private readonly IronTesseract _ocr;

        public DocumentOcrService()
        {
            _ocr = new IronTesseract();
        }

        public string ProcessDocument(string imagePath)
        {
            using var input = new OcrInput();
            input.LoadImage(imagePath);
            input.Deskew();
            input.DeNoise();
            return _ocr.Read(input).Text;
        }

        public string ProcessDocumentFromBytes(byte[] imageData)
        {
            using var input = new OcrInput();
            input.LoadImage(imageData);
            input.Deskew();
            input.DeNoise();
            return _ocr.Read(input).Text;
        }

        public string ProcessDocumentFromStream(Stream imageStream)
        {
            using var input = new OcrInput();
            input.LoadImage(imageStream);
            return _ocr.Read(input).Text;
        }
    }
}
C#

Une bibliothèque de classes, un ensemble de tests, un profil de précision. L'application MAUI appelle ProcessDocument(photoPath), l'API ASP.NET Coreappelle ProcessDocumentFromBytes(uploadedBytes), et la fonction Azure appelle ProcessDocumentFromStream(blobStream) — tous soutenus par la même implémentation. Le guide d'entrée de flux et le guide d'entrée d'images documentent toutes les variantes de chargement OcrInput.

Activation de l'OCR côté serveur dans ASP.NET Core

TesseractOcrMaui ne peut pas être référencé depuis un projet ASP.NET Core. Les équipes qui ajoutent un point de terminaison de téléchargement de documents sont obligées de se tourner vers une bibliothèque complètement différente. IronOCR s'exécute sous ASP.NET Coresans aucune modification de configuration autre que la clé de licence.

Approche de TesseractOcrMaui:

// ASP.NET CoreWeb API — TesseractOcrMauiCANNOT be used here.
// The package has no net8.0 or netstandard target.
// Referencing it produces: "The given project does not support targeting net8.0-ios/android/windows."
//
// Team is forced to add a second OCR library — Tesseract charlesw wrapper,
// a cloud API, or another solution — creating a split codebase.

[ApiController]
[Route("api/[controller]")]
public class DocumentsController : ControllerBase
{
    // Cannot inject ITesseract here — no MAUI host, no MAUI DI container
    // Must use a completely different OCR library for server-side processing
}
C#

Approche IronOCR :

// ASP.NET Core— IronOCR works without modification
using IronOcr;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class DocumentsController : ControllerBase
{
    [HttpPost("extract-text")]
    public async Task<IActionResult> ExtractText(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("No file uploaded.");

        var ocr = new IronTesseract();
        using var input = new OcrInput();

        // Load directly from the upload stream — no temp files
        using var stream = file.OpenReadStream();

        if (file.ContentType == "application/pdf")
            input.LoadPdf(stream);
        else
            input.LoadImage(stream);

        input.Deskew();
        input.DeNoise();

        var result = ocr.Read(input);

        return Ok(new
        {
            text = result.Text,
            confidence = result.Confidence,
            pageCount = result.Pages.Count()
        });
    }

    [HttpPost("extract-text-batch")]
    public async Task<IActionResult> ExtractTextBatch(List<IFormFile> files)
    {
        var results = new List<object>();

        // Thread-safe: create one IronTesseract per thread
        await Parallel.ForEachAsync(files, async (file, ct) =>
        {
            var ocr = new IronTesseract();
            using var input = new OcrInput();
            using var stream = file.OpenReadStream();
            input.LoadImage(stream);
            var result = ocr.Read(input);

            lock (results)
            {
                results.Add(new { file = file.FileName, text = result.Text });
            }
        });

        return Ok(results);
    }
}
C#

Le même code se déploie sans modification sur IIS, Kestrel ou un conteneur Docker sous Linux. Le guide ASP.NET OCR couvre la configuration du middleware et le guide de déploiement Docker documente la configuration des conteneurs Linux.

Élimination du code de gestionnaire spécifique à la plateforme

L'architecture de TesseractOcrMaui, exclusivement destinée à MAUI, oblige les développeurs à écrire du code conditionnel à la plateforme lorsqu'ils tentent d'intégrer l'OCR dans des solutions multi-cibles. IronOCR élimine le besoin de conditions liées à la plateforme, car le même package s'installe correctement sur toutes les cibles.

Approche de TesseractOcrMaui:

// Attempting to share OCR logic across MAUI and non-MAUI targets
// requires platform-conditional compilation — a maintenance hazard

#if ANDROID || IOS || WINDOWS
// Only compile this block in MAUI targets
// Non-MAUI targets cannot reference TesseractOcrMauiat all
using TesseractOcrMaui;

public class PlatformOcrHandler
{
    private readonly ITesseract _tesseract;

    public PlatformOcrHandler(ITesseract tesseract)
    {
        _tesseract = tesseract;
    }

    public async Task<string> ProcessAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var r = await _tesseract.RecognizeTextAsync(imagePath);
        return r.RecognizedText ?? string.Empty;
    }
}
#else
// Server targets need a completely different implementation
public class PlatformOcrHandler
{
    public string ProcessAsync(string imagePath)
    {
        // Duplicate logic using a different library
        throw new PlatformNotSupportedException("Use server OCR library here");
    }
}
#endif
C#

Approche IronOCR :

// One implementation — no conditional compilation, no duplicate logic
using IronOcr;

public class PlatformOcrHandler
{
    // This class compiles identically for:
    // net8.0-android, net8.0-ios, net8.0-windows (MAUI targets)
    // net8.0 (server targets)
    // netstandard2.1 (shared library targets)

    public string Process(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        input.Deskew();
        return ocr.Read(input).Text;
    }
}

// Multi-target .csproj — no conditional package references needed
// <TargetFrameworks>net8.0;net8.0-android;net8.0-ios</TargetFrameworks>
// IronOcr resolves correctly for all three targets from one package reference
C#

Les conditions liées à la plateforme dans le code de gestion de l'OCR indiquent une division architecturale qui s'accentue avec le temps. Chaque modification de configuration de langage, chaque ajustement de prétraitement, chaque réglage du seuil de confiance doit être appliqué dans les deux branches. IronOCR rend cette division inutile. La présentation de la bibliothèque OCR .NET décrit en détail la structure des projets multi-cibles.

Extraction de données structurées à l'aide des coordonnées des mots

TesseractOcrMaui expose seulement result.RecognizedText et un score de confiance de haut niveau. L'extraction de mots individuels avec leurs cadres de sélection — nécessaire pour la validation des champs de formulaire, l'analyse de documents ou les superpositions de surlignage — n'est pas possible. IronOCR expose un modèle d'objet de document complet : pages, paragraphes, lignes, mots et caractères, chacun avec ses coordonnées en pixels.

Approche de TesseractOcrMaui:

// TesseractOcrMaui: flat text string only — no structure, no coordinates
public class TesseractMauiFormParser
{
    private readonly ITesseract _tesseract;

    public TesseractMauiFormParser(ITesseract tesseract)
    {
        _tesseract = tesseract;
    }

    public async Task<Dictionary<string, string>> ParseFormAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var result = await _tesseract.RecognizeTextAsync(imagePath);

        // result.RecognizedText is one flat string — no field positions
        // Parsing requires fragile line-splitting and regex heuristics
        var fields = new Dictionary<string, string>();
        var lines = result.RecognizedText?.Split('\n') ?? Array.Empty<string>();

        foreach (var line in lines)
        {
            // Hope the layout stays consistent enough to parse
            var parts = line.Split(':');
            if (parts.Length == 2)
                fields[parts[0].Trim()] = parts[1].Trim();
        }

        return fields;
        // Non way to validate against expected field positions
        // Non confidence per word — only document-level confidence
    }
}
C#

Approche IronOCR :

// IronOCR: full document structure with bounding boxes per word
using IronOcr;

public class IronOcrFormParser
{
    public List<WordLocation> ExtractWordsWithPositions(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);

        var result = ocr.Read(input);
        var wordLocations = new List<WordLocation>();

        foreach (var page in result.Pages)
        {
            foreach (var word in page.Words)
            {
                wordLocations.Add(new WordLocation
                {
                    Text = word.Text,
                    Confidence = word.Confidence,
                    X = word.X,
                    Y = word.Y,
                    Width = word.Width,
                    Height = word.Height
                });
            }
        }

        return wordLocations;
    }

    public FormData ParseStructuredForm(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        input.Deskew();

        var result = ocr.Read(input);
        var form = new FormData();

        foreach (var page in result.Pages)
        {
            foreach (var paragraph in page.Paragraphs)
            {
                // Use Y coordinate to identify form regions
                if (paragraph.Y < 200)
                    form.HeaderText += paragraph.Text + " ";
                else if (paragraph.Y > 800)
                    form.FooterText += paragraph.Text + " ";
                else
                    form.BodyLines.Add(paragraph.Text);
            }
        }

        form.OverallConfidence = result.Confidence;
        return form;
    }
}

public class WordLocation
{
    public string Text { get; set; }
    public float Confidence { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

public class FormData
{
    public string HeaderText { get; set; } = string.Empty;
    public string FooterText { get; set; } = string.Empty;
    public List<string> BodyLines { get; set; } = new();
    public float OverallConfidence { get; set; }
}
C#

Les coordonnées WORD permettent la validation par rapport à des modèles de formulaire connus, le marquage basé sur la confiance pour révision humaine et la mise en évidence par superposition dans les interfaces utilisateur des visionneuses de documents. Le guide de résultats structurés documente le modèle complet d'objet OcrResult incluant l'accès au niveau des caractères et le guide des scores de confiance couvre les modèles de filtrage de confiance par mot.

Traitement en arrière-plan avec Async natif et suivi de la progression

TesseractOcrMaui expose une API asynchrone (RecognizeTextAsync) mais uniquement dans le contexte de l'application MAUI. Les tâches batch de longue durée doivent s'exécuter dans un service d'arrière-plan, une Azure Function ou un processus de travail — autant d'environnements que TesseractOcrMauine peut pas cibler. IronOCR offre une prise en charge native asynchrone qui fonctionne dans n'importe quel service hébergé.

Approche de TesseractOcrMaui:

// Background processing is impossible with TesseractOcrMaui.
// IHostedService runs in a server context — TesseractOcrMauihas no server target.
// The MAUI async API exists, but there is nowhere to run it outside the MAUI app host.

public class DocumentBatchWorker : BackgroundService
{
    // ITesseract cannot be injected here — no MAUI DI in a hosted service
    // Attempting to reference TesseractOcrMauiwill fail to compile:
    // error: Package TesseractOcrMauidoes not support target net8.0
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        throw new PlatformNotSupportedException(
            "TesseractOcrMaui has no server target. Use a different OCR library.");
    }
}
C#

Approche IronOCR :

// IronOCR: hosted service background batch processor
using IronOcr;
using Microsoft.Extensions.Hosting;

public class DocumentBatchWorker : BackgroundService
{
    private readonly ILogger<DocumentBatchWorker> _logger;
    private readonly string _inputFolder;
    private readonly string _outputFolder;

    public DocumentBatchWorker(ILogger<DocumentBatchWorker> logger, IConfiguration config)
    {
        _logger = logger;
        _inputFolder = config["Ocr:InputFolder"];
        _outputFolder = config["Ocr:OutputFolder"];
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var pendingFiles = Directory.GetFiles(_inputFolder, "*.pdf")
                .Concat(Directory.GetFiles(_inputFolder, "*.jpg"))
                .ToList();

            if (pendingFiles.Count > 0)
            {
                _logger.LogInformation("Processing {Count} documents.", pendingFiles.Count);

                // Thread-safe parallel processing — one IronTesseract per thread
                await Parallel.ForEachAsync(pendingFiles,
                    new ParallelOptions { MaxDegreeOfParallelism = 4, CancellationToken = stoppingToken },
                    async (filePath, ct) =>
                    {
                        await ProcessDocumentAsync(filePath, ct);
                    });
            }

            await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
        }
    }

    private async Task ProcessDocumentAsync(string filePath, CancellationToken ct)
    {
        try
        {
            var ocr = new IronTesseract();
            using var input = new OcrInput();

            if (Path.GetExtension(filePath).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
                input.LoadPdf(filePath);
            else
                input.LoadImage(filePath);

            input.Deskew();
            input.DeNoise();

            var result = await Task.Run(() => ocr.Read(input), ct);

            // Produce searchable PDF from the same OCR pass
            var outputPath = Path.Combine(_outputFolder,
                Path.GetFileNameWithoutExtension(filePath) + "_searchable.pdf");
            result.SaveAsSearchablePdf(outputPath);

            File.Delete(filePath); // move from input queue
            _logger.LogInformation("Processed {File}: {Confidence:F1}% confidence.", filePath, result.Confidence);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to process {File}.", filePath);
        }
    }
}
C#

Le travailleur s'enregistre dans Program.cs avec builder.Services.AddHostedService<DocumentBatchWorker>() et fonctionne dans tout hôte .NET 8 — Service Windows, unité systemd Linux, conteneur Docker, ou application conteneur Azure. Le guide OCR asynchrone couvre les modèles asynchrones et le guide PDF consultable documente les options de sortie SaveAsSearchablePdf.

Référence de mappage de l'API TesseractOcrMauivers IronOCR

TesseractOcrMauiÉquivalent d'IronOCR
dotnet add package TesseractOcrMauidotnet add package IronOcr
builder.Services.AddTesseractOcr()Supprimer entièrement — aucune inscription requise
ITesseract (injecté)new IronTesseract() (instanciation directe)
_tesseract.InitAsync("eng")ocr.Language = OcrLanguage.English; (ou omettre pour l'anglais par défaut)
_tesseract.RecognizeTextAsync(imagePath)ocr.Read(input)
result.RecognizedTextresult.Text
result.SuccessFondé sur les exceptions ; pas d'indicateur booléen
result.Statuscatch (Exception ex) message
result.Confidenceresult.Confidence (aussi par mot)
TesseractOcrMaui.Results.RecognitionResultIronOcr.OcrResult
<MauiAsset> paquet de données entraînéesdotnet add package IronOcr.Languages.French
Resources/Raw/tessdata/eng.traineddataSupprimer — les données linguistiques se trouvent dans le package NuGet
FileSystem.OpenAppPackageFileAsync() (pour données entraînées)Supprimer — inutile
Prise en charge des fichiers PDF non disponibleinput.LoadPdf(path) ou input.LoadPdf(stream)
Aucun prétraitementinput.Deskew(), input.DeNoise(), input.Binarize(), input.Contrast()
Aucun fichier PDF consultableresult.SaveAsSearchablePdf(outputPath)
Pas de coordonnées de motsresult.Pages[0].Words[i].X, .Y, .Width, .Height
Pas de confiance par WORDresult.Pages[0].Words[i].Confidence
net8.0-ios uniquement ciblesnet8.0 + IronOcr.iOS package
net8.0-android uniquement ciblesnet8.0 + IronOcr.Android package

Problèmes de migration courants et solutions

Problème n° 1 : AddTesseractOcr ne peut pas être supprimé sans endommager les classes dépendantes

TesseractOcrMaui : Chaque classe qui effectue l'OCR reçoit ITesseract via l'injection de constructeur. Supprimer AddTesseractOcr() casse immédiatement ces constructeurs avec une exception de résolution DI.

Solution : Supprimer le paramètre du constructeur et le remplacer par une instanciation directe IronTesseract. Si le projet utilise un conteneur DI et que vous souhaitez conserver le modèle injectable, enregistrez IronTesseract manuellement :

// Option A: Direct instantiation (recommended for most cases)
public class ScanPageViewModel
{
    public string ScanDocument(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return ocr.Read(input).Text;
    }
}

// Option B: Register IronTesseract in DI if your architecture requires it
// In MauiProgram.cs or Program.cs:
builder.Services.AddSingleton<IronTesseract>();

// Then inject normally:
public class ScanPageViewModel
{
    private readonly IronTesseract _ocr;
    public ScanPageViewModel(IronTesseract ocr) { _ocr = ocr; }

    public string ScanDocument(string imagePath)
    {
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return _ocr.Read(input).Text;
    }
}
C#

Problème n° 2 : fichiers de données d'entraînement manquants après la suppression du package

TesseractOcrMaui : Le dossier Resources/Raw/tessdata/, les fichiers .traineddata qu'il contient et les déclarations <MauiAsset> dans .csproj doivent être supprimés. Les laisser entraîne des avertissements de compilation et alourdit le bundle de l'application avec des fichiers inutilisés.

Solution : Supprimez le dossier tessdata, retirez les entrées <MauiAsset>, et désinstallez toute langue téléchargée manuellement. Installez plutôt le pack linguistique IronOCR correspondant :

# Delete traineddata assets
rm -rf Resources/Raw/tessdata

# Remove from .csproj (delete the MauiAsset ItemGroup):
# <ItemGroup>
#   <MauiAsset Include="Resources\Raw\tessdata\*.traineddata" />
# </ItemGroup>

# Install IronOCR language pack (if non-English language was needed)
dotnet add package IronOcr.Languages.French
dotnet add package IronOcr.Languages.German
SHELL

Les paquets linguistiques d'IronOCR sont résolus au moment de la compilation et intégrés sans aucune gestion manuelle des fichiers. Le guide multilingue répertorie tous les paquets disponibles et la configuration multilingue simultanée.

Problème n° 3 : InitAsync doit être appelé avant chaque appel à RecognizeTextAsync

TesseractOcrMaui : L'appel ITesseract.InitAsync(language) doit précéder chaque appel RecognizeTextAsync. Les équipes ajoutent souvent des drapeaux de sécurité _isInitialized, des verrouillages vérifiés deux fois, ou des sémaphores pour éviter l'initialisation répétée. Tout ce code devient du code mort après la migration.

Solution : IronTesseract n'a pas d'étape d'initialisation. La langue est définie une fois sur l'instance. Supprimez tous les appels InitAsync, tous les drapeaux _isInitialized et toute la logique de sécurité de l'initialisation :

// Before: initialization guard required before every OCR call
private bool _isInitialized = false;
private readonly SemaphoreSlim _initLock = new SemaphoreSlim(1, 1);

public async Task<string> GetTextAsync(string imagePath)
{
    await _initLock.WaitAsync();
    try
    {
        if (!_isInitialized)
        {
            await _tesseract.InitAsync("eng");
            _isInitialized = true;
        }
    }
    finally { _initLock.Release(); }

    var result = await _tesseract.RecognizeTextAsync(imagePath);
    return result.RecognizedText ?? string.Empty;
}

// After: no initialization, no guard, no semaphore
public string GetText(string imagePath)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    return ocr.Read(input).Text;
}
C#

Problème n° 4 : le modèle de vérification result.Success doit être remplacé

TesseractOcrMaui : La valeur de retour RecognizeTextAsync contient un booléen Success et une chaîne Status. Le code qui vérifie if (!result.Success) et lit result.Status pour des informations d'erreur doit être réécrit.

Solution : IronOCR utilise la sémantique standard des exceptions .NET. Remplacer les vérifications de drapeau de réussite par try/catch. En cas de succès, .Text est toujours peuplé (chaîne vide si aucun texte n'a été trouvé) :

// Before: success-flag pattern
var result = await _tesseract.RecognizeTextAsync(imagePath);
if (!result.Success)
{
    logger.LogError("OCR failed: {Status}", result.Status);
    return string.Empty;
}
return result.RecognizedText ?? string.Empty;

// After: exception pattern
try
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    var result = ocr.Read(input);
    return result.Text; // empty string if no text found — never null
}
catch (Exception ex)
{
    logger.LogError(ex, "OCR failed for {Path}.", imagePath);
    return string.Empty;
}
C#

Problème n° 5 : framework cible MAUI-Only dans les projets de bibliothèques partagées

TesseractOcrMaui : Une bibliothèque de classes qui référence TesseractOcrMaui hérite automatiquement de sa contrainte de plateforme. Le <TargetFramework> de la bibliothèque doit être défini sur un moniker MAUI (net8.0-android, net8.0-ios, ou net8.0-windows), ce qui l'empêche d'être référencé par des projets de serveur.

Solution : Changez la cible de la bibliothèque de classes en net8.0 ou netstandard2.1 et référez IronOcr à la place. La bibliothèque se résout désormais correctement depuis n'importe quel projet qui l'utilise :

<!-- Before: locked to MAUI target because TesseractOcrMauihas no net8.0 target -->
<TargetFramework>net8.0-android</TargetFramework>
<PackageReference Include="TesseractOcrMaui" Version="*" />

<!-- After: universal target — referenced from MAUI, API, worker, and Functions -->
<TargetFramework>net8.0</TargetFramework>
<PackageReference Include="IronOcr" Version="*" />
XML

Problème n° 6 : le traitement des PDF nécessite la suppression d'une deuxième bibliothèque

TesseractOcrMaui : Les équipes qui ont implémenté le support PDF ont ajouté une deuxième bibliothèque (PDFium, PdfPig, ou un renderer cloud) pour convertir les pages PDF en images avant de les envoyer à RecognizeTextAsync. Après la migration vers IronOCR, cette deuxième bibliothèque et tout son code de rendu de page pourront être supprimés.

Solution : Supprimez la bibliothèque de rendu PDF et remplacez tout le pipeline d'extraction de page par input.LoadPdf() :

// Before: PDF library + manual temp file management (50+ lines)
using var pdfDoc = PdfDocument.Open(pdfPath);
var results = new List<string>();
foreach (var page in pdfDoc.GetPages())
{
    var tempImagePath = Path.Combine(FileSystem.CacheDirectory, $"page_{page.Number}.png");
    RenderPageToImage(page, tempImagePath, dpi: 300);
    await _tesseract.InitAsync("eng");
    var r = await _tesseract.RecognizeTextAsync(tempImagePath);
    results.Add(r.RecognizedText ?? string.Empty);
    File.Delete(tempImagePath);
}
return string.Join("\n", results);

// After: native PDF support — 5 lines
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(pdfPath);
var result = ocr.Read(input);
return result.Text;
C#

Le guide d'entrée PDF couvre la sélection de plages de pages, les PDF protégés par mot de passe et le chargement par flux.

Liste de contrôle pour la migration vers TesseractOcrMaui

Pré-migration

Vérifiez le code source pour recenser toutes les utilisations de TesseractOcrMauiavant de modifier le code :

# Find all files that reference TesseractOcrMauinamespaces
grep -r "TesseractOcrMaui" --include="*.cs" .

# Find all ITesseract injection points
grep -r "ITesseract" --include="*.cs" .

# Find all AddTesseractOcr registrations
grep -r "AddTesseractOcr" --include="*.cs" .

# Find all InitAsync calls
grep -r "InitAsync" --include="*.cs" .

# Find all RecognizeTextAsync calls
grep -r "RecognizeTextAsync" --include="*.cs" .

# Find traineddata asset declarations in project files
grep -r "tessdata" --include="*.csproj" .

# Find MauiAsset traineddata declarations
grep -r "MauiAsset" --include="*.csproj" .

# Identify projects with MAUI-only target frameworks that hold OCR logic
grep -r "net8.0-android\|net8.0-ios\|net8.0-windows" --include="*.csproj" .
SHELL

Notez chaque classe qui utilise ITesseract dans un constructeur — ces constructeurs vont changer. Notez chaque fichier de projet qui déclare <MauiAsset> pour traineddata — ces déclarations seront supprimées. Vérifiez si une bibliothèque de rendu PDF est présente et si elle est utilisée exclusivement pour le prétraitement OCR.

Migration de code

  1. Exécutez dotnet remove package TesseractOcrMaui dans chaque projet qui le référence
  2. Exécutez dotnet add package IronOcr dans chaque projet qui effectuera l'OCR
  3. Exécutez dotnet add package IronOcr.Android dans les projets MAUI ciblant Android
  4. Exécutez dotnet add package IronOcr.iOS dans les projets MAUI ciblant iOS
  5. Exécutez dotnet add package IronOcr.Languages.* pour toute langue autre que l'anglais précédemment incluse comme traineddata
  6. Ajoutez IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; au démarrage de l'application dans chaque projet de point d'entrée
  7. Supprimez Resources/Raw/tessdata/ et tous les fichiers .traineddata des projets MAUI
  8. Retirez toutes les lignes <MauiAsset Include="Resources\Raw\tessdata\*.traineddata" /> des fichiers .csproj
  9. Retirez builder.Services.AddTesseractOcr() de tous les fichiers MauiProgram.cs
  10. Remplacez tous les using TesseractOcrMaui; et using TesseractOcrMaui.Results; par using IronOcr;
  11. Supprimez les paramètres de constructeur ITesseract de toutes les classes de service et de modèle-vue
  12. Remplacez les appels await _tesseract.InitAsync("eng") par ocr.Language = OcrLanguage.English; si nécessaire (par défaut c'est l'anglais)
  13. Remplacez await _tesseract.RecognizeTextAsync(imagePath) par ocr.Read(input) en utilisant une instance OcrInput
  14. Remplacez result.RecognizedText par result.Text
  15. Remplacez les vérifications if (!result.Success) par des blocs try/catch
  16. Si une bibliothèque de rendu PDF a été ajoutée uniquement pour prendre en charge TesseractOcrMaui, retirez-la et remplacez le code d'extraction de page par input.LoadPdf()
  17. Changez tout framework cible uniquement MAUI dans les bibliothèques de classes qui contenaient la logique OCR en net8.0 ou netstandard2.1

Après la migration

  • Vérifier que l'OCR génère du texte à partir d'une image JPEG capturée par l'appareil photo de l'appareil sur les cibles iOS et Android
  • Vérifiez que l'OCR produit du texte à partir de la même image chargée via byte[] dans le point de terminaison API côté serveur
  • Vérifiez que la bibliothèque de classes partagée se compile et s'exécute de manière identique lorsqu'elle est référencée à la fois dans des projets MAUI et .NET Core
  • Vérifiez que l'importation de fichiers PDF fonctionne de bout en bout sans création de fichiers temporaires
  • Vérifiez que la sortie SaveAsSearchablePdf est indexable dans un visualiseur PDF
  • Confirmez que les scores de confiance sont présents sur result.Confidence et sur page.Words[i].Confidence
  • Vérifiez que l'application MAUI génère un journal de démarrage sans erreur, sans exception de type " fichier de données d'apprentissage introuvable ".
  • Vérifiez que le dossier Resources/Raw/tessdata/ est absent du bundle de l'application MAUI dans les builds de version
  • Exécutez un traitement par lots en parallèle avec 10 documents ou plus pour vérifier la sécurité des threads
  • Confirmez que la suppression de InitAsync n'a pas laissé de sémaphores orphelins ou de variables d'état _isInitialized dans toute classe de service

Principaux avantages de la migration vers IronOCR

Un code unique pour tout le produit. Après migration, chaque projet de la solution - application mobile MAUI, API ASP.NET Core, fonction Azure, travailleur de fond - appelle la même classe DocumentOcrService à partir de la même bibliothèque partagée. La configuration de la langue, les paramètres de prétraitement et le réglage de la précision s'effectuent en un seul endroit. Lorsqu'un nouveau type de document nécessite un nouveau filtre de prétraitement, la modification est effectuée une seule fois et s'applique partout.

Déploiement côté serveur sans réécriture. IronOCR se déploie sur des conteneurs Linux, Windows Server, Azure App Service, AWS Lambdaet toute autre cible d'exécution .NET 8 sans modification. La même instance IronTesseract qui traite les captures de caméra mobile traite les téléversements PDF côté serveur. Le guide de déploiement Azure et le guide de déploiement AWS documentent les étapes de configuration spécifiques à chaque plateforme.

Traitement PDF sans une deuxième bibliothèque. L'entrée PDF native via input.LoadPdf() élimine la bibliothèque de rendu PDF, la boucle d'extraction d'image page par page, la gestion des fichiers temporaires et le code de nettoyage que l'architecture de TesseractOcrMauinécessitait. Les contrats PDF scannés, les factures et les documents d'identité se chargent en une ligne. Le même passage OCR qui extrait le texte peut produire un PDF consultable avec result.SaveAsSearchablePdf() — une capacité que TesseractOcrMauine peut fournir à aucun niveau.

Prétraitement qui gère de vraies images mobiles. input.Deskew(), input.DeNoise(), input.Binarize(), et input.Sharpen() sont des appels de méthode unique qui appliquent des corrections d'image calibrées avant que le moteur Tesseract ne voie les données. Les équipes qui acceptaient une précision de 40 à 60 % sur des captures mobiles en basse lumière sans prétraitement obtiennent généralement une précision de 85 à 90 % ou plus après l'ajout d'un pipeline à trois filtres. Pas besoin de SkiaSharp, d'ImageSharp ni de mise en œuvre d'algorithmes. Le guide de correction de la qualité d'image répertorie tous les filtres disponibles et indique quand les appliquer.

Assistance commerciale avec un processus d'escalade défini. Iron Software fournit un support par e-mail pour tous les niveaux de licence IronOCR, ainsi qu'un support prioritaire par téléphone et par chat pour les niveaux Professional et Enterprise. Lorsqu'une mise à jour de plateforme perturbe la résolution des bibliothèques natives sur un niveau d'API Android spécifique — le type de problème que la file d'attente des tickets GitHub de TesseractOcrMauitraite grâce au travail bénévole —, il existe une véritable équipe d'ingénieurs qui a l'obligation d'y répondre. Les licences perpétuelles commencent à $999 pour le niveau Lite ; La page des licences répertorie tous les niveaux et les niveaux d'assistance inclus.

Plus de 125 langues via NuGet sans alourdir le bundle de l'application. TesseractOcrMauiintègre des fichiers de données entraînées au sein de l'application MAUI — chaque langue ajoute 10 à 50 Mo à la taille de téléchargement de l'application. Les packs linguistiques IronOCR s'installent via NuGet et ne sont inclus que dans les versions côté serveur ou dans les versions de plate-forme où ils sont explicitement référencés. Les offres groupées d'applications mobiles restent légères ; Les versions côté serveur disposent de l'ensemble complet des langues. Ajouter une nouvelle langue est une commande dotnet add package sans changement de fichier de projet et sans gestion de fichier. Le catalogue complet des langues répertorie l'ensemble des plus de 125 packs disponibles.

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

Articles connexes

Key in blue circle

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

Your trial license will be sent to your email address

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

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