Altbilgi içeriğine atla
VIDEOLAR

Görüntü Renklerini C#'da Okuma İçin Nasıl Düzeltebilirim

Bu kılavuz, .NET geliştiricilerine, OCR.space'in REST API entegrasyonunu tek bir NuGet paketi olarak sunulan yerel bir .NET kütüphanesi olan IronOCR ile değiştirmeleri için rehberlik eder. Kurulumda paket değişimi, ad alanları temizliği ve REST'ten yerellik dönemine özgü dört somut kod geçiş senaryosu ele alınır: çok parçalı yükleme ortadan kaldırılması, base64 şifreleme çıkarılması, OCR motoru seçim yedeği ve yapılandırılmış veri çıkarımı. 1. Aşama karşılaştırma makalesini okuyarak fazladan bilgi edinmiş olan geliştiriciler, bu kılavuzun, özellik karşılaştırması yerine geçişin mekanik adımlarına odaklandığını görecekler.

OCR.space'den Niçin Geçiş Yapmalısınız

OCR.space gerçek bir boşluk doldurur: herhangi bir uygulama yüklemeye gerek kalmadan, bir öğleden sonra geliştiricilerin OCR'yi test etmek istemesi için sıfır maliyetli deneyim. Sorun, ücretsiz katmanın, üretim için değil prototipleme için tasarlanmış olmasıdır. .NET uygulaması gerçek belge hacimlerine, uyumluluk gereksinimlerine veya ekip geliştirmeye doğru ilerlediğinde, OCR.space entegrasyonunun tüm özellikleri uygulamaya karşı çalışır.

NuGet paketi yok demek SDK ve IntelliSense yok demek. OCR.space bir REST uç noktası ve dokümantasyon sağlar. .NET entegrasyonu — HTTP istemcisi yapımı, istek serileştirme, cevap deserialization, hata yönetimi ve yeniden deneme mantığı — tamamen geliştiricinin sorumluluğundadır. Bu ufak bir rahatsızlık değildir. İlk iş mantığı yöntemi yazılmadan önce minimum uygulanabilir istemci, 80'den fazla altyapı kod satırıdır. Bu kod, her .NET kod tabanında her OCR.space entegrasyonunda fark edilmeyen bir şekilde aynı koddur ve zamanla hata ve bakım yükü biriktirir.

Oran limitleri üretim uygulamalarına yapay sınırlar koyar. Ücretsiz katman IP adresi başına dakikada 60 istek ve günde 500 istek sınırını uygular. Her iki limit de katı duvarlardır. Gece yarısı ile bir sonraki gece yarısı arasında 500 isteği aşan bir uygulama, sayaç sıfırlanana kadar hata yanıtları alır. Ortak ofis ağlarında veya ortak CI/CD ortamlarında çalışan üretim sistemleri, işe başlamadan önce günlük kotayı tüketebilir.

Belgeler her çağrıda altyapınızı terk eder. OCR.space'in yerinde dağıtım seçeneği yoktur. Her istek, belgeyi — faturalar, tıbbi kayıtlar, sözleşmeler, kimlik belgeleri — OCR.space'nin bulut sunucularına iletir. Hassas belgelerin üçüncü taraflara iletilmesini yasaklayan HIPAA, GDPR ve dahili veri sınıflandırma politikaları, sözleşmeye bağlı kontrollerden bağımsız olarak OCR.space'i mimari olarak uyumsuz kılar.

Ücretsiz katman, filigranlı aranabilir PDF'ler üretir. Teslim edilen output olarak aranabilir PDF üreten uygulamalar — belge arşivleme sistemleri, uyum platformları, müşteri odaklı belge portalları — bu amaç için OCR.space'nin ücretsiz katmanını kullanamaz. Filigran, çıktı PDF'ye gömülüdür ve ücretli bir plan olmadan çıkarılamaz.

Abonelik fiyatlandırması hacimle artar; OCR.space PRO seviyesinin yıllık $144 ücreti, altıncı yıldan önce IronOCR'un $999 süresiz giriş fiyatını geçer. Ücretsiz seviye eşiğini aşan döküman hacmi öngörülen ekipler, sabit bir süresiz lisansa karşı abonelik maliyetleriyle karşılaşırlar. $999 Lite lisansı, bir geliştirici ve bir dağıtım konumunu kapsar, herhangi bir hacimde çağrı başına herhangi bir ücret talep etmez. Katman detayları için IronOCR lisans sayfasını görüntüleyin.

Temel Sorun

OCR.space, tek bir belgeyi işlemeye başlamadan önce tam bir HTTP istemcisi inşa etmenizi gerektirir:

// OCR.space: 80+ lines of infrastructure before business logic
public class OcrSpaceApiClient : IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;
    private readonly SemaphoreSlim _rateLimiter; // You implement this

    public OcrSpaceApiClient(string apiKey)
    {
        _httpClient = new HttpClient();
        _httpClient.Timeout = TimeSpan.FromSeconds(120);
        _rateLimiter = new SemaphoreSlim(60, 60); // Free tier: 60/min
    }
    // ... 70+ more lines of HTTP plumbing follow
}
// OCR.space: 80+ lines of infrastructure before business logic
public class OcrSpaceApiClient : IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;
    private readonly SemaphoreSlim _rateLimiter; // You implement this

    public OcrSpaceApiClient(string apiKey)
    {
        _httpClient = new HttpClient();
        _httpClient.Timeout = TimeSpan.FromSeconds(120);
        _rateLimiter = new SemaphoreSlim(60, 60); // Free tier: 60/min
    }
    // ... 70+ more lines of HTTP plumbing follow
}
Imports System
Imports System.Net.Http
Imports System.Threading

' OCR.space: 80+ lines of infrastructure before business logic
Public Class OcrSpaceApiClient
    Implements IDisposable

    Private ReadOnly _httpClient As HttpClient
    Private ReadOnly _apiKey As String
    Private ReadOnly _rateLimiter As SemaphoreSlim ' You implement this

    Public Sub New(apiKey As String)
        _httpClient = New HttpClient()
        _httpClient.Timeout = TimeSpan.FromSeconds(120)
        _rateLimiter = New SemaphoreSlim(60, 60) ' Free tier: 60/min
    End Sub
    ' ... 70+ more lines of HTTP plumbing follow

    Public Sub Dispose() Implements IDisposable.Dispose
        _httpClient.Dispose()
        _rateLimiter.Dispose()
    End Sub
End Class
$vbLabelText   $csharpLabel

IronOCR bir NuGet paketidir. Tüm istemci zaten yazılmıştır:

// IronOCR: no client to build, no rate limiter to manage
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var result = new IronTesseract().Read("document.jpg");
Console.WriteLine(result.Text);
// IronOCR: no client to build, no rate limiter to manage
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var result = new IronTesseract().Read("document.jpg");
Console.WriteLine(result.Text);
Imports IronOcr

' IronOCR: no client to build, no rate limiter to manage
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim result = New IronTesseract().Read("document.jpg")
Console.WriteLine(result.Text)
$vbLabelText   $csharpLabel

IronOCR vs OCR.space: Özellik Karşılaştırması

Aşağıdaki tablo, OCR.space kavramlarını ve kısıtlamalarını doğrudan IronOCR eşdeğerlerine karşı eşlemektedir.

Özellik OCR.space IronOCR
NuGet paketi Yok — REST API sadece IronOcr — doğal .NET
SDK / IntelliSense Yok — manuel JSON Ayrıntılı — tip edilmiş API
Özel modeller gerekli Hayır Hayır
İşleme yeri OCR.space bulut sunucuları Yerel — işlem sırasında
İnternet bağımlılığı Her çağrı için gerekli None
İzole konuşlandırma Desteklenmiyor Tam destekli
Hız sınırları 60/dakika, 500/gün (ücretsiz) None
Dosya boyut sınırı 5 MB (ücretsiz katman) Sadece mevcut bellek
PDF girişi Evet (sınırlı, 5 MB) Evet — yerel, boyut sınırı yok
Aranabilir PDF çıktısı Ücretsiz katmanda filigranlı Temiz çıktı, tüm katmanlar
Otomatik ön işleme Sunucu tarafı, geliştirici kontrolü yok Deskew, DeNoise, Karşıtlık, İkili, Keskinleştir
Dil desteği ~25 dil 125+ NuGet dil paketleri aracılığıyla
Çok dilli her belgede Desteklenmiyor Evet — OcrLanguage.French + OcrLanguage.German
Yapılandırılmış çıktı (kelimeler, satırlar) Sadece düz metin Sayfalar, paragraflar, satırlar, koordinatlı kelimeler
Kelime düzeyinde güven puanları Mevcut değil Evet — word.Confidence
Bölge tabanlı OCR Desteklenmiyor Evet — CropRectangle
Barkod okuma Desteklenmiyor Evet — ReadBarCodes = true
Aranabilir PDF oluşturma Filigranlı (ücretsiz), temiz (ücretli) Temiz çıktı — tüm lisans katmanları
HIPAA / GDPR uyumluluğu Risk — veriler harici olarak iletilir Evet — harici veri iletimi yok
Fiyatlandırma modeli Aylık abonelik Tek seferlik süresiz
Giriş fiyatı $12/ay ($144/yıl) $999 tek seferlik
.NET uyumluluğu HttpClient — herhangi bir .NET .NET 4.6.2+, .NET 5/6/7/8/9
Çapraz platform dağıtımı Dışa doğru internet gerektirir Windows, Linux, macOS, Docker, Azure, AWS

