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
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)
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
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"
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
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
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
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
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
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
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
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
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
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
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
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")
İ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
Çö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
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" .
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
IronOcrNuGet paketini yükleyin:dotnet add package IronOcr- Uygulama başlangıcına
IronOcr.License.LicenseKey = "..."ekleyin OcrSpaceApiClientsınıfını ve tüm destek altyapısını silin- Özel
OcrResultPOCO'yu silin (IronOcr.OcrResultile değiştirildi) - Özel
OcrSpaceExceptionsınıfını silin (standart .NET istisnaları ile değiştirildi) SemaphoreSlimoran sınırlayıcıyı ve ilişkili Task.Delay mantığını silin- 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ıOcrInputile değiştirin _httpClient.PostAsync(...)çağrılarınınew IronTesseract().Read(input)ile değiştirinJsonDocument,ParsedResults[0].ParsedText'nın saf dışı analizi ileresult.Textile değiştirinTextOverlayJSON koordinat analiziniresult.Pages[n].Wordsile değiştirinOCREngineparametre geçişini uygun ön işleme filtreleri ile değiştirinlanguageparametre dizileriniOcrLanguageenum değerleri ile değiştirin- Dosya boyutu ön doğrulama kontrollerini kaldırın (5 MB sınırı artık geçerli değil)
async Task<string>OCR yöntemlerini senkronizestring'a çevirin, çünkü HTTP tek asenkron nedendi- 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.Frenchile ç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=2gerektiren belgeler üzerinderesult.Confidencedeğerlerinin kabul edilebilir olup olmadığını onaylayın - Yapısal belgelerdeki beklenen alan pozisyonlarına
result.Pages[n].Wordskoordinatları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.
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.

