IRONSOFTWAREHOME
VIDÉOS

Comment implémenter l'OCR en C# en utilisant des bibliothèques open source

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 août 2026

Ce guide s'adresse aux développeurs .NET qui ont intégré l'API REST de Klippa et qui migrent vers IronOCR pour le traitement de documents sur site. Il décrit les étapes pratiques pour supprimer l'infrastructure client HTTP, éliminer la désérialisation JSON et remplacer les téléchargements de documents dépendants du cloud par des appels OCR locaux qui ne passent jamais par le réseau.

Pourquoi migrer depuis Klippa OCR?

Klippa est un service d'analyse documentaire exclusivement basé sur le cloud et ne nécessitant pas de kit de développement .NET . Chaque intégration est un client REST développé sur mesure. Cette réalité architecturale a des conséquences en aval qui s'accumulent tout au long du cycle de vie d'un système de production.

L'absence de package NuGet signifie que vous êtes propriétaire de la couche d'intégration. Il n'y a rien à installer. Le coût d'entrée est l'écriture d'un HttpClient wrapper, la configuration des en-têtes d'authentification X-Auth-Key, la création des corps de requête MultipartFormDataContent, la désérialisation du schéma de réponse JSON de Klippa et la mise en place de la logique de nouvelle tentative pour les échecs transitoires. Il faut donc compter 2 à 4 jours de mise en place avant que le premier document ne soit traité de manière fiable en production. Lorsque Klippa met à jour son schéma d'API, votre code de désérialisation devient incompatible et nécessite une maintenance manuelle.

Chaque téléchargement de document nécessite une connexion réseau. Klippa traite les documents exclusivement sur des serveurs hébergés dans l'UE. Les pannes de production du côté de Klippa, une latence élevée ou toute interruption de l'accès Internet sortant de votre serveur d'application interrompent complètement le traitement des documents. Il n'existe aucune solution de repli, aucun mode local, ni aucune nouvelle tentative pour résoudre le problème d'indisponibilité d'un service cloud.