Hızlı Başlangıç: OCR.space üzerinden IronOCR Geçişi

Adım 1: NuGet Paketini Değiştirin

OCR.space'i kaldırılacak bir NuGet paketi yoktur. Projeden tüm OCR.space ile ilgili altyapı kodunu kaldırın: HttpClient sarmalayıcı sınıf, SemaphoreSlim oran sınırlandırıcı, özel sonuç modelleri ve özel istisna türleri. Bunların hepsi IronOCR'un NuGet paketi ile değiştirilmiştir.

IronOCR NuGet sayfasından IronOCR'yi yükleyin:

dotnet add package IronOcr

Adım 2: Ad Alanlarını Güncelleyin

OCR.space HTTP ve JSON ad alanlarını kaldırın.IronOCR ad alanını ekleyin:

// Before (OCR.space — manually written infrastructure)
using System.Net.Http;
using System.Text.Json;
using System.Threading;

// After (IronOCR)
using IronOcr;
// Before (OCR.space — manually written infrastructure)
using System.Net.Http;
using System.Text.Json;
using System.Threading;

// After (IronOCR)
using IronOcr;
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading

Imports IronOcr
$vbLabelText   $csharpLabel

Adım 3: Lisansa İzin Verin

Başvuru başlatmayı uygulama başında bir kez ekleyin — istek başına değil:

// Program.cs or application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Program.cs or application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronOcr

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

Kod Göç Örnekleri

MultipartFormDataContent Dosya Yüklemeleri Değiştiriliyor

OCR.space, dosya baytları ve API anahtarı ile MultipartFormDataContent oluşturmayı, ardından bulut uç noktasına POST yapmayı gerektirir. Belge, her çağrıda altyapınızı terk eder.

OCR.space Yaklaşımı:

// MultipartFormDataContent: file upload to cloud on every request
public async Task<string> UploadAndExtract(string imagePath)
{
    using var content = new MultipartFormDataContent();
    var imageBytes = File.ReadAllBytes(imagePath);

    // Document is transmitted to OCR.space servers here
    content.Add(new ByteArrayContent(imageBytes), "file", Path.GetFileName(imagePath));
    content.Add(new StringContent(_apiKey), "apikey");
    content.Add(new StringContent("eng"), "language");
    content.Add(new StringContent("2"), "OCREngine"); // Select Engine 2

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", content);
    response.EnsureSuccessStatusCode();

    string json = await response.Content.ReadAsStringAsync();
    using var doc = JsonDocument.Parse(json);

    // Navigate JSON tree manually — no typed result
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
// MultipartFormDataContent: file upload to cloud on every request
public async Task<string> UploadAndExtract(string imagePath)
{
    using var content = new MultipartFormDataContent();
    var imageBytes = File.ReadAllBytes(imagePath);

    // Document is transmitted to OCR.space servers here
    content.Add(new ByteArrayContent(imageBytes), "file", Path.GetFileName(imagePath));
    content.Add(new StringContent(_apiKey), "apikey");
    content.Add(new StringContent("eng"), "language");
    content.Add(new StringContent("2"), "OCREngine"); // Select Engine 2

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", content);
    response.EnsureSuccessStatusCode();

    string json = await response.Content.ReadAsStringAsync();
    using var doc = JsonDocument.Parse(json);

    // Navigate JSON tree manually — no typed result
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading.Tasks

Public Class YourClassName
    Private _apiKey As String
    Private _httpClient As HttpClient

    Public Async Function UploadAndExtract(imagePath As String) As Task(Of String)
        Using content As New MultipartFormDataContent()
            Dim imageBytes = File.ReadAllBytes(imagePath)

            ' Document is transmitted to OCR.space servers here
            content.Add(New ByteArrayContent(imageBytes), "file", Path.GetFileName(imagePath))
            content.Add(New StringContent(_apiKey), "apikey")
            content.Add(New StringContent("eng"), "language")
            content.Add(New StringContent("2"), "OCREngine") ' Select Engine 2

            Dim response = Await _httpClient.PostAsync("https://api.ocr.space/parse/image", content)
            response.EnsureSuccessStatusCode()

            Dim json As String = Await response.Content.ReadAsStringAsync()
            Using doc = JsonDocument.Parse(json)
                ' Navigate JSON tree manually — no typed result
                Return doc.RootElement _
                    .GetProperty("ParsedResults")(0) _
                    .GetProperty("ParsedText") _
                    .GetString() OrElse String.Empty
            End Using
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

IronOCR Yaklaşımı:

// OcrInput replaces the entire upload + JSON pipeline
public string ExtractFromFile(string imagePath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath); // Stays local — no network call

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

    return result.Text; // Typed property — no JSON navigation
}
// OcrInput replaces the entire upload + JSON pipeline
public string ExtractFromFile(string imagePath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath); // Stays local — no network call

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

    return result.Text; // Typed property — no JSON navigation
}
Imports IronTesseract

Public Function ExtractFromFile(ByVal imagePath As String) As String
    Using input As New OcrInput()
        input.LoadImage(imagePath) ' Stays local — no network call

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

        Return result.Text ' Typed property — no JSON navigation
    End Using
End Function
$vbLabelText   $csharpLabel

OcrInput, MultipartFormDataContent için yerel bir yedektir. Dosya yolları, bayt dizileri, akışlar ve çok sayfalı TIFF'leri tutarlı bir API üzerinden kabul eder. HttpClient, API anahtar enjeksiyonu ve JSON gezintisi tamamen kaybolur. girdi görüntüleri nasıl yapılır kılavuzu her desteklenen girdi formatını kapsar.

Base64 Şifrelemesini Ortadan Kaldırma

OCR.space entegrasyonları dosya yükleme parametresi yerine base64Image form parametresini kullandığında, kod dosyayı baytlara okur, Base64'e kodlar, bir veri URI dizesi oluşturur ve FormUrlEncodedContent içinde gömülü hale getirir. IronOCR, ham baytları doğrudan şifreleme adımı olmadan kabul eder.

OCR.space Yaklaşımı:

// base64Image parameter: read → encode → embed in form → POST → parse
public async Task<string> ExtractViaBase64(string imagePath)
{
    byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
    string base64Image = Convert.ToBase64String(imageBytes); // Mandatory encoding step

    // Embed as data URI — adds 33% overhead to payload size
    string mimeType = "image/png";
    string dataUri = $"data:{mimeType};base64,{base64Image}";

    var formContent = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", dataUri),
        new KeyValuePair<string, string>("language", "eng"),
        new KeyValuePair<string, string>("isOverlayRequired", "false")
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", formContent);
    string json = await response.Content.ReadAsStringAsync();

    using var doc = JsonDocument.Parse(json);
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
// base64Image parameter: read → encode → embed in form → POST → parse
public async Task<string> ExtractViaBase64(string imagePath)
{
    byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
    string base64Image = Convert.ToBase64String(imageBytes); // Mandatory encoding step

    // Embed as data URI — adds 33% overhead to payload size
    string mimeType = "image/png";
    string dataUri = $"data:{mimeType};base64,{base64Image}";

    var formContent = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", dataUri),
        new KeyValuePair<string, string>("language", "eng"),
        new KeyValuePair<string, string>("isOverlayRequired", "false")
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", formContent);
    string json = await response.Content.ReadAsStringAsync();

    using var doc = JsonDocument.Parse(json);
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading.Tasks

Public Class ImageProcessor
    Private _apiKey As String
    Private _httpClient As HttpClient

    Public Sub New(apiKey As String, httpClient As HttpClient)
        _apiKey = apiKey
        _httpClient = httpClient
    End Sub

    ' base64Image parameter: read → encode → embed in form → POST → parse
    Public Async Function ExtractViaBase64(imagePath As String) As Task(Of String)
        Dim imageBytes As Byte() = Await File.ReadAllBytesAsync(imagePath)
        Dim base64Image As String = Convert.ToBase64String(imageBytes) ' Mandatory encoding step

        ' Embed as data URI — adds 33% overhead to payload size
        Dim mimeType As String = "image/png"
        Dim dataUri As String = $"data:{mimeType};base64,{base64Image}"

        Dim formContent As New FormUrlEncodedContent(New KeyValuePair(Of String, String)() {
            New KeyValuePair(Of String, String)("apikey", _apiKey),
            New KeyValuePair(Of String, String)("base64Image", dataUri),
            New KeyValuePair(Of String, String)("language", "eng"),
            New KeyValuePair(Of String, String)("isOverlayRequired", "false")
        })

        Dim response As HttpResponseMessage = Await _httpClient.PostAsync("https://api.ocr.space/parse/image", formContent)
        Dim json As String = Await response.Content.ReadAsStringAsync()

        Using doc As JsonDocument = JsonDocument.Parse(json)
            Return doc.RootElement _
                .GetProperty("ParsedResults")(0) _
                .GetProperty("ParsedText") _
                .GetString() OrElse String.Empty
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

IronOCR Yaklaşımı:

// LoadImage(bytes): raw bytes accepted directly — no encoding
public string ExtractFromBytes(byte[] imageBytes)
{
    using var input = new OcrInput();
    input.LoadImage(imageBytes); //HayırBase64, no data URI, no overhead

    var result = new IronTesseract().Read(input);
    return result.Text;
}
// LoadImage(bytes): raw bytes accepted directly — no encoding
public string ExtractFromBytes(byte[] imageBytes)
{
    using var input = new OcrInput();
    input.LoadImage(imageBytes); //HayırBase64, no data URI, no overhead

    var result = new IronTesseract().Read(input);
    return result.Text;
}
Imports IronOcr

Public Function ExtractFromBytes(imageBytes As Byte()) As String
    Using input As New OcrInput()
        input.LoadImage(imageBytes) 'HayırBase64, no data URI, no overhead

        Dim result = New IronTesseract().Read(input)
        Return result.Text
    End Using
End Function
$vbLabelText   $csharpLabel

IronOCR'de Base64 şifreleme adımı bulunmamaktadır çünkü bir HTTP taşıma katmanı yoktur. Ham baytlar doğrudan OcrInput.LoadImage() içine gider. Veri URI yükü — Base64 şifreleme, yük boyutunu yaklaşık %33 arttırır — de ortadan kalkar. akış girişi kılavuzu, dosya yerine bir yükleyici veya bellek tamponundan kaynaklanan baytlar için faydalı olan Stream girdileri için aynı deseni gösterir.

OCR Motor Seçimini Resim Ön İşleme ile Değiştirme

OCR.space, OCREngine form parametresi aracılığıyla iki OCR motorunu sunar: Motor 1 karmaşık düzenlerde daha düşük doğrulukla daha hızlıdır; Motor 2, çoğu belge türünde daha yüksek doğruluk ile daha yavaştır. Geliştiriciler, belge özelliklerine dayanarak her çağrı için motoru seçerler. IronOCR, tek bir optimize edilmiş Tesseract 5 motoru çalıştırır ancak motor modlarına geçiş yapmak yerine kök neden olan belge kalitesine odaklanan explicit ön işleme filtreleri sunar.

OCR.space Yaklaşımı:

// OCREngine parameter: binary choice, no control over why accuracy differs
public async Task<string> ExtractWithEngineSelection(
    string imagePath,
    bool useHighAccuracyEngine = true)
{
    byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
    string base64 = Convert.ToBase64String(imageBytes);

    var formContent = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", $"data:image/png;base64,{base64}"),
        new KeyValuePair<string, string>("language", "eng"),
        // Engine 1 = faster, Engine 2 = higher accuracy — binary choice only
        new KeyValuePair<string, string>("OCREngine", useHighAccuracyEngine ? "2" : "1"),
        new KeyValuePair<string, string>("scale", "true"),
        new KeyValuePair<string, string>("detectOrientation", "true")
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", formContent);
    string json = await response.Content.ReadAsStringAsync();

    using var doc = JsonDocument.Parse(json);
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
// OCREngine parameter: binary choice, no control over why accuracy differs
public async Task<string> ExtractWithEngineSelection(
    string imagePath,
    bool useHighAccuracyEngine = true)
{
    byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
    string base64 = Convert.ToBase64String(imageBytes);

    var formContent = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", $"data:image/png;base64,{base64}"),
        new KeyValuePair<string, string>("language", "eng"),
        // Engine 1 = faster, Engine 2 = higher accuracy — binary choice only
        new KeyValuePair<string, string>("OCREngine", useHighAccuracyEngine ? "2" : "1"),
        new KeyValuePair<string, string>("scale", "true"),
        new KeyValuePair<string, string>("detectOrientation", "true")
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", formContent);
    string json = await response.Content.ReadAsStringAsync();

    using var doc = JsonDocument.Parse(json);
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading.Tasks

Public Class OCRService
    Private _apiKey As String
    Private _httpClient As HttpClient

    Public Sub New(apiKey As String, httpClient As HttpClient)
        _apiKey = apiKey
        _httpClient = httpClient
    End Sub

    ' OCREngine parameter: binary choice, no control over why accuracy differs
    Public Async Function ExtractWithEngineSelection(imagePath As String, Optional useHighAccuracyEngine As Boolean = True) As Task(Of String)
        Dim imageBytes As Byte() = Await File.ReadAllBytesAsync(imagePath)
        Dim base64 As String = Convert.ToBase64String(imageBytes)

        Dim formContent As New FormUrlEncodedContent(New KeyValuePair(Of String, String)() {
            New KeyValuePair(Of String, String)("apikey", _apiKey),
            New KeyValuePair(Of String, String)("base64Image", $"data:image/png;base64,{base64}"),
            New KeyValuePair(Of String, String)("language", "eng"),
            ' Engine 1 = faster, Engine 2 = higher accuracy — binary choice only
            New KeyValuePair(Of String, String)("OCREngine", If(useHighAccuracyEngine, "2", "1")),
            New KeyValuePair(Of String, String)("scale", "true"),
            New KeyValuePair(Of String, String)("detectOrientation", "true")
        })

        Dim response As HttpResponseMessage = Await _httpClient.PostAsync("https://api.ocr.space/parse/image", formContent)
        Dim json As String = Await response.Content.ReadAsStringAsync()

        Using doc As JsonDocument = JsonDocument.Parse(json)
            Return doc.RootElement _
                .GetProperty("ParsedResults")(0) _
                .GetProperty("ParsedText") _
                .GetString() OrElse String.Empty
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

IronOCR Yaklaşımı:

// Preprocessing pipeline: fix the document, not the engine selection
public string ExtractWithPreprocessing(string imagePath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);

    // Apply filters that match the document's specific quality issues
    input.Deskew();         // Correct rotation — replaces detectOrientation
    input.DeNoise();        // Remove noise from fax/photocopier artifacts
    input.Contrast();       // Enhance contrast on low-quality scans
    input.Scale(200);       // Upscale small or low-DPI images

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

    Console.WriteLine($"Confidence: {result.Confidence}%"); //Hayırequivalent in OCR.space
    return result.Text;
}
// Preprocessing pipeline: fix the document, not the engine selection
public string ExtractWithPreprocessing(string imagePath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);

    // Apply filters that match the document's specific quality issues
    input.Deskew();         // Correct rotation — replaces detectOrientation
    input.DeNoise();        // Remove noise from fax/photocopier artifacts
    input.Contrast();       // Enhance contrast on low-quality scans
    input.Scale(200);       // Upscale small or low-DPI images

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

    Console.WriteLine($"Confidence: {result.Confidence}%"); //Hayırequivalent in OCR.space
    return result.Text;
}
Imports System

Public Class Example
    ' Preprocessing pipeline: fix the document, not the engine selection
    Public Function ExtractWithPreprocessing(imagePath As String) As String
        Using input As New OcrInput()
            input.LoadImage(imagePath)

            ' Apply filters that match the document's specific quality issues
            input.Deskew()         ' Correct rotation — replaces detectOrientation
            input.DeNoise()        ' Remove noise from fax/photocopier artifacts
            input.Contrast()       ' Enhance contrast on low-quality scans
            input.Scale(200)       ' Upscale small or low-DPI images

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

            Console.WriteLine($"Confidence: {result.Confidence}%") ' Equivalent in OCR.space
            Return result.Text
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

OCR.space OCREngine parametresi belge kalitesi için bir vekildir — Motor 1 bir belgede başarısız olduğunda, geliştiriciler farklı algoritmanın telafi edeceğini umarak Motor 2'ye geçerler. IronOCR'un ön işleme hattı kalite sorununu doğrudan ele alır: Deskew() eğik taramaları düzeltir, DeNoise() faks artefaktlarını işler ve Contrast() düşük kontrastlı fotokopilerden metinleri kurtarır. Sonucun Confidence özelliği, çıkarım kalitesini nicelendirir, bu OCREngine geçişi sağlayamaz. görüntü kalitesi düzeltme kılavuzu ve filtre sihirbazı , her filtrenin farklı belge türlerine etkisini belgelendirir.

Çağrı Başına Dil Geçişi Olmadan Çok Dilli OCR

OCR.space, her API çağrısı için bir language parametresini kabul eder. Karışık diller içeren belgeler, her dil için ayrı ayrı çağrılar gerektirir, sonuçlar manuel olarak birleştirilir. IronOCR, + operatörünü OcrLanguage değerlerinde kullanarak tek bir okuma işlemiyle birden fazla dili aynı anda işler.

OCR.space Yaklaşımı:

// OCR.space: one language per call — multi-language requires multiple requests
public async Task<string> ExtractMultiLanguage(string imagePath)
{
    // First pass: English
    string englishText = await ExtractWithLanguage(imagePath, "eng");

    // Second pass: French (consumes another rate-limit slot, another API call)
    string frenchText = await ExtractWithLanguage(imagePath, "fre");

    // Manually merge results — no way to know which text belongs to which language
    return $"{englishText}\n{frenchText}";
}

private async Task<string> ExtractWithLanguage(string imagePath, string langCode)
{
    byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
    string base64 = Convert.ToBase64String(imageBytes);

    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", $"data:image/png;base64,{base64}"),
        new KeyValuePair<string, string>("language", langCode) // One language per call
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", content);
    string json = await response.Content.ReadAsStringAsync();

    using var doc = JsonDocument.Parse(json);
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
// OCR.space: one language per call — multi-language requires multiple requests
public async Task<string> ExtractMultiLanguage(string imagePath)
{
    // First pass: English
    string englishText = await ExtractWithLanguage(imagePath, "eng");

    // Second pass: French (consumes another rate-limit slot, another API call)
    string frenchText = await ExtractWithLanguage(imagePath, "fre");

    // Manually merge results — no way to know which text belongs to which language
    return $"{englishText}\n{frenchText}";
}

private async Task<string> ExtractWithLanguage(string imagePath, string langCode)
{
    byte[] imageBytes = await File.ReadAllBytesAsync(imagePath);
    string base64 = Convert.ToBase64String(imageBytes);

    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", $"data:image/png;base64,{base64}"),
        new KeyValuePair<string, string>("language", langCode) // One language per call
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", content);
    string json = await response.Content.ReadAsStringAsync();

    using var doc = JsonDocument.Parse(json);
    return doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("ParsedText")
        .GetString() ?? string.Empty;
}
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading.Tasks

Public Class OCRSpace
    Private _apiKey As String
    Private _httpClient As HttpClient

    Public Async Function ExtractMultiLanguage(imagePath As String) As Task(Of String)
        ' First pass: English
        Dim englishText As String = Await ExtractWithLanguage(imagePath, "eng")

        ' Second pass: French (consumes another rate-limit slot, another API call)
        Dim frenchText As String = Await ExtractWithLanguage(imagePath, "fre")

        ' Manually merge results — no way to know which text belongs to which language
        Return $"{englishText}{vbLf}{frenchText}"
    End Function

    Private Async Function ExtractWithLanguage(imagePath As String, langCode As String) As Task(Of String)
        Dim imageBytes As Byte() = Await File.ReadAllBytesAsync(imagePath)
        Dim base64 As String = Convert.ToBase64String(imageBytes)

        Dim content = New FormUrlEncodedContent(New KeyValuePair(Of String, String)() {
            New KeyValuePair(Of String, String)("apikey", _apiKey),
            New KeyValuePair(Of String, String)("base64Image", $"data:image/png;base64,{base64}"),
            New KeyValuePair(Of String, String)("language", langCode) ' One language per call
        })

        Dim response = Await _httpClient.PostAsync("https://api.ocr.space/parse/image", content)
        Dim json As String = Await response.Content.ReadAsStringAsync()

        Using doc = JsonDocument.Parse(json)
            Return doc.RootElement _
                .GetProperty("ParsedResults")(0) _
                .GetProperty("ParsedText") _
                .GetString() OrElse String.Empty
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

IronOCR Yaklaşımı:

// IronOCR: multiple languages in a single read — one pass, correct output
public string ExtractMultiLanguage(string imagePath)
{
    var ocr = new IronTesseract();

    // Combine languages with + operator — processed simultaneously
    ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;

    var result = ocr.Read(imagePath);
    return result.Text; // Correctly interleaved multilingual output
}
// IronOCR: multiple languages in a single read — one pass, correct output
public string ExtractMultiLanguage(string imagePath)
{
    var ocr = new IronTesseract();

    // Combine languages with + operator — processed simultaneously
    ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;

    var result = ocr.Read(imagePath);
    return result.Text; // Correctly interleaved multilingual output
}
Imports IronOcr

Public Function ExtractMultiLanguage(imagePath As String) As String
    Dim ocr As New IronTesseract()

    ' Combine languages with + operator — processed simultaneously
    ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German

    Dim result = ocr.Read(imagePath)
    Return result.Text ' Correctly interleaved multilingual output
End Function
$vbLabelText   $csharpLabel

OCR.space'nin her çağrı için tek dil kısıtlaması, geliştiricileri N diline sahip bir belge için N API çağrısı yapmaya ve sonuçları nasıl uzlaştırabileceklerini tahmin etmeye zorlar. IronOCR, dil modellerini tek bir motor geçişine birleştirir ve son işlem olmadan doğru bir şekilde iç içe geçmiş çıktı üretir. Dil paketleri NuGet paketleri olarak yüklenir — IronOcr.Languages.French, IronOcr.Languages.German gibi — ve çevrimdışı çalışır. birden fazla dil nasıl yapılır rehberi, tüm 125+ Desteklenen diller için paket yüklemeyi ve + operatör sözdizimini kapsar.

Sözel Koordinatlarla Yapılandırılmış Veri Çıkarma

OCR.space ParsedResults[0].ParsedText plain text döndürür. Kelime düzeyinde veri, bağlama kutuları, hat sınırları ve her öğe için güven puanları yoktur. Belirli alanları bulması gereken uygulamalar — bir faturanın sağ üst köşesindeki bir tarih, bir tablonun alt sağ hücresinde bir toplam — OCR.space yanıtından inşa edilebilecek bir yapı bulunmamaktadır. IronOCR, her biri piksel koordinatları ve güven puanları ile sayfalar, paragraflar, satırlar, kelimeler ve karakterler olmak üzere tam bir belge hierarşisi sağlar.

OCR.space Yaklaşımı:

// OCR.space: plain text only — no structure, no coordinates
public async Task<string> ExtractInvoiceFields(string invoicePath)
{
    byte[] invoiceBytes = await File.ReadAllBytesAsync(invoicePath);
    string base64 = Convert.ToBase64String(invoiceBytes);

    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", $"data:application/pdf;base64,{base64}"),
        new KeyValuePair<string, string>("filetype", "PDF"),
        new KeyValuePair<string, string>("language", "eng"),
        // isOverlayRequired=true returns word boxes, but only as raw JSON coordinates
        new KeyValuePair<string, string>("isOverlayRequired", "true")
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", content);
    string json = await response.Content.ReadAsStringAsync();

    // Navigate deeply-nested JSON to find word boxes — no typed models
    using var doc = JsonDocument.Parse(json);
    var overlay = doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("TextOverlay");

    // Parse word coordinate arrays manually — fragile JSON path traversal
    var wordData = new List<(string word, int x, int y)>();
    foreach (var line in overlay.GetProperty("Lines").EnumerateArray())
    {
        foreach (var word in line.GetProperty("Words").EnumerateArray())
        {
            string wordText = word.GetProperty("WordText").GetString() ?? "";
            int left = word.GetProperty("Left").GetInt32();
            int top = word.GetProperty("Top").GetInt32();
            wordData.Add((wordText, left, top));
        }
    }

    // Reconstruct full text from raw JSON — still no typed result
    return string.Join(" ", wordData.Select(w => w.word));
}
// OCR.space: plain text only — no structure, no coordinates
public async Task<string> ExtractInvoiceFields(string invoicePath)
{
    byte[] invoiceBytes = await File.ReadAllBytesAsync(invoicePath);
    string base64 = Convert.ToBase64String(invoiceBytes);

    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("apikey", _apiKey),
        new KeyValuePair<string, string>("base64Image", $"data:application/pdf;base64,{base64}"),
        new KeyValuePair<string, string>("filetype", "PDF"),
        new KeyValuePair<string, string>("language", "eng"),
        // isOverlayRequired=true returns word boxes, but only as raw JSON coordinates
        new KeyValuePair<string, string>("isOverlayRequired", "true")
    });

    var response = await _httpClient.PostAsync("https://api.ocr.space/parse/image", content);
    string json = await response.Content.ReadAsStringAsync();

    // Navigate deeply-nested JSON to find word boxes — no typed models
    using var doc = JsonDocument.Parse(json);
    var overlay = doc.RootElement
        .GetProperty("ParsedResults")[0]
        .GetProperty("TextOverlay");

    // Parse word coordinate arrays manually — fragile JSON path traversal
    var wordData = new List<(string word, int x, int y)>();
    foreach (var line in overlay.GetProperty("Lines").EnumerateArray())
    {
        foreach (var word in line.GetProperty("Words").EnumerateArray())
        {
            string wordText = word.GetProperty("WordText").GetString() ?? "";
            int left = word.GetProperty("Left").GetInt32();
            int top = word.GetProperty("Top").GetInt32();
            wordData.Add((wordText, left, top));
        }
    }

    // Reconstruct full text from raw JSON — still no typed result
    return string.Join(" ", wordData.Select(w => w.word));
}
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading.Tasks

Public Class InvoiceProcessor
    Private _apiKey As String
    Private _httpClient As HttpClient

    Public Sub New(apiKey As String, httpClient As HttpClient)
        _apiKey = apiKey
        _httpClient = httpClient
    End Sub

    Public Async Function ExtractInvoiceFields(invoicePath As String) As Task(Of String)
        Dim invoiceBytes As Byte() = Await File.ReadAllBytesAsync(invoicePath)
        Dim base64 As String = Convert.ToBase64String(invoiceBytes)

        Dim content As New FormUrlEncodedContent(New KeyValuePair(Of String, String)() {
            New KeyValuePair(Of String, String)("apikey", _apiKey),
            New KeyValuePair(Of String, String)("base64Image", $"data:application/pdf;base64,{base64}"),
            New KeyValuePair(Of String, String)("filetype", "PDF"),
            New KeyValuePair(Of String, String)("language", "eng"),
            New KeyValuePair(Of String, String)("isOverlayRequired", "true")
        })

        Dim response As HttpResponseMessage = Await _httpClient.PostAsync("https://api.ocr.space/parse/image", content)
        Dim json As String = Await response.Content.ReadAsStringAsync()

        Using doc As JsonDocument = JsonDocument.Parse(json)
            Dim overlay = doc.RootElement _
                .GetProperty("ParsedResults")(0) _
                .GetProperty("TextOverlay")

            Dim wordData As New List(Of (word As String, x As Integer, y As Integer))()
            For Each line In overlay.GetProperty("Lines").EnumerateArray()
                For Each word In line.GetProperty("Words").EnumerateArray()
                    Dim wordText As String = word.GetProperty("WordText").GetString() OrElse ""
                    Dim left As Integer = word.GetProperty("Left").GetInt32()
                    Dim top As Integer = word.GetProperty("Top").GetInt32()
                    wordData.Add((wordText, left, top))
                Next
            Next

            Return String.Join(" ", wordData.Select(Function(w) w.word))
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

IronOCR Yaklaşımı:

// IronOCR: full document hierarchy — typed, no JSON, no coordinates parsing
public void ExtractInvoiceFields(string invoicePath)
{
    var ocr = new IronTesseract();
    var result = ocr.Read(invoicePath);

    // Access the full document hierarchy — all strongly typed
    foreach (var page in result.Pages)
    {
        foreach (var paragraph in page.Paragraphs)
        {
            Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}");
        }

        foreach (var word in page.Words)
        {
            // Word-level confidence — identify low-quality extractions
            if (word.Confidence < 70)
                Console.WriteLine($"Low confidence word '{word.Text}' at ({word.X}, {word.Y})");
        }
    }

    // Or use region-based OCR to target specific invoice zones directly
    var totalRegion = new CropRectangle(400, 700, 200, 50); // Bottom-right total field
    using var input = new OcrInput();
    input.LoadImage(invoicePath, totalRegion);
    string totalText = ocr.Read(input).Text;
    Console.WriteLine($"Invoice total: {totalText}");
}
// IronOCR: full document hierarchy — typed, no JSON, no coordinates parsing
public void ExtractInvoiceFields(string invoicePath)
{
    var ocr = new IronTesseract();
    var result = ocr.Read(invoicePath);

    // Access the full document hierarchy — all strongly typed
    foreach (var page in result.Pages)
    {
        foreach (var paragraph in page.Paragraphs)
        {
            Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}");
        }

        foreach (var word in page.Words)
        {
            // Word-level confidence — identify low-quality extractions
            if (word.Confidence < 70)
                Console.WriteLine($"Low confidence word '{word.Text}' at ({word.X}, {word.Y})");
        }
    }

    // Or use region-based OCR to target specific invoice zones directly
    var totalRegion = new CropRectangle(400, 700, 200, 50); // Bottom-right total field
    using var input = new OcrInput();
    input.LoadImage(invoicePath, totalRegion);
    string totalText = ocr.Read(input).Text;
    Console.WriteLine($"Invoice total: {totalText}");
}
Imports IronOcr