Les documents sensibles quittent votre infrastructure. Les documents financiers (reçus avec les détails de paiement, factures avec les numéros de TVA et les montants, pièces d'identité avec les données du passeport) sont transmis à un serveur tiers à chaque appel d'API. Les dispositions du RGPD relatives au transfert de données répondent en partie à ces problématiques pour les traitements effectués dans l'UE, mais le périmètre de l'audit s'étend toujours à l'infrastructure de Klippa, à ses politiques de conservation des données et à ses sous-traitants. Pour les équipes ayant des contrats dans les secteurs de la santé, des services juridiques, financiers ou gouvernementaux, l'expression " hébergé dans l'UE " ne satisfait pas à l'exigence selon laquelle les données ne doivent pas quitter l'organisation.

Tarification par document sans plafond. Klippa ne publie pas ses tarifs. Pour tout volume de documents significatif (10 000 reçus par mois dans un système de gestion des dépenses, 500 factures par jour dans un flux de travail d'automatisation des comptes fournisseurs), le modèle de facturation par document engendre des coûts qu'une licence perpétuelle n'entraînerait jamais. L'évolution des coûts est directement liée à la croissance des entreprises, ce qui est l'inverse de ce que devraient faire les dépenses d'infrastructure.

Le périmètre d'intervention du spécialiste s'élargit lorsque les besoins évoluent. Klippa est formée à la gestion des reçus, des factures et des pièces d'identité. Une application conçue initialement pour la gestion des dépenses reste rarement cantonnée à ce rôle. La première fois qu'un type de document ne faisant pas partie de ces trois catégories apparaît (un contrat de travail scanné, un formulaire médical, un dessin technique, un bon de commande avec une mise en page non standard), Klippa ne renvoie rien d'utile. IronOCR traite tout document contenant du texte, sans restriction de catégorie.

Les appels REST asynchrones ajoutent de la latence dans les contextes synchrones. Chaque appel Klippa est une opération HTTP asynchrone. L'envoi aller-retour d'un seul document prend entre 500 ms et 2000 ms sur le réseau. IronOCR traite le même document localement en 100 à 400 ms sans la surcharge asynchrone dans les scénarios où le traitement synchrone convient mieux à l'architecture.

Le problème fondamental

Klippa ne possède pas de SDK. L'OCR consiste à construire et à envoyer une requête HTTP, puis à désérialiser le JSON :

// Klippa: 15+ lines of HTTP plumbing before you read a single character
var content = new MultipartFormDataContent();
content.Add(new ByteArrayContent(File.ReadAllBytes(imagePath)), "document", "receipt.jpg");
_client.DefaultRequestHeaders.Add("X-Auth-Key", _apiKey); // auth header — rotates, breaks, leaks

var response = await _client.PostAsync(
    "https://custom-ocr.klippa.com/api/v1/parseDocument", content);
response.EnsureSuccessStatusCode(); // throws on 4xx/5xx — no retry, document lost

var json = await response.Content.ReadAsStringAsync();
var parsed = JsonSerializer.Deserialize<KlippaResponse>(json); // your schema, your maintenance
var text = parsed?.Data?.ParsedDocument?.Text; // nullable chain — breaks when schema changes
C#

IronOCR remplace tout cela :

// IronOCR: no HTTP, no auth headers, no JSON — just text
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var text = new IronTesseract().Read(imagePath).Text;
C#

Comparaison des fonctionnalités IronOCR et de Klippa OCR

Le tableau ci-dessous compare les deux bibliothèques selon les dimensions les plus importantes pour une décision de migration en production.

FonctionKlippa OCRIronOCR
Modèle de déploiementServeurs exclusivement en nuage (serveurs européens)Sur place, entièrement local
Kit de développement .NET / package NuGetNoneIronOcr NuGet package
Internet requisOui, à chaque appelJamais
Les données du document quittent le réseauToujoursJamais
OCR à usage généralNon (reçus, factures, pièces d'identité uniquement)Oui (tout type de document)
Configuration de l'authentificationX-Auth-Key HTTP headerIronOcr.License.LicenseKey string
Client HTTP requisOuiNon
Désérialisation de la réponseAnalyse manuelle JSONObjet typé OcrResult
logique de nouvelle tentative/délai d'attenteroulé à la mainPas nécessaire (appel local)
Assistance hors ligne / isolée du réseauNonOui
Entrée PDFOui (cloud)Oui (natif, local)
Entrée TIFF multipageInconnuOui
Formats d'entrée d'imageJPG, PNG (nuage)JPG, PNG, BMP, TIFF, GIF et plus encore
Entrée de flux et de tableau d'octetsPas de SDKOui
prétraitement automatique des imagesCôté nuageux (opaque)Oui (Correction de l'inclinaison, réduction du bruit, contraste, binarisation, netteté)
Sortie structurée : coordonnées des motsNonOui
Scores de confiance par motNonOui
Sortie PDF consultableNonOui
Lecture de codes-barres lors de la reconnaissance optique de caractères (OCR)NonOui
Assistance multilingueLimité aux types de documents formésplus de 125 langues
Sécurité du filN/A (appels HTTP)Oui (un IronTesseract par thread)
Déploiement multiplateformeREST-agnostiqueWindows, Linux, macOS, Docker, Azure, AWS
Conformité HIPAA/ITAR/environnement isolé (sans contact)NonOui
Modèle de tarificationSaaS par document (tarifs non publiés)Licence perpétuelle de $999
Coût par page à l'échelleOui, sans limitesNone

Démarrage rapide : Migration de Klippa OCRvers IronOCR

Étape 1 : Remplacer le package NuGet

Klippa ne possède pas de package NuGet officiel. Supprimez les dépendances du client HTTP qui existent uniquement pour prendre en charge l'intégration de Klippa :

# Remove Klippa-related packages (if installed for REST support)
dotnet remove package Newtonsoft.Json
dotnet remove package System.Net.Http.Json
SHELL

Installez IronOCR depuis NuGet :

dotnet add package IronOcr

Étape 2 : Mise à jour des espaces de noms

Supprimez les espaces de noms HTTP et JSON requis par l'intégration de Klippa. Ajouter l'espace de noms IronOCR unique :

// Before (Klippa integration)
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;

// After (IronOCR)
using IronOcr;
C#

Étape 3 : initialisation de la licence

Ajoutez l'initialisation de la licence une fois au démarrage de l'application — dans Program.cs, Startup.cs, ou avant le premier appel OCR :

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

Exemples de migration de code

Remplacement de la classe de service client HTTP

L'intégration de Klippa nécessite une classe de service complète encapsulant l'infrastructure HTTP. Il n'y a aucun moyen d'éviter cela car il n'existe pas de SDK.

Approche Klippa :

// Klippa: entire service class just to send one HTTP request
public class KlippaOcrService : IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl = "https://custom-ocr.klippa.com/api/v1";

    public KlippaOcrService(string apiKey)
    {
        _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Add("X-Auth-Key", apiKey);
        _httpClient.Timeout = TimeSpan.FromSeconds(30); // network timeout required
    }

    public async Task<string> ReadDocumentTextAsync(string filePath)
    {
        using var form = new MultipartFormDataContent();
        var fileBytes = await File.ReadAllBytesAsync(filePath);
        form.Add(new ByteArrayContent(fileBytes), "document", Path.GetFileName(filePath));

        var response = await _httpClient.PostAsync($"{_baseUrl}/parseDocument", form);
        response.EnsureSuccessStatusCode();

        var json = await response.Content.ReadAsStringAsync();
        using var doc = JsonDocument.Parse(json);
        // navigate Klippa's nested JSON schema
        return doc.RootElement
            .GetProperty("data")
            .GetProperty("parsed_document")
            .GetProperty("text")
            .GetString() ?? string.Empty;
    }

    public void Dispose() => _httpClient.Dispose();
}
C#

Approche IronOCR :

// IronOCR: no HTTP, no JSON navigation, no Dispose plumbing
public class OcrService
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public string ReadDocumentText(string filePath)
    {
        return _ocr.Read(filePath).Text;
    }
}

// At startup:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// Usage — identical call site, different internals:
var service = new OcrService();
var text = service.ReadDocumentText("invoice.jpg"); // local, synchronous, zero network
C#

La classe de service Klippa existe uniquement parce que l'API nécessite une infrastructure HTTP. L'équivalent d'IronOCR se réduit à un seul appel Read(). Les délais d'attente, les en-têtes d'authentification et les modèles de suppression disparaissent tous en l'absence de réseau. Consultez le guide d'installation d'IronTesseract pour les options d'initialisation et l' exemple de code OCR de base pour un code fonctionnel.

Suppression du téléchargement de formulaires en plusieurs parties

Klippa reçoit les documents sous forme de formulaires multiparties téléchargés. Le code de téléchargement est mécanique mais fragile : lectures de fichiers, en-têtes de type de contenu, construction des limites et gestion de la taille du téléchargement.

Approche Klippa :

// Klippa: multipart upload — every document is an HTTP form POST
public async Task<KlippaResult> UploadAndParseAsync(
    string filePath, string documentType = "financial")
{
    using var form = new MultipartFormDataContent();

    // read file into memory — entire document in RAM before upload
    var fileBytes = await File.ReadAllBytesAsync(filePath);
    var byteContent = new ByteArrayContent(fileBytes);
    byteContent.Headers.ContentType =
        new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg");

    form.Add(byteContent, "document", Path.GetFileName(filePath));
    form.Add(new StringContent(documentType), "DocumentType");

    // document leaves your server here
    var response = await _httpClient.PostAsync(
        "https://custom-ocr.klippa.com/api/v1/parseDocument", form);

    if (!response.IsSuccessStatusCode)
    {
        var error = await response.Content.ReadAsStringAsync();
        throw new InvalidOperationException($"Klippa API error: {response.StatusCode}{error}");
    }

    var json = await response.Content.ReadAsStringAsync();
    return JsonSerializer.Deserialize<KlippaResult>(json,
        new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
C#

Approche IronOCR :

// IronOCR: load from file path, byte array, or stream — no upload, no form
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// From file path
using var input = new OcrInput();
input.LoadImage("invoice.jpg");
var result = new IronTesseract().Read(input);

// From byte array (same bytes Klippa was uploading)
byte[] fileBytes = await File.ReadAllBytesAsync("invoice.jpg");
using var inputFromBytes = new OcrInput();
inputFromBytes.LoadImage(fileBytes);
var resultFromBytes = new IronTesseract().Read(inputFromBytes);

Console.WriteLine(result.Text);
C#

La construction MultipartFormDataContent, les en-têtes de type de contenu et le téléchargement lui-même ont tous disparu. IronOCR lit directement à partir du chemin du fichier, d'un tableau d'octets ou d'un Stream — les mêmes données que Klippa transmettait au cloud restent locales. Le guide d'entrée d'images couvre tous les formats d'entrée pris en charge, et le guide d'entrée de flux couvre le chemin de flux mémoire pour les documents qui arrivent sous forme de tableaux d'octets provenant de processus en amont.

Remplacement de la désérialisation de la réponse JSON

Klippa renvoie une structure JSON imbriquée. Naviguer dans cette structure nécessite soit un modèle C# correspondant, soit un parcours inline JsonDocument — qui se cassent tous les deux lorsque Klippa modifie leur schéma de réponse.

Approche Klippa :

// Klippa: deserialization model — breaks when API schema changes
public class KlippaResponse
{
    [JsonPropertyName("data")]
    public KlippaData Data { get; set; }
}

public class KlippaData
{
    [JsonPropertyName("parsed_document")]
    public KlippaParsedDocument ParsedDocument { get; set; }
}

public class KlippaParsedDocument
{
    [JsonPropertyName("text")]
    public string Text { get; set; }

    [JsonPropertyName("amount")]
    public decimal? Amount { get; set; }

    [JsonPropertyName("merchant")]
    public string Merchant { get; set; }

    [JsonPropertyName("date")]
    public string Date { get; set; }
}

// Usage: navigate the nullable chain every time
public async Task<string> GetExtractedTextAsync(string imagePath)
{
    var klippaResult = await UploadAndParseAsync(imagePath);
    // every property access is nullable — schema drift breaks this silently
    return klippaResult?.Data?.ParsedDocument?.Text ?? string.Empty;
}
C#

Approche IronOCR :

// IronOCR: typed result object — no JSON schema, no nullable chains
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var ocr = new IronTesseract();
var result = ocr.Read("invoice.jpg");

// Direct property access — no deserialization, no nullable navigation
string fullText   = result.Text;
double confidence = result.Confidence;
int pageCount     = result.Pages.Count();

// Structured data: lines and words with coordinates
foreach (var page in result.Pages)
{
    foreach (var line in page.Lines)
    {
        Console.WriteLine($"Line: '{line.Text}' at Y={line.Y}");
    }
}
C#

OcrResult est un objet .NET typé. Il n'y a pas de JSON à analyser, pas de classe de modèle à maintenir et aucun risque de dérive de schéma interrompant la désérialisation en production. Le guide de lecture des résultats documente le modèle d'objet OcrResult complet, y compris les coordonnées de mot, les scores de confiance et la hiérarchie de page structurée. Pour des modèles d'extraction de champs spécifiques aux factures construits sur OcrResult, le tutoriel sur la reconnaissance des factures OCR couvre la logique d'extraction de bout en bout.

Suppression de l'infrastructure de gestion des erreurs et de nouvelle tentative

L'intégration de Klippa via HTTP nécessite une gestion des erreurs pour chaque mode d'échec qu'un appel réseau peut produire : délais d'attente, réponses 4xx, réponses 5xx, limites de débit et JSON partiel. Les équipes qui gèrent les intégrations en production ajoutent des politiques de nouvelle tentative à l'aide de Polly ou d'une logique personnalisée. Cette infrastructure disparaît lorsque l'appel réseau disparaît.

Approche Klippa :

// Klippa: retry policy required — cloud calls fail unpredictably
public async Task<string> ReadWithRetryAsync(string filePath, int maxRetries = 3)
{
    var delay = TimeSpan.FromSeconds(1);

    for (int attempt = 1; attempt <= maxRetries; attempt++)
    {
        try
        {
            using var form = new MultipartFormDataContent();
            form.Add(
                new ByteArrayContent(await File.ReadAllBytesAsync(filePath)),
                "document",
                Path.GetFileName(filePath));

            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
            var response = await _httpClient.PostAsync(
                "https://custom-ocr.klippa.com/api/v1/parseDocument", form, cts.Token);

            if (response.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
            {
                // rate limited — back off and retry
                await Task.Delay(delay * attempt);
                continue;
            }

            response.EnsureSuccessStatusCode();
            var json = await response.Content.ReadAsStringAsync(cts.Token);
            var parsed = JsonSerializer.Deserialize<KlippaResponse>(json);
            return parsed?.Data?.ParsedDocument?.Text ?? string.Empty;
        }
        catch (HttpRequestException) when (attempt < maxRetries)
        {
            await Task.Delay(delay * attempt); // exponential backoff
        }
        catch (TaskCanceledException) when (attempt < maxRetries)
        {
            await Task.Delay(delay * attempt); // timeout — retry
        }
    }

    throw new InvalidOperationException($"Klippa API failed after {maxRetries} attempts");
}
C#

Approche IronOCR :

// IronOCR: no network, no retry policy needed — local call either works or throws once
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

public string ReadDocument(string filePath)
{
    // Non retry loop. Non CancellationTokenSource. Non HTTP status checks.
    // Non rate limit handling. Non partial-JSON guards.
    var result = new IronTesseract().Read(filePath);
    return result.Text;
}
C#

L'ensemble de l'infrastructure de nouvelle tentative — la boucle, le calcul de retard, le CancellationTokenSource, le branchement du code d'état HTTP, le bloc de capture TaskCanceledException — existe uniquement à cause du réseau. Supprimez l'appel réseau et tout disparaît. Un appel OCR local échoue rapidement avec une exception typée si le fichier d'entrée est manquant ou illisible, et réussit dans le cas contraire. Le guide d'optimisation de la vitesse explique comment optimiser les performances IronOCR si le débit est un point important après la migration.

Traitement des PDF multipages sans téléchargement sur le cloud

Klippa accepte les téléchargements de PDF via le même point de terminaison parseDocument. Les fichiers PDF multipages quittent toujours votre réseau. IronOCR lit les fichiers PDF nativement, en temps réel, avec un accès aux résultats page par page.

Approche Klippa :

// Klippa: PDF upload — entire document transmitted, results depend on cloud availability
public async Task<List<string>> ExtractPdfPagesAsync(string pdfPath)
{
    var pages = new List<string>();

    // Klippa parses the entire PDF server-side and returns combined results
    // You cannot control per-page processing or access raw page text
    using var form = new MultipartFormDataContent();
    form.Add(
        new ByteArrayContent(await File.ReadAllBytesAsync(pdfPath)),
        "document",
        Path.GetFileName(pdfPath));

    var response = await _httpClient.PostAsync(
        "https://custom-ocr.klippa.com/api/v1/parseDocument", form);
    response.EnsureSuccessStatusCode();

    var json = await response.Content.ReadAsStringAsync();
    var result = JsonSerializer.Deserialize<KlippaResponse>(json);
    // Klippa returns the combined parsed text — no per-page breakdown in basic API
    pages.Add(result?.Data?.ParsedDocument?.Text ?? string.Empty);

    return pages;
}
C#

Approche IronOCR :

// IronOCR: native PDF OCR with per-page structured access — no upload
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

using var input = new OcrInput();
input.LoadPdf("multi-page-invoice.pdf"); // reads locally — no HTTP

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

// Per-page access — not available from Klippa's combined response
foreach (var page in result.Pages)
{
    Console.WriteLine($"Page {page.PageNumber}: {page.Lines.Count()} lines");
    Console.WriteLine(page.Text);
}

// Or produce a searchable PDF from the scanned original
result.SaveAsSearchablePdf("searchable-output.pdf");
C#

IronOCR lit les fichiers PDF nativement, sans aucune conversion. Chaque page est accessible individuellement, avec sa hiérarchie complète de lignes, de mots et de caractères. L'appel SaveAsSearchablePdf() produit un PDF avec couche de texte à partir d'un document numérisé — une capacité que Klippa n'offre pas. Le guide d'importation PDF décrit les options de chargement, et le guide PDF consultable décrit les options de sortie, notamment le format PDF/A pour la conformité aux exigences d'archivage.

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

Klippa est une API REST, et non un SDK typé. Le tableau ci-dessous traduit la surface d'intégration de Klippa en équivalents IronOCR .

Concept KlippaÉquivalent d'IronOCR
HttpClient avec en-tête X-Auth-KeyInstance IronTesseract — pas de configuration d'authentification
MultipartFormDataContentOcrInput.LoadImage(path) ou OcrInput.LoadPdf(path)
POST /api/v1/parseDocumentIronTesseract.Read(input)
await _client.PostAsync(...)ocr.Read(input) — synchrone, pas de await nécessaire
response.EnsureSuccessStatusCode()Inutile — aucune réponse HTTP
JsonSerializer.Deserialize<KlippaResponse>(json)Objet typé OcrResult — pas de désérialisation
KlippaResponse.Data.ParsedDocument.TextOcrResult.Text
KlippaResponse.Data.ParsedDocument.AmountRegex personnalisé sur OcrResult.Text ou OcrResult.Lines
KlippaResponse.Data.ParsedDocument.MerchantOcrResult.Pages[0].Lines[0].Text
Boucle de nouvelle tentative avec Task.DelayInutile — aucun mode de défaillance réseau
CancellationTokenSource(TimeSpan.FromSeconds(30))Inutile — exécution locale
Gestion des limites de débit (HTTP 429)Inutile — aucune limite de débit
Routage de documents cloud vers les serveurs de l'UEExécution locale en cours
KlippaService.Dispose() / HttpClient.Dispose()Élimination de OcrInput via l'instruction using
Champs de réponse JSON structurésOcrResult.Text + OcrResult.Pages + OcrResult.Words
Abonnement à l'API SaaSObjet string IronOcr.License.LicenseKey — perpétuel

Problèmes de migration courants et solutions

Problème 1 : Sites d'appels asynchrones uniquement après la suppression du protocole HTTP

Klippa : Toute l'intégration de Klippa est asynchrone car les appels HTTP l'exigent. Les contrôleurs, services et travailleurs en arrière-plan dans l'ensemble de votre base de code appellent await ProcessDocumentAsync(...). Supprimer l'appel HTTP signifie que le await n'est plus nécessaire, mais les signatures de méthode async restent.

Solution : IronOCR fournit des API synchrones et asynchrones. Pour les sites d'appel qui doivent rester asynchrones (contrôleurs ASP.NET Core, services en arrière-plan avec CancellationToken), utilisez ReadAsync :

// Keep async method signatures — switch the implementation
public async Task<string> ProcessDocumentAsync(
    string filePath, CancellationToken cancellationToken = default)
{
    // Previously: await _httpClient.PostAsync(...)
    // Now: local call, same awaitable pattern
    var ocr = new IronTesseract();
    var result = await ocr.ReadAsync(filePath);
    return result.Text;
}
C#

Le guide OCR asynchrone couvre l'intégration ReadAsync et CancellationToken pour ASP.NET Core et les modèles de service hébergés.

Problème 2 : Enregistrement de l'injection de dépendances

Klippa : La classe KlippaService est enregistrée dans DI comme service singleton ou scoped et encapsule HttpClient. Sa suppression implique la mise à jour de l'enregistrement DI et de tous les points d'injection.

Solution : Enregistrez IronTesseract comme singleton (il est sûr pour le thread) et injectez-le directement, ou créez un wrapper mince qui reflète votre interface de service existante :

// In Program.cs or Startup.cs
builder.Services.AddSingleton<IronTesseract>();

// Or wrap for interface compatibility
builder.Services.AddSingleton<IOcrService, IronOcrService>();

public class IronOcrService : IOcrService
{
    private readonly IronTesseract _ocr;
    public IronOcrService(IronTesseract ocr) => _ocr = ocr;

    public string ReadDocument(string path) => _ocr.Read(path).Text;
}
C#

Une instance IronTesseract enregistrée comme singleton gère les requêtes concurrentes. Chaque appel à Read() est sûr pour le thread.

Problème 3 : Extraction de champs structurés sans JSON pré-analysé

Klippa : Klippa renvoie amount, merchant, date, et vat_amount comme propriétés JSON typées. La migration vers IronOCR signifie que ces champs ne sont plus pré-analysés.

Solution : OcrResult d'IronOCR fournit le texte brut et les coordonnées au niveau des mots pour construire une extraction équivalente. Pour les documents dont la mise en page est prévisible, la reconnaissance optique de caractères (OCR) basée sur les régions cible directement des champs spécifiques :

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

// Target specific layout regions instead of relying on pre-parsed cloud fields
var totalRegion   = new CropRectangle(350, 580, 250, 50); // bottom-right total area
var merchantRegion = new CropRectangle(50, 30, 400, 60);  // top header area

using var merchantInput = new OcrInput();
merchantInput.LoadImage("receipt.jpg", merchantRegion);
var merchantName = new IronTesseract().Read(merchantInput).Text.Trim();

using var totalInput = new OcrInput();
totalInput.LoadImage("receipt.jpg", totalRegion);
var totalText = new IronTesseract().Read(totalInput).Text.Trim();
C#

Le guide OCR basé sur la région couvre l'utilisation CropRectangle en détail. Pour obtenir des modèles d'extraction complets pour les différents formats de reçus et de factures, le tutoriel sur la numérisation des reçus fournit un code fonctionnel complet.

Problème 4 : Documents arrivant sous forme de flux depuis les services en amont

Klippa : Klippa reçoit les documents sous forme de téléchargements de formulaires multipart — des octets de fichier enveloppés dans le contenu d'un formulaire HTTP. Si votre application reçoit des documents sous forme de flux provenant de S3, d'Azure Blob Storage ou d'API internes, vous lisiez le flux en octets, puis vous téléversiez ces octets sur Klippa.

Solution : IronOCR accepte directement les objets Stream. L'étape de conversion d'octets disparaît :

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

// Stream from S3, Azure Blob, or any upstream source
public async Task<string> ProcessDocumentStreamAsync(Stream documentStream)
{
    using var input = new OcrInput();
    input.LoadImage(documentStream); // accepts Stream directly

    var ocr = new IronTesseract();
    var result = ocr.Read(input);
    return result.Text;
}
C#

Pas de ReadAllBytes, pas de construction MultipartFormDataContent, pas de POST HTTP. Le flux va directement dans OcrInput. Le guide des entrées de flux couvre les types de flux et les modèles d'évacuation.

Problème 5 : Tests d'intégration dépendant de la simulation HTTP

Klippa : Les tests d'intégration pour le code Klippa simulent HttpClient ou utilisent des intercepteurs HTTP (par exemple, WireMock, MockHttp) pour simuler les réponses de l'API. Ces tests simulent la couche HTTP, et non la logique OCR.

Solution : Les tests IronOCR utilisent de vrais documents avec un résultat attendu connu. Aucune infrastructure de simulation n'est nécessaire. Les tests s'exécutent hors ligne :

[Fact]
public void ReadDocument_ReturnsExpectedText()
{
    IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
    var ocr = new IronTesseract();

    // Use a real test fixture — no HTTP mocking, runs fully offline
    var result = ocr.Read("test-fixtures/sample-invoice.jpg");

    Assert.Contains("Invoice", result.Text, StringComparison.OrdinalIgnoreCase);
    Assert.True(result.Confidence > 70);
}
C#

Les tests qui nécessitaient auparavant une connexion Klippa en direct ou une configuration HTTP simulée complexe s'exécutent désormais en intégration continue sans accès réseau.

Problème n° 6 : Documents de faible qualité améliorés côté serveur par Klippa

Klippa : Le traitement dans le cloud applique une amélioration de l'image avant la reconnaissance. Les développeurs n'ont jamais besoin de configurer cela — cela se fait automatiquement sur les serveurs de Klippa. Lors de la migration, les documents traités silencieusement par Klippa peuvent présenter une précision moindre sans prétraitement explicite dans IronOCR.

Solution : Appliquer explicitement les filtres de prétraitement d'IronOCR. L'ensemble de filtres reflète celui appliqué côté serveur par les services cloud :

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

using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");
input.Deskew();    // fix rotation from camera or scanner
input.DeNoise();   // remove compression noise
input.Contrast();  // boost faded ink
input.Binarize();  // clean background for clearer character edges

var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
C#

Le guide de correction de la qualité d'image couvre tous les filtres de prétraitement et l'ordre dans lequel les appliquer pour différents types de dégradation de documents.

Liste de contrôle de migration Klippa OCR

Pré-migration

Avant de supprimer quoi que ce soit, vérifiez votre code source afin de localiser tout le code spécifique à Klippa :

# Find all files containing Klippa HTTP integration code
grep -r "X-Auth-Key" --include="*.cs" .
grep -r "klippa.com" --include="*.cs" .
grep -r "KlippaService\|KlippaResponse\|KlippaResult\|KlippaData" --include="*.cs" .

# Find all files with MultipartFormDataContent (likely Klippa upload code)
grep -r "MultipartFormDataContent" --include="*.cs" .

# Find all JSON deserialization models that map to Klippa response fields
grep -r "parsed_document\|vat_amount\|merchant\|X-Auth-Key" --include="*.cs" .

# Find all async methods that wrap Klippa calls
grep -r "ParseDocumentAsync\|ProcessReceiptAsync\|UploadAndParseAsync" --include="*.cs" .

# Find test files with HTTP mocks for Klippa
grep -r "MockHttp\|WireMock\|klippa" --include="*.cs" .
SHELL

Notes d'inventaire :

  • Enregistrez chaque classe qui encapsule HttpClient pour les appels Klippa
  • Listez toutes les classes de modèle de désérialisation JSON (KlippaResponse, KlippaParsedDocument, etc.)
  • Documentez tous les mappages de champs qui utilisent les propriétés JSON pré-analysées de Klippa
  • Veuillez noter les politiques de nouvelle tentative Polly ou les boucles de nouvelle tentative personnalisées conçues pour Klippa.

Migration de code

  1. Installez le IronOcr package NuGet (dotnet add package IronOcr)
  2. Ajoutez IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY" au démarrage de l'application
  3. Supprimez les importations System.Net.Http, System.Text.Json, Newtonsoft.Json des fichiers de service Klippa
  4. Supprimez la classe KlippaService (ou remplacez son corps par des appels IronTesseract, en conservant l'interface)
  5. Enregistrez IronTesseract comme singleton dans le conteneur DI
  6. Remplacez les blocs de téléchargement MultipartFormDataContent par OcrInput.LoadImage() ou OcrInput.LoadPdf()
  7. Supprimez les classes de modèle de réponse JSON (KlippaResponse, KlippaData, KlippaParsedDocument)
  8. Remplacez les chaînes de navigation JSON nullable (.Data?.ParsedDocument?.Text) par result.Text
  9. Supprimez les boucles de nouvelle tentative et CancellationTokenSource timeouts des sites d'appel Klippa
  10. Supprimer la gestion des limites de débit (blocs catch HTTP 429)
  11. Remplacez await ProcessDocumentAsync(...) par await ocr.ReadAsync(...) ou ocr.Read(...) synchrones
  12. Ajoutez des filtres de prétraitement OcrInput (Deskew, DeNoise, Contrast) pour les entrées de documents de mauvaise qualité
  13. Remplacer l'infrastructure de test HTTP simulée par des tests de données réelles
  14. Supprimez les stratégies de nouvelle tentative Polly ou le middleware de nouvelle tentative personnalisé limité aux appels Klippa

Après la migration

  • Vérifier que le texte extrait correspond au contenu attendu des documents de test connus.
  • Confirmer que les scores de confiance dépassent le seuil acceptable (généralement 70 % et plus) pour les types de documents de production
  • Testez les entrées PDF : chargez des PDF multi-pages nativement et vérifiez l'accès au texte par page via result.Pages
  • Testez les entrées de flux : passez MemoryStream et vérifiez que OcrInput.LoadImage(stream) produit le bon résultat
  • Vérifier que les filtres de prétraitement améliorent la précision des numérisations de faible qualité par rapport à la ligne de base non traitée
  • Confirmez que le IronTesseract singleton injecté par DI gère les requêtes concurrentes sans contention
  • Exécuter les tests d'intégration hors ligne (sans connexion réseau) — tous les tests doivent réussir sans accès au cloud
  • Vérifiez la sortie du PDF consultable avec result.SaveAsSearchablePdf("output.pdf") pour les flux de documents numérisés
  • Testez ReadAsync dans le contexte du contrôleur ASP.NET Core avec la propagation CancellationToken
  • Confirmez que le modèle de disposition using var input = new OcrInput() ne fuit pas de mémoire sous une charge soutenue

Principaux avantages de la migration vers IronOCR

Souveraineté des données dès le premier jour. Après la migration, vos documents financiers sensibles, les scans d'identité et les factures confidentielles restent à jamais dans votre infrastructure. Il n'y a pas de sous-traitant tiers dans le périmètre de l'audit, pas de politique de conservation des données à examiner et pas d'accord de transfert de données à maintenir. Les contraintes HIPAA, ITAR, CMMC et FedRAMP qui posaient auparavant problème à Klippa sont satisfaites par défaut. Le déploiement sur Docker , AWS ou Azure permet de conserver l'ensemble de vos ressources à l'intérieur des limites de votre propre infrastructure.

Complexité de l'infrastructure éliminée. La classe de service, le client HTTP, le code de téléchargement de formulaire, les modèles JSON, la politique de nouvelle tentative, la configuration du délai d'expiration — tout cela servait à encapsuler un appel réseau. Supprimez l'appel réseau et tout disparaît avec lui. Le code source qui en résulte est plus petit, plus facile à lire et comporte moins de sources de défaillance. Une instance unique IronTesseract injectée par DI remplace l'ensemble de la couche d'intégration HTTP.

Coût prévisible quel que soit le volume. Une licence IronOCR perpétuelle à $999 (Lite), 1 499 $ (Professional) ou 2 999 $ (Enterprise) couvre un traitement illimité des documents. Le traitement de 500 documents par mois ou de 500 000 documents par mois coûte la même chose. Le modèle de facturation par document qui rendait Klippa coûteux à grande échelle est structurellement absent. La page de licences IronOCR détaille tous les niveaux et ce que chacun inclut.

Portée des documents sans limites. IronOCR traite tout document contenant du texte. Les contrats numérisés, les dessins techniques, les formulaires médicaux, les bons de commande, les notes manuscrites, les captures d'écran, les archives TIFF — tous gérés par le même appel Read() avec la même API. La restriction de champ d'application spécialisée qui exigeait un deuxième système pour les documents ne relevant pas des catégories de formation de Klippa a disparu. Une seule bibliothèque, un seul point d'intégration, tout type de document.

Prise en charge désormais des environnements hors ligne et à accès restreint. Les applications déployées sur les réseaux bancaires, les systèmes gouvernementaux, les environnements périphériques ou toute infrastructure avec accès sortant restreint fonctionnent exactement comme dans les environnements ouverts. Il n'y a pas de vérification de connectivité, pas de test de santé vers un point de terminaison cloud, et pas de mode dégradé lorsque la connexion Internet est indisponible. Les déploiements isolés du réseau fonctionnent sans modification. Le guide de déploiement Linux et le guide de déploiement Docker couvrent les voies de déploiement conteneurisées et côté serveur pour ces environnements.

Contrôle total de l'amélioration d'image. Le prétraitement dans le cloud était une boîte noire : Klippa l'appliquait, vous observiez les résultats, vous n'aviez aucun paramètre à régler. Le pipeline de prétraitement d'IronOCR est explicite et composable : Deskew(), DeNoise(), Contrast(), Binarize(), Sharpen(), Scale(), Dilate(), DeepCleanBackgroundNoise(). Chaque filtre est optionnel et doit être commandé. Les améliorations en matière de précision sont mesurables, reproductibles et sous votre contrôle. Le guide de correction de la qualité d'image et la page relative aux fonctionnalités de prétraitement couvrent l'intégralité du catalogue de filtres et fournissent des indications sur le moment opportun pour appliquer chacun d'eux.

Veuillez noter: Klippa et Tesseract sont des marques déposées de leurs propriétaires respectifs. Ce site n'est pas affilié à, approuvé par ou sponsorisé par Google ou Klippa. 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