Public Sub ExtractInvoiceFields(invoicePath As String)
    Dim ocr As New IronTesseract()
    Dim result = ocr.Read(invoicePath)

    ' Access the full document hierarchy — all strongly typed
    For Each page In result.Pages
        For Each paragraph In page.Paragraphs
            Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}")
        Next

        For Each word In page.Words
            ' Word-level confidence — identify low-quality extractions
            If word.Confidence < 70 Then
                Console.WriteLine($"Low confidence word '{word.Text}' at ({word.X}, {word.Y})")
            End If
        Next
    Next

    ' Or use region-based OCR to target specific invoice zones directly
    Dim totalRegion As New CropRectangle(400, 700, 200, 50) ' Bottom-right total field
    Using input As New OcrInput()
        input.LoadImage(invoicePath, totalRegion)
        Dim totalText As String = ocr.Read(input).Text
        Console.WriteLine($"Invoice total: {totalText}")
    End Using
End Sub
$vbLabelText   $csharpLabel

OCR.space isOverlayRequired=true bayrağı JSON kelime koordinatları döndürür, ancak yanıt yapısı, yazılı bir model olmadan, IntelliSense olmadan ve yanıt yapısı değişirse kırılacak olan yap fragmanları ile iç içe geçmiş JSON dizilerinin gezilmesini gerektirir. IronOCR'un result.Pages, result.Words ve result.Lines adlandırılmış .NET nesneleridir. CropRectangle yaklaşımı, açıkça dokumentik bölgeleri hedef alır, tüm belgeyi çıkarmak yerine doğrudan belirli koordinatlara göre filtreleyerek çalışma yapar. okuma sonuçları nasıl yapılır ve bölge tabanlı OCR kılavuzu her iki deseni ayrıntılı olarak kapsar.

OCR.space API'si ile IronOCR Haritalama Referansı

OCR.space Konsepti IronOCR Karşılığı
NuGet paketi yok dotnet add package IronOcr
HttpClient inşaatı Gerekli değil — HTTP katmanı yok
SemaphoreSlim oran sınırlandırıcı Gerekli değil — oran limitleri yok
FormUrlEncodedContent / MultipartFormDataContent OcrInput
base64Image veri URI parametresi input.LoadImage(bytes)
file yükleme parametresi input.LoadImage(path)
apikey başlık / form alanı IronOcr.License.LicenseKey (başlangıçta bir kez)
language parametresi (çağrı başına bir kez) ocr.Language = OcrLanguage.English + OcrLanguage.French
OCREngine=1 (hızlı) Varsayılan motor (optimize edilmiş Tesseract 5)
OCREngine=2 (yüksek doğruluk) input.Deskew(); input.DeNoise(); input.Contrast();
scale=true parametresi input.Scale(200)
detectOrientation=true parametresi input.Deskew()
isOverlayRequired=true parametresi result.Pages[n].Words (her zaman mevcut, adlandırılmış)
isCreateSearchablePdf=true parametresi result.SaveAsSearchablePdf("output.pdf")
filetype=PDF parametresi input.LoadPdf(path)
ParsedResults[0].ParsedText result.Text
ParsedResults[n] (sayfa başına metin) result.Pages[n].Text
TextOverlay.Lines[n].Words[n].WordText result.Pages[n].Words[n].Text
TextOverlay.Lines[n].Words[n].Left/Top result.Pages[n].Words[n].X / .Y
IsErroredOnProcessing JSON bayrağı Exception standart Exception mesajı ile
FileParseExitCode sayfa başına bayrak Exception standart Exception mesajı ile
HTTP 429 Çok Fazla İstek Geçerli değil — hız sınırları yok
Özel OcrResult POCO (kullanıcı tanımlı) IronOcr.OcrResult (NuGet tarafından sağlanır)
Özel OcrSpaceException (kullanıcı tanımlı) Standart .NET istisna türleri

Yaygın Göç Sorunları ve Çözümleri

Sorun 1: Yalnızca HTTP İçin Var Olan Asenkron Kod

OCR.space: Bir HTTP yolculuğu içerdiğinden her OCR çağrısı async şeklindedir. Hizmet yöntemleri, denetleyici eylemleri ve arka plan işleri, ağ beklemesi sırasında iş parçacığını engellememek için asenkron yapılmıştır.

Çözüm: IronOCR'un Read() metodu senkronizdir. Asenkron olan yöntemlerden await kaldırın çünkü bunlar sadece OCR.space'de gerekli idi. Bloklamayan yürütme önemli olan ASP.NET Core bağlamlarında, senkron çağrıyı Task.Run() içine sarmalayın veya asenkron OCR kılavuzu nda belgelenen asenkron kalıpları kullanın.IronOCR çağrılarına refleksif olarak await eklemeyin — gereksiz bir maliyet ekler ve web dışı bağlamlarda gereksizdir.

// Before: async because OCR.space required network I/O
public async Task<string> ProcessDocumentAsync(string path)
{
    return await _ocrSpaceClient.ExtractTextAsync(path); // Network wait
}

// After: synchronous — no network, no async needed
public string ProcessDocument(string path)
{
    return _ocr.Read(path).Text; // Local execution
}
// Before: async because OCR.space required network I/O
public async Task<string> ProcessDocumentAsync(string path)
{
    return await _ocrSpaceClient.ExtractTextAsync(path); // Network wait
}

// After: synchronous — no network, no async needed
public string ProcessDocument(string path)
{
    return _ocr.Read(path).Text; // Local execution
}
Imports System.Threading.Tasks

' Before: async because OCR.space required network I/O
Public Async Function ProcessDocumentAsync(path As String) As Task(Of String)
    Return Await _ocrSpaceClient.ExtractTextAsync(path) ' Network wait
End Function

' After: synchronous — no network, no async needed
Public Function ProcessDocument(path As String) As String
    Return _ocr.Read(path).Text ' Local execution
End Function
$vbLabelText   $csharpLabel

Sorun 2: API Anahtarı Depolama ve Yenileme Altyapısı

OCR.space: API anahtarı her talebe enjekte edilmelidir. Ekipler genellikle bunu appsettings.json veya ortam değişkenlerinde saklar, IOptions<t> veya yapıcı enjeksiyon yoluyla enjekte eder ve maruz kaldığında rotasyon yapar. Anahtar yenilemesi her dağıtım ortamının güncellenmesi ve uygulamanın yeniden başlatılmasını gerektirir.

Çözüm:IronOCR lisans anahtarı başlatıldığında bir kez ayarlanır ve yürütme sırasında bir daha referans verilmez. İstek başına anahtar enjeksiyon modelini kaldırın. IOptions<OcrSpaceSettings> yapılandırma sınıfını kaldırın. Anahtar başlatma deseninde bir satır vardır:

// Startup.cs or Program.cs — once only
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
// Startup.cs or Program.cs — once only
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
Imports System

' Startup.vb or Program.vb — once only
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
$vbLabelText   $csharpLabel

İstek başına kimlik doğrulama hendeği yoktur, anahtar döndürme prosedürü yoktur ve anahtarın istek izlerinde yanlışlıkla günlüğe alınma riski yoktur.

Sorun 3: Dosya Boyutu Ön Doğrulama Mantığı

OCR.space: Ücretsiz katman, 5 MB'nin üzerindeki dosyaları hata yanıtıyla reddeder. Üretim kodu, bu kontrolü her istekte bir oran sınırı yuvasının boşa gitmesini önlemek için ekler:

// OCR.space: pre-validation to avoid wasting quota on large files
var fileInfo = new FileInfo(filePath);
if (fileInfo.Length > 5 * 1024 * 1024)
    throw new InvalidOperationException("File exceeds 5MB free tier limit.");
// OCR.space: pre-validation to avoid wasting quota on large files
var fileInfo = new FileInfo(filePath);
if (fileInfo.Length > 5 * 1024 * 1024)
    throw new InvalidOperationException("File exceeds 5MB free tier limit.");
Dim fileInfo As New FileInfo(filePath)
If fileInfo.Length > 5 * 1024 * 1024 Then
    Throw New InvalidOperationException("File exceeds 5MB free tier limit.")
End If
$vbLabelText   $csharpLabel

Çözüm: Bu kontrolü tamamen kaldırın. IronOCR'un OcrInput.LoadPdf() ve OcrInput.LoadImage() sistem belleği dışında bir boyut kısıtlamasına sahip değildir. Yapay 5 MB eşiği yalnızca OCR.space'nin ücretsiz katmanı sunucu kapasiteleri nedeniyle bunu uygular. 50 MB taranmış bir PDF, 500 KB bir PDF gibi aynı şekilde yüklenir.

Sorun 4: JSON Yanıt Gezinme Kırılganlığı

OCR.space: Yanıt ayrıştırma, dize anahtarlı özellik erişimi ile JsonDocument gezinmeye dayanır. Yanıt şekli değişirse, doc.RootElement.GetProperty("ParsedResults")[0].GetProperty("ParsedText") gibi kodlar KeyNotFoundException, ve ParsedResults boşsa IndexOutOfRangeException fırlatır. Her iki durumda da boyunca try-catch korumaları veya null kontrolleri gereklidir.

Çözüm:IronOCR bir adlandırılmış OcrResult nesnesi döndürür. .Text özelliği her zaman bir string — hiçbir zaman null değil, hiçbir zaman eksik değil. OCR hiçbir çıktı üretmezse (boş sayfa, okunamayan görüntü), result.Text boş bir dizedir. Gezilecek JSON yoktur ve korunacak özellik yolu kırılganlığı yoktur. Güven bazlı filtreleme için result.Confidence, doğrudan karşılaştırabileceğiniz bir double döndürür:

// IronOCR: typed result — no JSON path fragility
var result = new IronTesseract().Read("document.jpg");

if (result.Confidence < 50)
    Console.WriteLine("Low confidence — consider preprocessing");
else
    Console.WriteLine(result.Text);
// IronOCR: typed result — no JSON path fragility
var result = new IronTesseract().Read("document.jpg");

if (result.Confidence < 50)
    Console.WriteLine("Low confidence — consider preprocessing");
else
    Console.WriteLine(result.Text);
Imports IronOcr

Dim result = New IronTesseract().Read("document.jpg")

If result.Confidence < 50 Then
    Console.WriteLine("Low confidence — consider preprocessing")
Else
    Console.WriteLine(result.Text)
End If
$vbLabelText   $csharpLabel

güven puanları nasıl yapılır rehberi, kelime başına ve belgeler arası güven eşiklerini kapsar.

Sorun 5: CI/CD'deki Paylaşılan IP Oran Sınırı Tükenmesi

OCR.space: OCR.space'e karşı bütünleşik testleri başlatan CI/CD hatları, geliştirme ofis ağı ile aynı giden IP adresini kullanır. Ücretsiz katman hesapları, IP başına günlük 500 istek sınırını paylaşır. Her çalışmada 200 test dokümanı işleyen bir boru hattı, ilk geliştirici manuel test yapmadan önce günlük kotayı tüketebilir. Takımlar, entegrasyon testinin amacını boşa çıkaran testlerde OCR.space yanıtlarını taklit ederek bu durumu aşar.

Çözüm: IronOCR, yerel olarak işler. Test seti new IronTesseract().Read(testImagePath).Text doğrudan çağırır — taklit etmeye gerek yoktur, kota yoktur ve ağ bağımlılığı yoktur. Entegrasyon testleri, herhangi bir hız sınırı yönetimi veya test izolasyon desenleri olmadan, üretimle aynı gerçek OCR sonuçlarıyla CI/CD'de çalışır.

Sorun 6: IDisposable HttpClient yönetimi deseninden

OCR.space: HttpClient sarmalayıcı sınıf, HTTP bağlantı havuzunu salmak için IDisposable uygular. OCR hizmeti tüketicileri ya bir singleton enjekte etmeli, using blokları kullanmalı ya da DI kapsayıcının imha yaşam döngüsünde kaydetmelidir. Tasfiye etmeyi unutmak, yük altında soket tükenmesine neden olur.

Çözüm: IronTesseract ağ bağlantılarını yönetmez. IDisposable uygulamaz. Her konu için bir örnek oluşturun (veya ASP.NET'te her istek için), .Read() çağrısı yapın ve çöp toplayıcıya bırakın. OcrInput sınıfı IDisposable uygular ve ön işleme uygulandığında using bloklarına sarılmalıdır; ancak, birincil IronTesseract sınıfında yaşam döngüsü yönetimi gerekmez. OCR hizmeti sarmalayıcınızdan IDisposable uygulamasını kaldırın ve DI kaydını, bertaraf edilmesi gereken kapsamlı / geçici bir şekilde basit bir fabrika veya singleton'a sadeleştirin.

OCR.space Geçiş Kontrol Listesi

Geçiş Öncesi Görevler

Tüm OCR.space entegrasyon noktalarını belirlemek için kod tabanını denetleyin:

# Find all OCR.space HTTP calls
grep -rn "ocr.space" --include="*.cs" .

# Find all base64 encoding related to OCR
grep -rn "base64Image\|Convert.ToBase64String" --include="*.cs" .

# Find rate limiter and retry logic
grep -rn "SemaphoreSlim\|TooManyRequests\|exponential" --include="*.cs" .

# Find JSON parsing for OCR responses
grep -rn "ParsedResults\|IsErroredOnProcessing\|FileParseExitCode" --include="*.cs" .

# Find custom OCR models and exception types
grep -rn "OcrSpaceException\|OcrResult\b" --include="*.cs" .

# Find API key configuration
grep -rn "apikey\|OcrSpaceApiKey\|ocr_space" --include="*.cs" --include="*.json" .
# Find all OCR.space HTTP calls
grep -rn "ocr.space" --include="*.cs" .

# Find all base64 encoding related to OCR
grep -rn "base64Image\|Convert.ToBase64String" --include="*.cs" .

# Find rate limiter and retry logic
grep -rn "SemaphoreSlim\|TooManyRequests\|exponential" --include="*.cs" .

# Find JSON parsing for OCR responses
grep -rn "ParsedResults\|IsErroredOnProcessing\|FileParseExitCode" --include="*.cs" .

# Find custom OCR models and exception types
grep -rn "OcrSpaceException\|OcrResult\b" --include="*.cs" .

# Find API key configuration
grep -rn "apikey\|OcrSpaceApiKey\|ocr_space" --include="*.cs" --include="*.json" .
SHELL

OCR.space kodu içeren dosyaların listesini belgeleyin. OCR.space'in HTTP bağımlılığı nedeniyle yalnızca async olan yöntemlerin hangileri olduğunu not alın — bunlar göçten sonra senkronize hale gelebilir.

Kod Güncelleme Görevleri

  1. IronOcr NuGet paketini yükleyin: dotnet add package IronOcr
  2. Uygulama başlangıcına IronOcr.License.LicenseKey = "..." ekleyin
  3. OcrSpaceApiClient sınıfını ve tüm destek altyapısını silin
  4. Özel OcrResult POCO'yu silin (IronOcr.OcrResult ile değiştirildi)
  5. Özel OcrSpaceException sınıfını silin (standart .NET istisnaları ile değiştirildi)
  6. SemaphoreSlim oran sınırlayıcıyı ve ilişkili Task.Delay mantığını silin
  7. OCR görüntü kodlaması için kullanılan tüm Convert.ToBase64String() çağrılarını kaldırın 8.FormUrlEncodedContent / MultipartFormDataContentyapımını OcrInput ile değiştirin
  8. _httpClient.PostAsync(...) çağrılarını new IronTesseract().Read(input) ile değiştirin
  9. JsonDocument , ParsedResults[0].ParsedText'nın saf dışı analizi ile result.Text ile değiştirin
  10. TextOverlay JSON koordinat analizini result.Pages[n].Words ile değiştirin
  11. OCREngine parametre geçişini uygun ön işleme filtreleri ile değiştirin
  12. language parametre dizilerini OcrLanguage enum değerleri ile değiştirin
  13. Dosya boyutu ön doğrulama kontrollerini kaldırın (5 MB sınırı artık geçerli değil)
  14. async Task<string> OCR yöntemlerini senkronize string'a çevirin, çünkü HTTP tek asenkron nedendi
  15. OCR.space API anahtarını yapılandırma dosyalarından ve ortam değişkeni kurulumundan kaldırın

Geçiş Sonrası Testler

  • Metin çıkarımının, aynı test belgelerinde eşdeğer veya daha yüksek doğruluk ürettiğini doğrulayın
  • Büyük dosyaların (5 MB'dan fazla) hatasız işlendiğini onaylayın
  • OcrLanguage.English + OcrLanguage.French ile çok dilli belgeleri test edin ve iç içe geçmiş çıktıyı doğrulayın
  • Gerçek OCR çağrıları ile CI/CD hattını çalıştırın — herhangi bir belge hacminde hız sınırı hatası olmadığını onaylayın
  • Aranabilir PDF çıktısında filigran olmadığını doğrulayın
  • Daha önce asenkron olan denetleyici eylemlerinin senkron dönüştürmeden sonra doğru yanıt verdiğini kontrol edin
  • İzole veya ağ kısıtlamalı dağıtım ortamlarının belgeleri hatasız işlediğini test edin
  • Önceden OCREngine=2 gerektiren belgeler üzerinde result.Confidence değerlerinin kabul edilebilir olup olmadığını onaylayın
  • Yapısal belgelerdeki beklenen alan pozisyonlarına result.Pages[n].Words koordinatlarının uyduğunu doğrulayın
  • Uygulama başlangıç lisansının ilk OCR çağrısından önce başarıyla başlatıldığını test edin

IronOCR'a Geçişin Ana Faydaları

80'den fazla satır altyapı vergisi kaybolur. Her OCR.space entegrasyonu bir HTTP istemcisi, bir hız sınırlayıcı, bir JSON çözümleyici, özel istisna türleri ve özel sonuç modelleri sağlar. Bu kodların hiçbiri uygulamanın aslında ihtiyaç duyduğu bir şey yapmaz — OCR.space'in eksik SDK'sını telafi etmek için vardır. Geçiş sonrası o kod silinir. Kod tabanındaki OCR yüzey alanı, çağrı yerinde new IronTesseract().Read(path).Text ve başlangıçta bir lisans başlatma satırına azalır.

Belge işleme hızı, yerel donanımın bir fonksiyonu haline gelir. OCR.space her işlemde ağ gecikmesi, OCR.space sunucu kuyruk derinliği ve coğrafi gidiş-dönüş süresini tanıtır.IronOCR yerel işlem olarak çalışır. Bir yerel iş istasyonu, belge işleme kapatıldığında herhangi bir bulut API'sinden daha hızlı işler, ve toplu işleme seriyazdan çıkaran 60 istek/dakika sınırı olmadan. Çeşitli IronTesseract örnekleri üzerinden Parallel.ForEach ile paralel işleme, CPU çekirdekleriyle ölçeklenir — daha fazla bilgi için çok iş parçacıklı örneğe bakın.

Hassas belgeler kalıcı olarak altyapınızda kalır. Geçiş sonrası, tıbbi kayıtlar, finansal belgeler, yasal sözleşmeler ve kimlik belgeleri uygulama sunucusunu asla terk etmez. HIPAA, GDPR, SOC 2 uyum incelemeleri ve dahili veri sınıflandırma politikaları artık OCR.space'in veri işleme uygulamalarını kapsamlarına dahil etmek zorunda değildir. Denetim yüzeyi, kendi altyapınıza küçülür. Docker dağıtım rehberi ve Azure dağıtım rehberi, veri ikamet uyumluluğu gerektiren konteynerleştirilmiş ve bulut ortamlarda IronOCR'un dağıtımını kapsamaktadır.

Yapılandırılmış çıktı, belge zekası uygulamalarını mümkün kılar. OCR.space'nin ParsedText dizesi belge analizinin son noktasıdır. IronOCR'un result.Pages, result.Words ve result.Lines koordinatları ve kelime başına güven puanları, uygulamaların belirli alanları bulmasını, çıkarım kalitesini doğrulamasını, tablo verilerini çıkarmasını ve sonraki belge zeka hatları oluşturmasını sağlar. OCR.space'in düz metin çıktısının üzerinde özel yerleşim analizleri gerektiren özellikler, doğrudan API çağrılarına dönüşür. Tablo çıkarma rehberi ve taralı belge işleme rehberi, bu yapılandırılmış temel ile ne yapılabileceğini gösterir.

Maliyet her hacimde sabit ve öngörülebilir hale gelir. OCR.space'in ücretsiz katmanı ayda 25.000 isteği kapsar. Bunun üzerinde abone maliyetleri kullanımla ölçeklenir. IronOCR'un $999 Lite süresiz lisansı, herhangi bir hacimde belge başına ücret taşımaz. Ayda 100.000 belge işleyen bir ekip, ayda 1.000 belge işleyen bir ekip ile aynı lisans ücretini öder. Belge işleme uygulamaları için bütçe tahminleri, iş başarısı ile büyüyen değişken bir kalem yerine sabit yıllık bir maliyet haline gelir. IronOCR ürün sayfası, ekiplerin satın almadan önce belirli belge türleri üzerindeki doğruluğu doğrulamalarına olanak tanıyan bir ücretsiz deneme sürümü içerir.

Lütfen dikkate alınOCR.space ve Tesseract, ilgili sahiplerinin tescilli ticari markalarıdır. Bu site, Google veya OCR.space ile ilişkili, onaylanmış veya sponsorlu değildir. Tüm ürün adları, logolar ve markalar kendi sahiplerine aittir. Karşılaştırmalar, yalnızca bilgilendirme amaçlıdır ve yazı sırasında halka açık bilgilerle alakalı olarak yansıtılmaktadır.

Sıkça Sorulan Sorular

OCR.space API'dan IronOCR'ye neden geçmeliyim?

Yaygın geçiş nedenleri arasında COM ara bağlamının karmaşıklığını ortadan kaldırmak, dosya tabanlı lisans yönetimini değiştirmek, sayfa başına fatura düzenlemekten kaçınmak, Docker/kapsayıcı dağıtımını etkinleştirmek ve standart .NET araçlarıyla entegre olan bir NuGet doğal iş akışı benimsemek yer almaktadır.

OCR.space API'dan IronOCR'ye geçişteki ana kod değişiklikleri nelerdir?

OCR.space başlangıç dizilerini IronTesseract örneği ile değiştirin, COM yaşam döngüsü yönetimini (açık Create/Load/Close desenleri) kaldırın ve sonuç özellik adlarını güncelleyin. Sonuç, önemli ölçüde daha az boilerplate satırıdır.

Geçişi başlatmak için IronOCR'u nasıl kurarım?

Paket Yöneticisi Konsolunda 'Install-Package IronOcr' veya CLI'da 'dotnet add package IronOcr' çalıştırın. Dil paketleri ayrı paketlerdir: Örneğin, Fransızca için 'dotnet add package IronOcr.Languages.French'.

IronOCR, OCR.space API'nin standart iş belgeleri için OCR doğruluğunu karşılıyor mu?

IronOCR, faturalar, sözleşmeler, makbuzlar ve yazılı formlar dahil olmak üzere standart işletme içerikleri için yüksek doğruluğa ulaşır. Görüntü ön işleme filtreleri (dengelemeyi düzeltme, gürültü kaldırma, kontrast artırma) bozulmuş girdiler üzerindeki tanımayı daha da iyileştirir.

IronOCR, OCR.space API'nin ayrı kurduğu dil verilerini nasıl yönetiyor?

IronOCR'daki dil verileri, NuGet paketleri olarak dağıtılır. 'dotnet add package IronOcr.Languages.German' komutuyla Almanca desteği yüklenir. Herhangi bir manuel dosya yerleştirme veya dizin yolu gerekmez.

OCR.space API'dan IronOCR'ye geçiş, dağıtım altyapısında değişiklik gerektiriyor mu?

IronOCR, OCR.space API'dan daha az altyapı değişikliği gerektirir. SDK ikili yolları, lisans dosyası yerleşimleri veya lisans sunucu yapılandırmaları yoktur. NuGet paketi, tam OCR motorunu içerir ve lisans anahtarı uygulama kodunda belirlenmiş bir dizgedir.

Geçişten sonra IronOCR lisanslamasını nasıl yapılandırırım?

Uygulama başlangıç ​​kodunda IronOcr.License.LicenseKey = "SİZİN-ANAHTARINIZ" atayın. Docker veya Kubernetes'te, anahtarı bir ortam değişkeni olarak saklayın ve başlangıçta okuyun. Trafiği kabul etmeden önce doğrulamak için License.IsValidLicense kullanın.

IronOCR, PDF'leri OCR.space gibi işleyebilir mi?

Evet. IronOCR hem yerel hem de taranmış PDF'leri okur. Bir PDF yolu veya OcrPdfInput olan girdiye ocr.Read(input) çağrısı yapmak için IronTesseract örneği çağırın ve OcrResult sayfalarını yineleyin. Ayrı bir PDF işleme hattı gerekmez.

IronOCR, yüksek hacim işleme sırasında iş parçacığı nasıl ele alır?

IronTesseract, iş parçacığı başına örnek olacak şekilde güvenlidir. Paralel.ForEach veya Görev havuzunda her iş parçacığı için bir örnek oluşturun, OCR'u eşzamanlı olarak çalıştırın ve her örneği iş tamamlandığında bırakın. Küresel durum veya kilitleme gerekmez.

IronOCR metin çıktıktan sonra hangi çıktıları destekler?

IronOCR, metin, kelime koordinatları, güven skorları ve sayfa yapısını içeren yapılandırılmış sonuçlar döndürür. Dışa aktarma seçenekleri düz metin, aranabilir PDF ve aşağı akış işlemesi için yapılandırılmış sonuç nesneleri içerir.

IronOCR'ın fiyatlandırması, ölçeklendirme iş yükleri için OCR.space API'dan daha öngörülebilir mi?

IronOCR, sayfa başına veya hacim ücretlendirmesi olmadan düz oranlı sürekli lisanslama kullanır. 10.000 veya 10 milyon sayfa işleseniz de lisans maliyeti sabit kalır. Hacim ve ekip lisanslama seçenekleri IronOCR fiyatlandırma sayfasındadır.

OCR.space API'dan IronOCR'ye geçtikten sonra mevcut testlerime ne olacak?

Çıkarılmış metin içeriğini doğrulayan testler, geçişten sonra çalışmaya devam etmelidir. API çağrı şablonlarını veya COM nesne yaşam döngüsünü doğrulayan testler, IronOCR'un daha basit başlatma ve sonuç modelini yansıtacak şekilde güncellenmelidir.

Curtis Chau
Teknik Yazar

Curtis Chau, Bilgisayar Bilimleri alanında Lisans Derecesine (Carleton Üniversitesi) sahip ve Node.js, TypeScript, JavaScript ve React konularında uzmanlaşmış ön uç geliştirmeyle ilgileniyor. Sezgisel ve estetik açıdan hoş kullanıcı arayüzleri oluşturma tutkunu, Curtis modern çerçevelerle çalışmayı ve iyi yapı...

Daha Fazla Oku

Iron Destek Ekibi

Haftada 5 gün, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara