Altbilgi içeriğine atla
DIğER BILEşENLERLE KARşıLAşTıRıN

ABBYY FineReader vs Tesseract: OCR Karşılaştırması

OCR.space'in NuGet paketi yok. Bu tek gerçek, bir .NET geliştiricisinin onu seçerken yaptığı her entegrasyon kararını tanımlar: kendi özel HttpClient kodunuzu yazarsınız, belgelerinizi base64 kodlar, https://api.ocr.space/parse/image POST edersiniz, JSON yanıtını elle işler, HTTP 429'larını yakalarsınız, üstel geri alma uygularsınız, oran sınırlayıcı defter tutucusu oluşturur ve uygulamanıza bir metin karakteri gelmeden önce kendi özel hata türlerinizi belirlersiniz. Bu makale, bu DIY yükün kod, zaman ve üretim güvenilirliğinde ne maliyeti olduğunu incelemekte ve bunu, tek bir NuGet paketi olarak teslim edilen IronOCR ile doğrudan karşılaştırmaktadır.

OCR.space Anlama

OCR.space, OCR.space tarafından işletilen uzak sunucular üzerinde görüntü ve PDF işleyen freemium bir REST API'dir. Hizmet, kredi kartı gerektirmeyen aylık 25.000 talebi içeren ücretsiz katman etrafında konumlanıyor, bu da OCR ile denemeler yapan geliştiricilere veya kişisel projelerini geliştirenlere hitap ediyor. NuGet paketi yok, resmi .NET SDK yok ve herhangi bir dilde güçlü bir şekilde uyarlanmış istemci kütüphanesi yok. Her .NET entegrasyonu el yapımıdır ve HttpClient üzerine inşa edilmiştir.

.NET geliştiricileri için mimari gerçeklik:

  • NuGet paketi yok: İlk sınıf .NET desteği sıfır. IntelliSense yok, uyarlanmış modeller yok, entegre hata işleme yok.
  • Sadece bulutta işleme: Her belge altyapınızı terk eder. Yerinde (on-premise) bir seçenek ve kendi barındırılan dağıtım yolu yok.
  • Manuel REST entegrasyonu: Geliştiriciler dosyaları base64'e kodlar, FormUrlEncodedContent veya MultipartFormDataContent oluşturur ve ham JSON yanıtlarını işler.
  • DIY hız sınır yapısı: Ücretsiz katman, IP başına dakikada 60 istek ve günlük 500 istek zorlar. Üretim uygulamaları bu mantığı kendileri inşa etmelidir.
  • Dosya boyutu sınırlamaları: Ücretsiz katman, 5 MB üzeri dosyaları reddeder. Çok sayfalı PDF'ler genellikle bu limiti aşar.
  • Ücretsiz katmanda düz PDF çıktısı: Ücretsiz katmandaki aranabilir PDF oluşturma, OCR.space filigranlarını yerleştirir, çıktının müşteri teslimatı veya belge arşivleme için kullanılmaz hale getirir.
  • SLA yok: Ücretsiz katman, çalışma zamanı taahhüdü taşımaz. Ücretli planlar daha yüksek sınırlar sunar, ancak aynı mimari kısıtlamalara sahiptir.

REST Entegrasyonu Geliştiriciler Yazmalıdır

OCR.space'in belgeleri, geliştiricileri REST uç noktasına yönlendirir ve diğer her şeyi inşa etmeleri için bırakır. Minimum sürdürülebilir .NET istemcisi — üretim sertleştirmesi düşüncesi öncesinde — böyle görünür:

// OCR.space: what you build before the first line of your actual application
public class OcrSpaceApiClient : IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;
    private readonly SemaphoreSlim _rateLimiter;
    private const string ApiEndpoint = "https://api.ocr.space/parse/image";
    private const int MaxFileSizeFree = 5 * 1024 * 1024; // 5MB — hard limit on free tier
    private const int RateLimitPerMinute = 60;

    public OcrSpaceApiClient(string apiKey)
    {
        _apiKey = apiKey ?? throw new ArgumentNullException(nameof(apiKey));
        _httpClient = new HttpClient();
        _httpClient.Timeout = TimeSpan.FromSeconds(120);
        _rateLimiter = new SemaphoreSlim(RateLimitPerMinute, RateLimitPerMinute);
    }

    public async Task<OcrResult> ExtractTextFromFileAsync(
        string filePath,
        string language = "eng",
        CancellationToken cancellationToken = default)
    {
        if (!File.Exists(filePath))
            throw new FileNotFoundException("Image file not found", filePath);

        var fileInfo = new FileInfo(filePath);
        if (fileInfo.Length > MaxFileSizeFree)
        {
            throw new InvalidOperationException(
                $"File size {fileInfo.Length / 1024 / 1024}MB exceeds free tier limit of 5MB.");
        }

        await _rateLimiter.WaitAsync(cancellationToken);

        try
        {
            // Document leaves your infrastructure here
            byte[] imageBytes = await File.ReadAllBytesAsync(filePath, cancellationToken);
            string base64Image = Convert.ToBase64String(imageBytes);
            string mimeType = GetMimeType(filePath);

            var formContent = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("apikey", _apiKey),
                new KeyValuePair<string, string>("base64Image", $"data:{mimeType};base64,{base64Image}"),
                new KeyValuePair<string, string>("language", language),
                new KeyValuePair<string, string>("isOverlayRequired", "false"),
                new KeyValuePair<string, string>("filetype", Path.GetExtension(filePath).TrimStart('.')),
                new KeyValuePair<string, string>("detectOrientation", "true"),
                new KeyValuePair<string, string>("scale", "true"),
                new KeyValuePair<string, string>("OCREngine", "2")
            });

            var response = await _httpClient.PostAsync(ApiEndpoint, formContent, cancellationToken);

            if (!response.IsSuccessStatusCode)
            {
                string errorBody = await response.Content.ReadAsStringAsync(cancellationToken);
                throw new OcrSpaceException(
                    $"OCR.space API returned {response.StatusCode}: {errorBody}",
                    (int)response.StatusCode);
            }

            string jsonResponse = await response.Content.ReadAsStringAsync(cancellationToken);
            return ParseOcrResponse(jsonResponse);
        }
        finally
        {
            _ = Task.Run(async () =>
            {
                await Task.Delay(60000 / RateLimitPerMinute);
                _rateLimiter.Release();
            });
        }
    }

    private OcrResult ParseOcrResponse(string jsonResponse)
    {
        using var doc = JsonDocument.Parse(jsonResponse);
        var root = doc.RootElement;

        if (root.TryGetProperty("IsErroredOnProcessing", out var isErrored) && isErrored.GetBoolean())
        {
            string errorMessage = "OCR processing failed";
            if (root.TryGetProperty("ErrorMessage", out var errorMessages))
            {
                // Parse the array of error strings manually
                var messages = new List<string>();
                if (errorMessages.ValueKind == JsonValueKind.Array)
                {
                    foreach (var msg in errorMessages.EnumerateArray())
                        messages.Add(msg.GetString() ?? "Unknown error");
                }
                errorMessage = string.Join("; ", messages);
            }
            throw new OcrSpaceException(errorMessage, 500);
        }

        var result = new OcrResult();

        if (root.TryGetProperty("ParsedResults", out var parsedResults))
        {
            foreach (var parsedResult in parsedResults.EnumerateArray())
            {
                if (parsedResult.TryGetProperty("ParsedText", out var parsedText))
                    result.ParsedText += parsedText.GetString();

                if (parsedResult.TryGetProperty("FileParseExitCode", out var exitCode))
                    result.ExitCodes.Add(exitCode.GetInt32());
            }
        }

        return result;
    }

    private string GetMimeType(string filePath) =>
        Path.GetExtension(filePath).ToLowerInvariant() switch
        {
            ".png"          => "image/png",
            ".jpg" or ".jpeg" => "image/jpeg",
            ".bmp"          => "image/bmp",
            ".tiff" or ".tif" => "image/tiff",
            ".pdf"          => "application/pdf",
            _               => "application/octet-stream"
        };

    public void Dispose()
    {
        _httpClient?.Dispose();
        _rateLimiter?.Dispose();
    }
}

// Custom models — no SDK means you define these yourself
public class OcrResult
{
    public string ParsedText { get; set; } = string.Empty;
    public List<string> Warnings { get; } = new();
    public List<int> ExitCodes { get; } = new();
}

public class OcrSpaceException : Exception
{
    public int StatusCode { get; }
    public OcrSpaceException(string message, int statusCode) : base(message)
        => StatusCode = statusCode;
}
// OCR.space: what you build before the first line of your actual application
public class OcrSpaceApiClient : IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;
    private readonly SemaphoreSlim _rateLimiter;
    private const string ApiEndpoint = "https://api.ocr.space/parse/image";
    private const int MaxFileSizeFree = 5 * 1024 * 1024; // 5MB — hard limit on free tier
    private const int RateLimitPerMinute = 60;

    public OcrSpaceApiClient(string apiKey)
    {
        _apiKey = apiKey ?? throw new ArgumentNullException(nameof(apiKey));
        _httpClient = new HttpClient();
        _httpClient.Timeout = TimeSpan.FromSeconds(120);
        _rateLimiter = new SemaphoreSlim(RateLimitPerMinute, RateLimitPerMinute);
    }

    public async Task<OcrResult> ExtractTextFromFileAsync(
        string filePath,
        string language = "eng",
        CancellationToken cancellationToken = default)
    {
        if (!File.Exists(filePath))
            throw new FileNotFoundException("Image file not found", filePath);

        var fileInfo = new FileInfo(filePath);
        if (fileInfo.Length > MaxFileSizeFree)
        {
            throw new InvalidOperationException(
                $"File size {fileInfo.Length / 1024 / 1024}MB exceeds free tier limit of 5MB.");
        }

        await _rateLimiter.WaitAsync(cancellationToken);

        try
        {
            // Document leaves your infrastructure here
            byte[] imageBytes = await File.ReadAllBytesAsync(filePath, cancellationToken);
            string base64Image = Convert.ToBase64String(imageBytes);
            string mimeType = GetMimeType(filePath);

            var formContent = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("apikey", _apiKey),
                new KeyValuePair<string, string>("base64Image", $"data:{mimeType};base64,{base64Image}"),
                new KeyValuePair<string, string>("language", language),
                new KeyValuePair<string, string>("isOverlayRequired", "false"),
                new KeyValuePair<string, string>("filetype", Path.GetExtension(filePath).TrimStart('.')),
                new KeyValuePair<string, string>("detectOrientation", "true"),
                new KeyValuePair<string, string>("scale", "true"),
                new KeyValuePair<string, string>("OCREngine", "2")
            });

            var response = await _httpClient.PostAsync(ApiEndpoint, formContent, cancellationToken);

            if (!response.IsSuccessStatusCode)
            {
                string errorBody = await response.Content.ReadAsStringAsync(cancellationToken);
                throw new OcrSpaceException(
                    $"OCR.space API returned {response.StatusCode}: {errorBody}",
                    (int)response.StatusCode);
            }

            string jsonResponse = await response.Content.ReadAsStringAsync(cancellationToken);
            return ParseOcrResponse(jsonResponse);
        }
        finally
        {
            _ = Task.Run(async () =>
            {
                await Task.Delay(60000 / RateLimitPerMinute);
                _rateLimiter.Release();
            });
        }
    }

    private OcrResult ParseOcrResponse(string jsonResponse)
    {
        using var doc = JsonDocument.Parse(jsonResponse);
        var root = doc.RootElement;

        if (root.TryGetProperty("IsErroredOnProcessing", out var isErrored) && isErrored.GetBoolean())
        {
            string errorMessage = "OCR processing failed";
            if (root.TryGetProperty("ErrorMessage", out var errorMessages))
            {
                // Parse the array of error strings manually
                var messages = new List<string>();
                if (errorMessages.ValueKind == JsonValueKind.Array)
                {
                    foreach (var msg in errorMessages.EnumerateArray())
                        messages.Add(msg.GetString() ?? "Unknown error");
                }
                errorMessage = string.Join("; ", messages);
            }
            throw new OcrSpaceException(errorMessage, 500);
        }

        var result = new OcrResult();

        if (root.TryGetProperty("ParsedResults", out var parsedResults))
        {
            foreach (var parsedResult in parsedResults.EnumerateArray())
            {
                if (parsedResult.TryGetProperty("ParsedText", out var parsedText))
                    result.ParsedText += parsedText.GetString();

                if (parsedResult.TryGetProperty("FileParseExitCode", out var exitCode))
                    result.ExitCodes.Add(exitCode.GetInt32());
            }
        }

        return result;
    }

    private string GetMimeType(string filePath) =>
        Path.GetExtension(filePath).ToLowerInvariant() switch
        {
            ".png"          => "image/png",
            ".jpg" or ".jpeg" => "image/jpeg",
            ".bmp"          => "image/bmp",
            ".tiff" or ".tif" => "image/tiff",
            ".pdf"          => "application/pdf",
            _               => "application/octet-stream"
        };

    public void Dispose()
    {
        _httpClient?.Dispose();
        _rateLimiter?.Dispose();
    }
}

// Custom models — no SDK means you define these yourself
public class OcrResult
{
    public string ParsedText { get; set; } = string.Empty;
    public List<string> Warnings { get; } = new();
    public List<int> ExitCodes { get; } = new();
}

public class OcrSpaceException : Exception
{
    public int StatusCode { get; }
    public OcrSpaceException(string message, int statusCode) : base(message)
        => StatusCode = statusCode;
}
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading
Imports System.Threading.Tasks

' OCR.space: what you build before the first line of your actual application
Public Class OcrSpaceApiClient
    Implements IDisposable

    Private ReadOnly _httpClient As HttpClient
    Private ReadOnly _apiKey As String
    Private ReadOnly _rateLimiter As SemaphoreSlim
    Private Const ApiEndpoint As String = "https://api.ocr.space/parse/image"
    Private Const MaxFileSizeFree As Integer = 5 * 1024 * 1024 ' 5MB — hard limit on free tier
    Private Const RateLimitPerMinute As Integer = 60

    Public Sub New(apiKey As String)
        _apiKey = If(apiKey, Throw New ArgumentNullException(NameOf(apiKey)))
        _httpClient = New HttpClient()
        _httpClient.Timeout = TimeSpan.FromSeconds(120)
        _rateLimiter = New SemaphoreSlim(RateLimitPerMinute, RateLimitPerMinute)
    End Sub

    Public Async Function ExtractTextFromFileAsync(filePath As String, Optional language As String = "eng", Optional cancellationToken As CancellationToken = Nothing) As Task(Of OcrResult)
        If Not File.Exists(filePath) Then
            Throw New FileNotFoundException("Image file not found", filePath)
        End If

        Dim fileInfo = New FileInfo(filePath)
        If fileInfo.Length > MaxFileSizeFree Then
            Throw New InvalidOperationException($"File size {fileInfo.Length \ 1024 \ 1024}MB exceeds free tier limit of 5MB.")
        End If

        Await _rateLimiter.WaitAsync(cancellationToken)

        Try
            ' Document leaves your infrastructure here
            Dim imageBytes As Byte() = Await File.ReadAllBytesAsync(filePath, cancellationToken)
            Dim base64Image As String = Convert.ToBase64String(imageBytes)
            Dim mimeType As String = GetMimeType(filePath)

            Dim formContent = New FormUrlEncodedContent(New KeyValuePair(Of String, String)() {
                New KeyValuePair(Of String, String)("apikey", _apiKey),
                New KeyValuePair(Of String, String)("base64Image", $"data:{mimeType};base64,{base64Image}"),
                New KeyValuePair(Of String, String)("language", language),
                New KeyValuePair(Of String, String)("isOverlayRequired", "false"),
                New KeyValuePair(Of String, String)("filetype", Path.GetExtension(filePath).TrimStart("."c)),
                New KeyValuePair(Of String, String)("detectOrientation", "true"),
                New KeyValuePair(Of String, String)("scale", "true"),
                New KeyValuePair(Of String, String)("OCREngine", "2")
            })

            Dim response = Await _httpClient.PostAsync(ApiEndpoint, formContent, cancellationToken)

            If Not response.IsSuccessStatusCode Then
                Dim errorBody = Await response.Content.ReadAsStringAsync(cancellationToken)
                Throw New OcrSpaceException($"OCR.space API returned {response.StatusCode}: {errorBody}", CInt(response.StatusCode))
            End If

            Dim jsonResponse = Await response.Content.ReadAsStringAsync(cancellationToken)
            Return ParseOcrResponse(jsonResponse)
        Finally
            _ = Task.Run(Async Function()
                             Await Task.Delay(60000 \ RateLimitPerMinute)
                             _rateLimiter.Release()
                         End Function)
        End Try
    End Function

    Private Function ParseOcrResponse(jsonResponse As String) As OcrResult
        Using doc = JsonDocument.Parse(jsonResponse)
            Dim root = doc.RootElement

            If root.TryGetProperty("IsErroredOnProcessing", ByRef isErrored) AndAlso isErrored.GetBoolean() Then
                Dim errorMessage As String = "OCR processing failed"
                If root.TryGetProperty("ErrorMessage", ByRef errorMessages) Then
                    ' Parse the array of error strings manually
                    Dim messages = New List(Of String)()
                    If errorMessages.ValueKind = JsonValueKind.Array Then
                        For Each msg In errorMessages.EnumerateArray()
                            messages.Add(msg.GetString() OrElse "Unknown error")
                        Next
                    End If
                    errorMessage = String.Join("; ", messages)
                End If
                Throw New OcrSpaceException(errorMessage, 500)
            End If

            Dim result = New OcrResult()

            If root.TryGetProperty("ParsedResults", ByRef parsedResults) Then
                For Each parsedResult In parsedResults.EnumerateArray()
                    If parsedResult.TryGetProperty("ParsedText", ByRef parsedText) Then
                        result.ParsedText &= parsedText.GetString()
                    End If

                    If parsedResult.TryGetProperty("FileParseExitCode", ByRef exitCode) Then
                        result.ExitCodes.Add(exitCode.GetInt32())
                    End If
                Next
            End If

            Return result
        End Using
    End Function

    Private Function GetMimeType(filePath As String) As String
        Return Path.GetExtension(filePath).ToLowerInvariant() Select Case
            Case ".png" : Return "image/png"
            Case ".jpg", ".jpeg" : Return "image/jpeg"
            Case ".bmp" : Return "image/bmp"
            Case ".tiff", ".tif" : Return "image/tiff"
            Case ".pdf" : Return "application/pdf"
            Case Else : Return "application/octet-stream"
        End Select
    End Function

    Public Sub Dispose() Implements IDisposable.Dispose
        _httpClient?.Dispose()
        _rateLimiter?.Dispose()
    End Sub
End Class

' Custom models — no SDK means you define these yourself
Public Class OcrResult
    Public Property ParsedText As String = String.Empty
    Public ReadOnly Property Warnings As New List(Of String)()
    Public ReadOnly Property ExitCodes As New List(Of Integer)()
End Class

Public Class OcrSpaceException
    Inherits Exception

    Public ReadOnly Property StatusCode As Integer

    Public Sub New(message As String, statusCode As Integer)
        MyBase.New(message)
        Me.StatusCode = statusCode
    End Sub
End Class
$vbLabelText   $csharpLabel

Bu, ilk iş mantığı yönteminden önce var olan 90+ satır altyapı kodudur. Her OCR.space entegrasyonu bu şablonu (veya eşdeğer bir şeyi) gönderir ve bunu yazan her ekip aynı sorunu çözüyor, OCR.space onların adına çözmemeyi seçmiştir.

IronOCR'u Anlamak

IronOCR, .NET için ticari bir OCR kütüphanesidir ve IronOcr NuGet paketi aracılığıyla yüklenir. Bu, otomatik ön işleme, yerel PDF girişi, aranabilir PDF çıkışı, 125+ dil paketi ve yapılandırılmış sonuç çıkarımı ile optimize edilmiş bir Tesseract 5 motorunu kapsar — hepsi bulut bağımlılığı, API anahtarları veya istek başına ücretler olmadan. Belgeler, .NET uygulamasını çalıştıran herhangi bir altyapı üzerinde yerel olarak işlenir.

Anahtar özellikler:

  • Tek NuGet paketi: dotnet add package IronOcr tam kurulumdur. Yönetilecek yerel ikililer yok, tessdata dizinleri yok, ortam değişkenleri yok.
  • Güçlü tipte API: IronTesseract, OcrInput, OcrResult ve CropRectangle, tam IntelliSense desteğine sahip birinci sınıf .NET türleridir.
  • Otomatik ön işleme: Deskew, DeNoise, Kontrast, Binarize ve EnhanceResolution filtreleri, harici kütüphaneler olmadan otomatik olarak veya isteğe bağlı olarak uygulanır.
  • Yerel PDF desteği: Hem taranmış PDF'leri okuma hem de aranabilir PDF'ler oluşturma yerleşiktir. Kullanılabilir belleğin ötesinde boyut sınırlaması yok.
  • Yerel yürütme: OCR sırasında hiçbir ağ çağrısı gerçekleşmez. Kütüphane tamamen sürecin içinde çalışır. İzole ortamlarda yapılandırma değişiklikleri olmaksızın çalışır.
  • İş parçacığı güvenli: Birden fazla IronTesseract örneği kilitleme veya çekişme yönetimi olmadan aynı anda çalışır.
  • Süresiz lisanslama: $999 Lite / $1,499 Plus / $2,999 Professional. Herhangi bir hacimde istek başına ücret yok.

Özellik Karşılaştırması

Özellik OCR.space IronOCR
NuGet paketi Yok — REST API sadece IronOcr — tam .NET desteği
İşleme yeri OCR.space bulut sunucuları Yerel — altyapınız
Ücretsiz katman 25.000 istek/ay (sınırlı) Deneme mevcut
Ücretli fiyatlandırma Güncel fiyatlandırma için OCR.space ile iletişime geçin $2,999 bir kerelik süresiz
Hız sınırlama 60 istek/dak, 500/gün (ücretsiz) None
Çevrimdışı yetenek Hayır Evet — tamamen izole
Veri gizliliği Belgeler üçüncü tarafa gönderilir Belgeler sunucularınızda kalır

Ayrıntılı Özellik Karşılaştırması

Özellik OCR.space IronOCR
Entegrasyon
NuGet paketi None Evet (IronOcr)
Kuvvetli-tipli modeller Yok — elle JSON çözümüleme Evet (OcrResult, OcrInput)
IntelliSense desteği None Tam
Özel istisna türleri Kendiniz tanımlamalısınız Yerleşik
Yeniden deneme mantığı Kendiniz inşa etmelisiniz Yerleşik
İşleme
İşleme yeri Bulut sunucular Yerel işlem içinde
İnternet gerekli Evet — her çağrı Hayır
İzole destek Hayır Evet
Oran sınırlamaları Evet — tüm planlar None
Dosya boyutu sınırları 5 MB (ücretsiz katman) Sadece bellek
OCR Yetenekleri
Görüntü OCR Evet Evet
PDF OCR Evet (sınırlı) Evet (yerel, boyut sınırı yok)
Aranabilir PDF çıktısı Ücretsiz katmanda filigranlı Temiz çıktı, filigran yok
Otomatik ön işlem Yok (sadece sunucu tarafı) Deskew, DeNoise, Contrast, Binarize, EnhanceResolution
Elle ön işleme kontrolü None Tam filtre API'si
Dil desteği ~25 dil 125+ NuGet dil paketleri aracılığıyla
Her belge için çoklu dil Sınırlı Evet — birincil + ikincil diller
Yapılandırılmış çıktı (kelimeler/satırlar/sayfalar) Yok — sadece düz metin Evet — sayfalar, paragraflar, satırlar, kelimeler koordinatlarla
Güven skoru Hayır Evet — her sonuç ve kelime başına
Bölge bazlı OCR Hayır Evet — CropRectangle
OCR sırasında barkod okuma Hayır Evet — ReadBarCodes = true
Dağıtım
Docker Dışa doğru internet gerektirir Kutudan çıkar çıkmaz çalışır
Linux Dışa doğru internet gerektirir Tam destekli
HIPAA uyumlu Risk — belgeler kontrolünüzden çıkar Evet — dışa aktarım yok
GDPR uyumlu Risk — AB veri transferi belirsiz Evet — üçüncü taraf veri işleme yok
Fiyatlandırma
Fiyatlandırma modeli Aylık abonelik Tek seferlik süresiz lisans
Giriş fiyatı Güncel fiyatlandırma için OCR.space ile iletişime geçin $999 bir kerelik
Ölçekli belge başına maliyet Evet None
SLA Yok (ücretsiz), değişir (ücretli) KurumsalSLAmevcut

SDK Derinliği vs. Ham HTTP: Entegrasyon Maliyeti

OCR.space ile yerel bir SDK arasındaki fark bir stil tercihi değildir. Geliştirme süresinde, hata alanı yüzeyinde ve her dağıtımda bakım yükünde ölçülür.

OCR.space Yaklaşımı

OCR.space'i kullanan her .NET geliştiricisi kendi HTTP istemcisini yazar. En basit olası uygulama — yeniden deneme mantığı olmadan, toplu destek olmadan ve ön işleme yapmadan — hala50+satırdır:

// OCR.space: minimum viable extraction —50+lines before business logic
public class OcrSpaceBasicExtraction
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;

    public OcrSpaceBasicExtraction(string apiKey)
    {
        _apiKey = apiKey;
        _httpClient = new HttpClient();
    }

    public async Task<string> ExtractText(string imagePath)
    {
        // Read file and encode — document leaves your infrastructure
        byte[] imageBytes = File.ReadAllBytes(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", "eng")
        });

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

        if (!response.IsSuccessStatusCode)
            throw new Exception($"API error: {response.StatusCode}");

        // Parse JSON manually — no typed models
        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: minimum viable extraction —50+lines before business logic
public class OcrSpaceBasicExtraction
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;

    public OcrSpaceBasicExtraction(string apiKey)
    {
        _apiKey = apiKey;
        _httpClient = new HttpClient();
    }

    public async Task<string> ExtractText(string imagePath)
    {
        // Read file and encode — document leaves your infrastructure
        byte[] imageBytes = File.ReadAllBytes(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", "eng")
        });

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

        if (!response.IsSuccessStatusCode)
            throw new Exception($"API error: {response.StatusCode}");

        // Parse JSON manually — no typed models
        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.Net.Http
Imports System.IO
Imports System.Threading.Tasks
Imports System.Text.Json

Public Class OcrSpaceBasicExtraction
    Private ReadOnly _httpClient As HttpClient
    Private ReadOnly _apiKey As String

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

    Public Async Function ExtractText(imagePath As String) As Task(Of String)
        ' Read file and encode — document leaves your infrastructure
        Dim imageBytes As Byte() = File.ReadAllBytes(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", "eng")
        })

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

        If Not response.IsSuccessStatusCode Then
            Throw New Exception($"API error: {response.StatusCode}")
        End If

        ' Parse JSON manually — no typed models
        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

Toplu işlem ekleyin ve satır sayısı, çünkü her toplu istek hız sınırı daraltması, yeniden deneme mantığı üssel geri adımla ve HTTP 429 yanıtlarına açıkça düzenleme gerektirir. PDF işlemi ekleyin ve her çağrıdan önce 5 MB dosya boyutu kontrolü eklemeniz gerektiği için satır sayısı, çünkü ücretsiz katman, daha büyük dosyaları bir uyarı yerine bir hatayla reddedecektir.

IronOCR Yaklaşımı

IronOCR'yi NuGet'ten yüklemek, var olan yöntem çağrıları ile tüm bu altyapı kodunu değiştirir:

// IronOCR: complete implementation
var result = new IronTesseract().Read("invoice.png");
Console.WriteLine(result.Text);
// IronOCR: complete implementation
var result = new IronTesseract().Read("invoice.png");
Console.WriteLine(result.Text);
$vbLabelText   $csharpLabel

IronTesseract sınıfı, dosya okuma, ön işleme, motor çalıştırma ve sonuç yapımı işlemlerini yönetir. Hiçbir HTTP istemcisi yok. Base64 kodlama yok. JSON çözümleme yok. API anahtarı yok. Hız sınırlandırıcı yok. Giriş varyasyonlarını kapsayan görüntülerden metin okuma eğitimi, - dosya yolları, bayt dizileri, akışlar, bit eşlemeler - aynı tek çağrı desenini takip eder.

Kaynak dosyalardaki kod karmaşıklığı sayıları varsayımsal değildir:

Senaryo OCR.space Satırları IronOCR Satırları
Temel çıkarım 50+ 3
PDF işlemi 60+ 12
Toplu işlem 80+ 15
Hata işleme 70+ 15
Tam istemci altyapısı 200+ 0 (NuGet sağlar)

Toplu İşleme ve Hız Sınırları

Hız sınırı sorunu, OCR.space'in ücretsiz katmanının gerçek üretim koşulları altında açıkça bozulduğu yerdir.

OCR.space Yaklaşımı

OCR.space altında yığın işleme, 60 istek-dakika başı kısıtlaması içinde kalmak için bir SemaphoreSlim oluşturmayı ve yönetmeyi gerektirir, artı semafor mantığı hassas olmadığında veya paylaşılan altyapı bir IP adresi paylaştığında gönderilen HTTP 429 yanıtları için üstel geri alma deneme mantığı eklenmelidir:

// OCR.space batch:80+lines of rate-limit plumbing before actual work
public class OcrSpaceBatchProcessing
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;
    private readonly SemaphoreSlim _rateLimiter;

    public OcrSpaceBatchProcessing(string apiKey)
    {
        _apiKey = apiKey;
        _httpClient = new HttpClient();
        _rateLimiter = new SemaphoreSlim(60, 60); // Free tier: 60/minute
    }

    public async Task<Dictionary<string, string>> ProcessBatch(string[] imagePaths)
    {
        var results = new Dictionary<string, string>();

        foreach (var imagePath in imagePaths)
        {
            await _rateLimiter.WaitAsync();

            try
            {
                string text = await ProcessWithRetry(imagePath);
                results[imagePath] = text;
            }
            finally
            {
                _ = Task.Run(async () =>
                {
                    await Task.Delay(1000); // 1 second spacing
                    _rateLimiter.Release();
                });
            }
        }

        return results;
    }

    private async Task<string> ProcessWithRetry(string imagePath, int maxRetries = 3)
    {
        for (int attempt = 0; attempt < maxRetries; attempt++)
        {
            try
            {
                byte[] imageBytes = File.ReadAllBytes(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", "eng")
                });

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

                if (response.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
                {
                    // Rate limited — exponential backoff
                    await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
                    continue;
                }

                response.EnsureSuccessStatusCode();

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

                return doc.RootElement
                    .GetProperty("ParsedResults")[0]
                    .GetProperty("ParsedText")
                    .GetString() ?? string.Empty;
            }
            catch (HttpRequestException) when (attempt < maxRetries - 1)
            {
                await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
            }
        }

        throw new Exception($"Failed to process {imagePath} after {maxRetries} attempts");
    }
}
// OCR.space batch:80+lines of rate-limit plumbing before actual work
public class OcrSpaceBatchProcessing
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;
    private readonly SemaphoreSlim _rateLimiter;

    public OcrSpaceBatchProcessing(string apiKey)
    {
        _apiKey = apiKey;
        _httpClient = new HttpClient();
        _rateLimiter = new SemaphoreSlim(60, 60); // Free tier: 60/minute
    }

    public async Task<Dictionary<string, string>> ProcessBatch(string[] imagePaths)
    {
        var results = new Dictionary<string, string>();

        foreach (var imagePath in imagePaths)
        {
            await _rateLimiter.WaitAsync();

            try
            {
                string text = await ProcessWithRetry(imagePath);
                results[imagePath] = text;
            }
            finally
            {
                _ = Task.Run(async () =>
                {
                    await Task.Delay(1000); // 1 second spacing
                    _rateLimiter.Release();
                });
            }
        }

        return results;
    }

    private async Task<string> ProcessWithRetry(string imagePath, int maxRetries = 3)
    {
        for (int attempt = 0; attempt < maxRetries; attempt++)
        {
            try
            {
                byte[] imageBytes = File.ReadAllBytes(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", "eng")
                });

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

                if (response.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
                {
                    // Rate limited — exponential backoff
                    await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
                    continue;
                }

                response.EnsureSuccessStatusCode();

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

                return doc.RootElement
                    .GetProperty("ParsedResults")[0]
                    .GetProperty("ParsedText")
                    .GetString() ?? string.Empty;
            }
            catch (HttpRequestException) when (attempt < maxRetries - 1)
            {
                await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
            }
        }

        throw new Exception($"Failed to process {imagePath} after {maxRetries} attempts");
    }
}
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading
Imports System.Threading.Tasks

Public Class OcrSpaceBatchProcessing
    Private ReadOnly _httpClient As HttpClient
    Private ReadOnly _apiKey As String
    Private ReadOnly _rateLimiter As SemaphoreSlim

    Public Sub New(apiKey As String)
        _apiKey = apiKey
        _httpClient = New HttpClient()
        _rateLimiter = New SemaphoreSlim(60, 60) ' Free tier: 60/minute
    End Sub

    Public Async Function ProcessBatch(imagePaths As String()) As Task(Of Dictionary(Of String, String))
        Dim results As New Dictionary(Of String, String)()

        For Each imagePath In imagePaths
            Await _rateLimiter.WaitAsync()

            Try
                Dim text As String = Await ProcessWithRetry(imagePath)
                results(imagePath) = text
            Finally
                _ = Task.Run(Async Function()
                                 Await Task.Delay(1000) ' 1 second spacing
                                 _rateLimiter.Release()
                             End Function)
            End Try
        Next

        Return results
    End Function

    Private Async Function ProcessWithRetry(imagePath As String, Optional maxRetries As Integer = 3) As Task(Of String)
        For attempt As Integer = 0 To maxRetries - 1
            Try
                Dim imageBytes As Byte() = File.ReadAllBytes(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", "eng")
                })

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

                If response.StatusCode = System.Net.HttpStatusCode.TooManyRequests Then
                    ' Rate limited — exponential backoff
                    Await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)))
                    Continue For
                End If

                response.EnsureSuccessStatusCode()

                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
            Catch ex As HttpRequestException When attempt < maxRetries - 1
                Await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)))
            End Try
        Next

        Throw New Exception($"Failed to process {imagePath} after {maxRetries} attempts")
    End Function
End Class
$vbLabelText   $csharpLabel

Ücretsiz katmandaki 500 günlük isteği daha fazla sınırlar. Tek bir günde 600 belge işleyen bir uygulama, ertesi takvim günü otomatik devir olmaksızın yarı yolda başarısız olacak.

IronOCR Yaklaşımı

IronOCR'de hız sınırları yoktur. Toplu işlem bir döngüdür:

//IronOCR batch: 8 lines, no rate limits, no retries needed
public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
    var results = new Dictionary<string, string>();
    var ocr = new IronTesseract();

    foreach (var imagePath in imagePaths)
    {
        //Hayırrate limits, no retries, no cloud dependency
        var result = ocr.Read(imagePath);
        results[imagePath] = result.Text;
    }

    return results;
}
//IronOCR batch: 8 lines, no rate limits, no retries needed
public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
    var results = new Dictionary<string, string>();
    var ocr = new IronTesseract();

    foreach (var imagePath in imagePaths)
    {
        //Hayırrate limits, no retries, no cloud dependency
        var result = ocr.Read(imagePath);
        results[imagePath] = result.Text;
    }

    return results;
}
Imports System.Collections.Generic

Public Function ProcessBatch(imagePaths As String()) As Dictionary(Of String, String)
    Dim results As New Dictionary(Of String, String)()
    Dim ocr As New IronTesseract()

    For Each imagePath As String In imagePaths
        Dim result = ocr.Read(imagePath)
        results(imagePath) = result.Text
    Next

    Return results
End Function
$vbLabelText   $csharpLabel

Yığın boyunca IronTesseract örneğini yeniden kullanmak, tekrar eden motor başlatma maliyetinden kaçınır. İşleme hızı uzak bir API'nin kısıtlama politikası ile değil, yerel CPU ve disk I/O ile sınırlıdır. Çok iş parçacıklı örnek, yığın söz konusu olduğunda çekirdekler arasında paralel nasıl çalışılacağını gösterir.

PDF İşleme

PDF desteği ikinci ana yapısal boşluğu illüstre eder.

OCR.space Yaklaşımı

OCR.space, ücretli planlarda ve kısmen ücretsiz katmanda PDF yüklemeleri kabul eder, ancak ücretsiz hesaplarda 5 MB dosya boyutu tavanı çoğu çok sayfalı belgeyi dışlar. Ücretsiz katmanla aranabilir PDF çıkışı filigran içerir. Uygulama, her talep öncesinde sayfa başına sonuç çıkışını ve açık dosya boyutu kontrolü gerektirir:

// OCR.space PDF: size check required, watermarks on free tier
public async Task<List<string>> ExtractTextFromPdf(string pdfPath)
{
    var pageTexts = new List<string>();

    // Reject before wasting a request quota entry
    var fileInfo = new FileInfo(pdfPath);
    if (fileInfo.Length > 5 * 1024 * 1024)
        throw new InvalidOperationException("File exceeds 5MB free tier limit. Upgrade or split PDF.");

    byte[] pdfBytes = File.ReadAllBytes(pdfPath);
    string base64 = Convert.ToBase64String(pdfBytes);

    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>("language", "eng"),
        new KeyValuePair<string, string>("filetype", "PDF"),
        new KeyValuePair<string, string>("isCreateSearchablePdf", "false") // Watermarked on free tier
    });

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

    if (!response.IsSuccessStatusCode)
        throw new Exception($"API error: {response.StatusCode}");

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

    if (doc.RootElement.TryGetProperty("ParsedResults", out var results))
    {
        foreach (var result in results.EnumerateArray())
        {
            if (result.TryGetProperty("ParsedText", out var text))
                pageTexts.Add(text.GetString() ?? string.Empty);
        }
    }

    return pageTexts;
}
// OCR.space PDF: size check required, watermarks on free tier
public async Task<List<string>> ExtractTextFromPdf(string pdfPath)
{
    var pageTexts = new List<string>();

    // Reject before wasting a request quota entry
    var fileInfo = new FileInfo(pdfPath);
    if (fileInfo.Length > 5 * 1024 * 1024)
        throw new InvalidOperationException("File exceeds 5MB free tier limit. Upgrade or split PDF.");

    byte[] pdfBytes = File.ReadAllBytes(pdfPath);
    string base64 = Convert.ToBase64String(pdfBytes);

    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>("language", "eng"),
        new KeyValuePair<string, string>("filetype", "PDF"),
        new KeyValuePair<string, string>("isCreateSearchablePdf", "false") // Watermarked on free tier
    });

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

    if (!response.IsSuccessStatusCode)
        throw new Exception($"API error: {response.StatusCode}");

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

    if (doc.RootElement.TryGetProperty("ParsedResults", out var results))
    {
        foreach (var result in results.EnumerateArray())
        {
            if (result.TryGetProperty("ParsedText", out var text))
                pageTexts.Add(text.GetString() ?? string.Empty);
        }
    }

    return pageTexts;
}
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading.Tasks

Public Class OCRSpaceClient
    Private ReadOnly _apiKey As String
    Private ReadOnly _httpClient As HttpClient

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

    Public Async Function ExtractTextFromPdf(pdfPath As String) As Task(Of List(Of String))
        Dim pageTexts As New List(Of String)()

        ' Reject before wasting a request quota entry
        Dim fileInfo As New FileInfo(pdfPath)
        If fileInfo.Length > 5 * 1024 * 1024 Then
            Throw New InvalidOperationException("File exceeds 5MB free tier limit. Upgrade or split PDF.")
        End If

        Dim pdfBytes As Byte() = File.ReadAllBytes(pdfPath)
        Dim base64 As String = Convert.ToBase64String(pdfBytes)

        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)("language", "eng"),
            New KeyValuePair(Of String, String)("filetype", "PDF"),
            New KeyValuePair(Of String, String)("isCreateSearchablePdf", "false") ' Watermarked on free tier
        })

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

        If Not response.IsSuccessStatusCode Then
            Throw New Exception($"API error: {response.StatusCode}")
        End If

        Dim json As String = Await response.Content.ReadAsStringAsync()
        Using doc As JsonDocument = JsonDocument.Parse(json)
            If doc.RootElement.TryGetProperty("ParsedResults", results) Then
                For Each result In results.EnumerateArray()
                    If result.TryGetProperty("ParsedText", text) Then
                        pageTexts.Add(If(text.GetString(), String.Empty))
                    End If
                Next
            End If
        End Using

        Return pageTexts
    End Function
End Class
$vbLabelText   $csharpLabel

IronOCR Yaklaşımı

IronOCR, PDF'leri yerel olarak okur. Limit, keyfi bir dosya boyutu eşiği değil, mevcut bellektir. Aranabilir PDF çıktısı, her lisans katmanında filigransız temiz dosyalar üretir:

//IronOCR PDF: native support, no size limit, no watermarks
public List<string> ExtractTextFromPdf(string pdfPath)
{
    var pageTexts = new List<string>();

    using var input = new OcrInput();
    input.LoadPdf(pdfPath); //Hayır5MB ceiling

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

    foreach (var page in result.Pages)
        pageTexts.Add(page.Text);

    return pageTexts;
}

// Generate searchable PDF — no watermarks
public void CreateSearchablePdf(string inputPath, string outputPath)
{
    var result = new IronTesseract().Read(inputPath);
    result.SaveAsSearchablePdf(outputPath);
}
//IronOCR PDF: native support, no size limit, no watermarks
public List<string> ExtractTextFromPdf(string pdfPath)
{
    var pageTexts = new List<string>();

    using var input = new OcrInput();
    input.LoadPdf(pdfPath); //Hayır5MB ceiling

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

    foreach (var page in result.Pages)
        pageTexts.Add(page.Text);

    return pageTexts;
}

// Generate searchable PDF — no watermarks
public void CreateSearchablePdf(string inputPath, string outputPath)
{
    var result = new IronTesseract().Read(inputPath);
    result.SaveAsSearchablePdf(outputPath);
}
Imports System.Collections.Generic

'IronOCR PDF: native support, no size limit, no watermarks
Public Function ExtractTextFromPdf(pdfPath As String) As List(Of String)
    Dim pageTexts As New List(Of String)()

    Using input As New OcrInput()
        input.LoadPdf(pdfPath) 'Hayır5MB ceiling

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

        For Each page In result.Pages
            pageTexts.Add(page.Text)
        Next
    End Using

    Return pageTexts
End Function

' Generate searchable PDF — no watermarks
Public Sub CreateSearchablePdf(inputPath As String, outputPath As String)
    Dim result = New IronTesseract().Read(inputPath)
    result.SaveAsSearchablePdf(outputPath)
End Sub
$vbLabelText   $csharpLabel

Şifre korumalı PDF'ler tek bir parametredir: input.LoadPdf("encrypted.pdf", Password: "secret"). PDF OCR nasıl yapılır kılavuzu, sayfa aralığı seçimi ve şifre işlemini ayrıntılı olarak ele almaktadır. Aranabilir PDF oluşturma kalıpları için aranabilir PDF nasıl yapılır kılavuzuna bakın.

Hata Yönetimi

OCR.space, hataları iki ayrı kanal üzerinden iletir: HTTP durum kodları ve bir JSON IsErroredOnProcessing bayrağı. Üretim kodu her ikisini de kontrol etmeli, IsErroredOnProcessing doğru olduğunda JSON hata dizisini parçalara ayırmalı ve kısmi arızalar için sayfa başına FileParseExitCode değerlerini incelemelidir. Bunların hiçbiri tiplenmiş değildir — her şey JsonDocument üzerinden metin ayrımıdır:

// OCR.space: two error layers, all string-based
public async Task<string> SafeExtract(HttpClient client, string apiKey, string imagePath)
{
    try
    {
        byte[] imageBytes = File.ReadAllBytes(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}")
        });

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

        if (!response.IsSuccessStatusCode)
        {
            switch (response.StatusCode)
            {
                case System.Net.HttpStatusCode.Unauthorized:
                    throw new Exception("Invalid API key");
                case System.Net.HttpStatusCode.TooManyRequests:
                    throw new Exception("Rate limit exceeded — wait and retry");
                case System.Net.HttpStatusCode.PaymentRequired:
                    throw new Exception("Quota exceeded — upgrade plan");
                default:
                    throw new Exception($"API error: {response.StatusCode}");
            }
        }

        // Second error layer: JSON-level failures
        string json = await response.Content.ReadAsStringAsync();
        using var doc = JsonDocument.Parse(json);

        if (doc.RootElement.TryGetProperty("IsErroredOnProcessing", out var isError)
            && isError.GetBoolean())
        {
            var messages = new List<string>();
            if (doc.RootElement.TryGetProperty("ErrorMessage", out var errors))
            {
                foreach (var e in errors.EnumerateArray())
                    messages.Add(e.GetString() ?? "Unknown error");
            }
            throw new Exception(string.Join("; ", messages));
        }

        // Third layer: per-page exit codes
        if (doc.RootElement.TryGetProperty("ParsedResults", out var results))
        {
            foreach (var result in results.EnumerateArray())
            {
                if (result.TryGetProperty("FileParseExitCode", out var exitCode)
                    && exitCode.GetInt32() != 1)
                    throw new Exception($"Page parse failed: exit code {exitCode.GetInt32()}");
            }
        }

        return doc.RootElement
            .GetProperty("ParsedResults")[0]
            .GetProperty("ParsedText")
            .GetString() ?? string.Empty;
    }
    catch (JsonException ex)
    {
        throw new Exception($"Invalid API response: {ex.Message}");
    }
    catch (HttpRequestException ex)
    {
        throw new Exception($"Network error: {ex.Message}");
    }
}
// OCR.space: two error layers, all string-based
public async Task<string> SafeExtract(HttpClient client, string apiKey, string imagePath)
{
    try
    {
        byte[] imageBytes = File.ReadAllBytes(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}")
        });

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

        if (!response.IsSuccessStatusCode)
        {
            switch (response.StatusCode)
            {
                case System.Net.HttpStatusCode.Unauthorized:
                    throw new Exception("Invalid API key");
                case System.Net.HttpStatusCode.TooManyRequests:
                    throw new Exception("Rate limit exceeded — wait and retry");
                case System.Net.HttpStatusCode.PaymentRequired:
                    throw new Exception("Quota exceeded — upgrade plan");
                default:
                    throw new Exception($"API error: {response.StatusCode}");
            }
        }

        // Second error layer: JSON-level failures
        string json = await response.Content.ReadAsStringAsync();
        using var doc = JsonDocument.Parse(json);

        if (doc.RootElement.TryGetProperty("IsErroredOnProcessing", out var isError)
            && isError.GetBoolean())
        {
            var messages = new List<string>();
            if (doc.RootElement.TryGetProperty("ErrorMessage", out var errors))
            {
                foreach (var e in errors.EnumerateArray())
                    messages.Add(e.GetString() ?? "Unknown error");
            }
            throw new Exception(string.Join("; ", messages));
        }

        // Third layer: per-page exit codes
        if (doc.RootElement.TryGetProperty("ParsedResults", out var results))
        {
            foreach (var result in results.EnumerateArray())
            {
                if (result.TryGetProperty("FileParseExitCode", out var exitCode)
                    && exitCode.GetInt32() != 1)
                    throw new Exception($"Page parse failed: exit code {exitCode.GetInt32()}");
            }
        }

        return doc.RootElement
            .GetProperty("ParsedResults")[0]
            .GetProperty("ParsedText")
            .GetString() ?? string.Empty;
    }
    catch (JsonException ex)
    {
        throw new Exception($"Invalid API response: {ex.Message}");
    }
    catch (HttpRequestException ex)
    {
        throw new Exception($"Network error: {ex.Message}");
    }
}
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading.Tasks

Public Class OCRSpace
    Public Async Function SafeExtract(client As HttpClient, apiKey As String, imagePath As String) As Task(Of String)
        Try
            Dim imageBytes As Byte() = File.ReadAllBytes(imagePath)
            Dim base64 As String = Convert.ToBase64String(imageBytes)

            Dim content 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}")
            })

            Dim response As HttpResponseMessage = Await client.PostAsync("https://api.ocr.space/parse/image", content)

            If Not response.IsSuccessStatusCode Then
                Select Case response.StatusCode
                    Case System.Net.HttpStatusCode.Unauthorized
                        Throw New Exception("Invalid API key")
                    Case System.Net.HttpStatusCode.TooManyRequests
                        Throw New Exception("Rate limit exceeded — wait and retry")
                    Case System.Net.HttpStatusCode.PaymentRequired
                        Throw New Exception("Quota exceeded — upgrade plan")
                    Case Else
                        Throw New Exception($"API error: {response.StatusCode}")
                End Select
            End If

            ' Second error layer: JSON-level failures
            Dim json As String = Await response.Content.ReadAsStringAsync()
            Using doc As JsonDocument = JsonDocument.Parse(json)
                If doc.RootElement.TryGetProperty("IsErroredOnProcessing", ByRef isError) AndAlso isError.GetBoolean() Then
                    Dim messages As New List(Of String)()
                    If doc.RootElement.TryGetProperty("ErrorMessage", ByRef errors) Then
                        For Each e In errors.EnumerateArray()
                            messages.Add(e.GetString() ?? "Unknown error")
                        Next
                    End If
                    Throw New Exception(String.Join("; ", messages))
                End If

                ' Third layer: per-page exit codes
                If doc.RootElement.TryGetProperty("ParsedResults", ByRef results) Then
                    For Each result In results.EnumerateArray()
                        If result.TryGetProperty("FileParseExitCode", ByRef exitCode) AndAlso exitCode.GetInt32() <> 1 Then
                            Throw New Exception($"Page parse failed: exit code {exitCode.GetInt32()}")
                        End If
                    Next
                End If

                Return doc.RootElement _
                    .GetProperty("ParsedResults")(0) _
                    .GetProperty("ParsedText") _
                    .GetString() ?? String.Empty
            End Using
        Catch ex As JsonException
            Throw New Exception($"Invalid API response: {ex.Message}")
        Catch ex As HttpRequestException
            Throw New Exception($"Network error: {ex.Message}")
        End Try
    End Function
End Class
$vbLabelText   $csharpLabel

IronOCR, açık mesajlarla standart .NET istisnalarını yükseltir. JSON ayrıştırma yok, HTTP durum kodu değiştirme yok, katmanlı hata çıkarımı yok:

// IronOCR: standard .NET exceptions
public string SafeExtract(string imagePath)
{
    try
    {
        var result = new IronTesseract().Read(imagePath);
        return result.Text;
    }
    catch (FileNotFoundException)
    {
        throw; // File not found — straightforward
    }
    catch (Exception ex) when (ex.Message.Contains("corrupt"))
    {
        throw new Exception($"Image file is corrupt: {imagePath}");
    }
    //HayırJSON errors.HayırHTTP errors.Hayırrate limit errors.
}
// IronOCR: standard .NET exceptions
public string SafeExtract(string imagePath)
{
    try
    {
        var result = new IronTesseract().Read(imagePath);
        return result.Text;
    }
    catch (FileNotFoundException)
    {
        throw; // File not found — straightforward
    }
    catch (Exception ex) when (ex.Message.Contains("corrupt"))
    {
        throw new Exception($"Image file is corrupt: {imagePath}");
    }
    //HayırJSON errors.HayırHTTP errors.Hayırrate limit errors.
}
Imports System
Imports IronOcr

Public Function SafeExtract(imagePath As String) As String
    Try
        Dim result = New IronTesseract().Read(imagePath)
        Return result.Text
    Catch ex As FileNotFoundException
        Throw ' File not found — straightforward
    Catch ex As Exception When ex.Message.Contains("corrupt")
        Throw New Exception($"Image file is corrupt: {imagePath}")
    End Try
End Function
$vbLabelText   $csharpLabel

IronTesseract API referans dokümanı ve OcrResult API referans dokümanı, çıkarım kalitesinin değerlendirilmesi için Confidence özelliği de dahil olmak üzere tiplenmiş sonuç yapısını belgeler.

API Eşleme Başvurusu

OCR.space Konsepti IronOCR Karşılığı
POST https://api.ocr.space/parse/image new IronTesseract().Read(path)
FormUrlEncodedContent / MultipartFormDataContent OcrInput
base64Image parametresi input.LoadImage(path) veya input.LoadImage(bytes)
language parametresi ocr.Language = OcrLanguage.English
OCREngine parametresi Motor dahili olarak yönetiliyor
isOverlayRequired parametresi result.Words / result.Lines (her zaman mevcut)
isCreateSearchablePdf parametresi result.SaveAsSearchablePdf(outputPath)
filetype=PDF parametresi input.LoadPdf(path)
ParsedResults[0].ParsedText result.Text
ParsedResults[n] (sayfa başına) result.Pages[n].Text
IsErroredOnProcessing JSON bayrağı Standart .NET istisnası
FileParseExitCode sayfa başına bayrak Standart .NET istisnası
ProcessingTimeInMilliseconds Varsayılan – ekstra ayrıştırma gerekmez
HTTP 429 / oran limiti 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
SemaphoreSlim hız sınırlayıcı (kullanıcı tarafından yapılmış) Gerekli değil
Her istekte API anahtarı IronOcr.License.LicenseKey (başlangıçta bir kez)

Takımlar OCR.space'den IronOCR'ye Geçmeyi Düşündüklerinde

Yük Testi Sırasında Ücretsiz Katmanı Aşmak

OCR.space'in IP başına günlük 500 istek tavanı, yumuşak bir öneri değil, katı bir duvardır. Ekipler bunu, bir ofis IP adresini paylaşan birden çok geliştiricinin olduğu yük testi veya sahne dağıtımlarında keşfeder. OCR.space'e karşı entegrasyon testleri yürüten paylaşılan bir CI/CD hattı, iş günü bitmeden günlük kotayı tüketecektir. Bu noktada uygulama hata verir, çünkü kod yanlış olduğu için değil, üçüncü bir tarafın sayacı keyfi bir eşik seviyesine ulaştığı için. Yerel işleme geçmek, bu hata kategorisini tamamen ortadan kaldırır – işleme işlemi yerinde çalıştığı için tükenilecek bir kota yoktur.

Uyumluluk ve Veri Sınıflandırması İncelemeleri

Belgeleri PII, PHI veya finansal olarak hassas olarak sınıflandıran güvenlik incelemeleri, OCR.space için ikili bir sorun yaratır: hizmetin dahili dağıtım yolu yoktur. HIPAA senaryoları için belgelenmiş bir İş Ortağı Anlaşması (BAA) eşdeğeri, GDPR altında AB veri aktarımlarını net bir şekilde yöneten bir Veri İşleme Anlaşması yapısı ve belgenin gönderilmesini engelleyecek bir teknik mekanizma, sözleşme kontrolleri olsa bile, yoktur. Bulut üzerinden aktarılan belge işlemeye karşı uyumluluk bulguları alan ekiplerin yerel bir çözüme ihtiyacı vardır. IronOCR, bu gereksinimi tasarım gereği karşılar – belgeler asla uygulama sunucusunu terk etmez. Lisansa ilişkin sayfa, bulut-sağlayıcı incelemesini kapsamdan çıkararak uyumluluk dokümantasyonunu basitleştiren süresiz lisans yapısını belgeliyor.

Entegrasyon Kodu Bakım Yükü

OCR.space entegrasyonları, özellik gereksinimlerine orantılı olarak teknik borç biriktirir. Başlangıçtaki HTTP istemcisi yönetilebilir. Sonrasında ekip, tekrar deneme mantığını ekler. Sonra ekip, bir adresi paylaşan birden fazla hizmet nedeniyle, toplam IP oranı limiti izlemeyi ekler. Daha sonra dosya boyutu ön-doğrulama adımını eklerler. Ardından JSON hata yapısının Motor 1 ve Motor 2 yanıtları arasında farklılık gösterdiğini keşfederler ve bir dal eklerler. Altı ay sonra, OCR.space entegrasyonu, OCR ile ilgili herhangi bir şeye dokunmadan önce her yeni ekip üyesinin anlaması gereken 400 satır altyapı kodu olur. O ekip, bakım maliyetini bir $999 bir kerelik IronOCR lisansına karşı değerlendirirken aritmetik basittir.

Yapılandırılmış Çıktı Gereksinimleri

OCR.space yalnızca düz metin döndürür ve başka hiçbir şey sağlamaz. Yanıtta kelime koordinatları, satır sınırları, paragraf segmentasyonu veya kelime başına güven skorları yoktur. Fatura alanlarından belirli alanları çıkartmak isteyen uygulamalar – bilinen bir bölgede satıcı ismi, sağ alt köşede toplam tutar – OCR.space'in çıktısından oluşturmak için yapılandırılmış bir temele sahip değildir. IronOCR, her ayrıntı düzeyinde koordinatlar ve güvenlik değerleriyle tam bir belge hiyerarşisini açığa çıkarır: sayfalar, paragraflar, satırlar ve bireysel kelimeler. Bölgeye dayalı işleme, tüm sayfa çıktısını sonradan işlemeye gerek kalmadan, belirli belge bölgelerini hedefleme imkanı sağlar. Sonuç okuma nasıl yapılır ve bölgeye dayalı OCR rehberi bu kalıpları ayrıntılı olarak ele almaktadır.

Ücretsiz Katmanın Ötesinde Hacim Büyümesi

Ayda 25.000 istek için ücretsiz katman, düşük hacimli senaryolar için işlevseldir. Bunun ötesinde, ücretli katmanlar uygulanır — güncel fiyatlandırma için OCR.space ile iletişime geçin. Bu maliyetler zamanla birikir ve karşılaştırma, bir $999 ile sürekli bir lisans ile, asla istek başına ücretlendirilmeden yapılır. Aylık 25.000'den fazla belge hacmi büyümesi projeksiyonu yapan ekipler için yerel işlemeye yönelik basit bir maliyet durumu vardır.

Genel Geçiş Dikkat Edilmesi Gereken Hususlar

HTTP İstemcisini Bir Yöntem Çağrısıyla Değiştirme

OCR.space'den IronOCR'ya geçiş, belgelerden gelen metni her ikisi de döndürdüğü için mimari olarak basittir. HTTP istemcisi, JSON ayrıştırıcısı, oran sınırlayıcı ve özel istisna türleri ortadan kalkar. Yerine geçen tek şey bir NuGet paketi ve yöntem çağrılarıdır. Hizmet sınırındaki önce/sonra:

// Before: OCR.space service (simplified — actual implementation is200+lines)
public class OcrSpaceService : IDisposable
{
    private readonly HttpClient _client = new();
    private readonly string _apiKey;

    public OcrSpaceService(string apiKey) => _apiKey = apiKey;

    public async Task<string> ProcessDocument(string path)
    {
        byte[] bytes = File.ReadAllBytes(path);
        string base64 = Convert.ToBase64String(bytes);

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

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

        string json = await response.Content.ReadAsStringAsync();
        using var doc = JsonDocument.Parse(json);
        return doc.RootElement.GetProperty("ParsedResults")[0].GetProperty("ParsedText").GetString()!;
    }

    public void Dispose() => _client.Dispose();
}

// After:IronOCR service — no HttpClient, no JSON, no API key
public class IronOcrService
{
    private readonly IronTesseract _ocr = new();

    public string ProcessDocument(string path)
    {
        return _ocr.Read(path).Text;
    }
    //HayırDispose — no external connections to close
}
// Before: OCR.space service (simplified — actual implementation is200+lines)
public class OcrSpaceService : IDisposable
{
    private readonly HttpClient _client = new();
    private readonly string _apiKey;

    public OcrSpaceService(string apiKey) => _apiKey = apiKey;

    public async Task<string> ProcessDocument(string path)
    {
        byte[] bytes = File.ReadAllBytes(path);
        string base64 = Convert.ToBase64String(bytes);

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

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

        string json = await response.Content.ReadAsStringAsync();
        using var doc = JsonDocument.Parse(json);
        return doc.RootElement.GetProperty("ParsedResults")[0].GetProperty("ParsedText").GetString()!;
    }

    public void Dispose() => _client.Dispose();
}

// After:IronOCR service — no HttpClient, no JSON, no API key
public class IronOcrService
{
    private readonly IronTesseract _ocr = new();

    public string ProcessDocument(string path)
    {
        return _ocr.Read(path).Text;
    }
    //HayırDispose — no external connections to close
}
Imports System
Imports System.IO
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.Text.Json

Public Class OcrSpaceService
    Implements IDisposable

    Private ReadOnly _client As New HttpClient()
    Private ReadOnly _apiKey As String

    Public Sub New(apiKey As String)
        _apiKey = apiKey
    End Sub

    Public Async Function ProcessDocument(path As String) As Task(Of String)
        Dim bytes As Byte() = File.ReadAllBytes(path)
        Dim base64 As String = Convert.ToBase64String(bytes)

        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}")
        })

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

        Dim json As String = Await response.Content.ReadAsStringAsync()
        Using doc = JsonDocument.Parse(json)
            Return doc.RootElement.GetProperty("ParsedResults")(0).GetProperty("ParsedText").GetString()
        End Using
    End Function

    Public Sub Dispose() Implements IDisposable.Dispose
        _client.Dispose()
    End Sub
End Class

Public Class IronOcrService
    Private ReadOnly _ocr As New IronTesseract()

    Public Function ProcessDocument(path As String) As String
        Return _ocr.Read(path).Text
    End Function
End Class
$vbLabelText   $csharpLabel

IDisposable uygulaması ortadan kalkar çünkü yönetilecek HttpClient yoktur.

API Anahtarının Kaldırılması

OCR.space her HTTP isteğinde bir API anahtarı gerektirir. Bu anahtar güvenli bir şekilde saklanmalı, ifşa edildiğinde döndürülmeli ve kaynak denetiminden hariç tutulmalıdır. IronOCR, genellikle bir ortam değişkeni veya yapılandırma sistemi üzerinden, uygulama başlatıldığında bir kez ayarlanan bir lisans anahtarı kullanır:

// At application startup — once, not per request
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// At application startup — once, not per request
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
' At application startup — once, not per request
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
$vbLabelText   $csharpLabel

Geçişten sonra, API anahtar döndürme süreci, gizli yönetim yapılandırması ve istek başına anahtar enjeksiyon mantığı tümüyle gereksiz hale gelir.

Göçten Sonra Ön İşleme

OCR.space, sonuçları geri göndermeden önce sunucu tarafında işleme uygular, ancak geliştiricilerin o işlemenin neyi içerdiği veya içermediği konusunda kontrolü yoktur. IronOCR, açık ön işleme yöntemleri sağlar. Belge kalitesi bir endişe ise — eğimli taramalar, düşük kontrastlı fotokopiler, gürültülü faks çıktıları — ön işleme boru hattı üç ila beş yöntem çağrısıdır:

using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");
input.Deskew();
input.DeNoise();
input.Contrast();
input.Binarize();
input.EnhanceResolution(300);
var result = new IronTesseract().Read(input);
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");
input.Deskew();
input.DeNoise();
input.Contrast();
input.Binarize();
input.EnhanceResolution(300);
var result = new IronTesseract().Read(input);
Imports IronOcr

Using input As New OcrInput()
    input.LoadImage("low-quality-scan.jpg")
    input.Deskew()
    input.DeNoise()
    input.Contrast()
    input.Binarize()
    input.EnhanceResolution(300)
    Dim result = New IronTesseract().Read(input)
End Using
$vbLabelText   $csharpLabel

Görüntü kalitesi düzeltme rehberi ve görüntü renk düzeltme rehberi mevcut filtrelerin tümünü ve doğruluk farklarını gösteren örneklerle belgelemektedir.

Async vs. Senkron

OCR.space aramaları, HTTP turu içerdiği için doğası gereği asenkroniktir.IronOCR aramaları varsayılan olarak senkroniktir, bu da web dışı bağlamlarda kodu basitleştirir. ASP.NET ve engellemeyen yürütme gerektiren sunucu senaryoları için, IronOCR, Task.Run saran veya doğrudan bir async API üzerinden asenkron çalışmayı destekler. Asenkron OCR rehberi kalıpları kapsar. Önceden bir bulut çağrısı bekleyen bir hizmet yönteminden await kaldırmak, async yalnızca OCR.space gerektirdiği için benimsendiği bağlamlarda çağrı yığınını basitleştirir.

Ek IronOCR Yetenekleri

Yukarıdaki bölümlerde ele alınmayan, OCR.space ile eşdeğer fonksiyonellik taşımayan her bir özellik:

  • hOCR dışa aktarma: result.SaveAsHocrFile("output.hocr") downstream belge işleme boru hatları için standartlara uygun hOCR çıkışı üretir.
  • İlerleme takibi: Uzun süreli çok sayfalı toplu işlem operasyonları için ilerleme olaylarına abone olun, UI uygulamalarında ilerleme çubukları ve ETA hesaplamalarına olanak tanır.
  • Tablo çıkarımı: Yapılandırılmış tablo verilerine sonuç modeli ile erişilebilir, kolon hizalamasını gerektiren fatura kalem çıkarılması gibi kullanım senaryolarını destekler.
  • Özelleşmiş belge okuma: Pasaport MRZ alanları, plaka, MICR çek yatay çizgileri ve el yazısı tanıma gibi amaç için geliştirilmiş özellikler, aynı IronTesseract API aracılığıyla erişilebilir.

.NET Uyumluluğu ve Geleceğe Hazırlık

IronOCR, .NET 6, .NET 7, .NET 8 ve .NET 9 hedef alır, her LTS ve STS sürümü için etkin destek sağlar. Kütüphane Windows x64, Windows x86,Linuxx64, macOS, Docker, AWS Lambda ve Azure App Service üzerinde çalışır — hepsi tek bir NuGet paketi üzerinden işletim sistemine özgü bir yapılandırma olmadan. OCR.space, her dağıtım ortamından çıkış yönlü HTTPS gerektirir, bu da hava boşluklu ağları, kısıtlayıcı kurumsal proxy'leri ve politika gereğince üçüncü taraf API'lere çıkış yönlü trafiğin engellendiği altyapıyı hariç tutar. IronOCR'nin çalışma zamanı ağ gereksinimleri yoktur; yürütmeyi tamamen yerinde yapar. .NET 10'un 2026 sonlarına doğru yayına girmesiyle birlikte, IronOCR'nin .NET büyük sürümlerindeki uygunluğunu koruma geçmişi entegrasyon değişiklikleri olmadan süreklilik sağlar.

Sonuç

OCR.space, gerçek ve yararlı bir nişi işgal eder: bir hafta sonu boyunca bir OCR özelliği prototiplemek isteyen geliştiriciler, metin çıkarımı kavramlarını araştıran öğrenciler veya aylık 25.000 belgenin altında hacmi olan uyumluluk gereksinimi olmayan kişisel araçlar için. Bu kitle için, ücretsiz katman gerçek bir değer sunar.

Sorun, .NET geliştiricilerinin genellikle hafta sonu prototipleri oluşturmuyor olmasıdır. Onlar faturalama sistemleri, tıbbi kayıt işlemcileri, belge arşivleme boru hatları ve uyumluluk duyarlı iş uygulamaları geliştirir. Bu bağlamlar için, OCR.space'in mevcut olmayan NuGet paketi bir rahatsızlık değildir — yapısal bir uyumsuzluktur. HTTP istemcisi, oran sınırlayıcı, JSON ayrıştırıcısı ve tekrar deneme altyapısını kurmak için harcanan her saat, uygulamanın gerçek gereksinimlerini karşılamaya harcanmayan bir saattir. Bu maliyet önden yüklü, ancak entegrasyonun ömrü boyunca bakım maliyeti devam eder.

IronOCR, her OCR.space entegrasyonunu tanımlayan spesifik hata modunu ele alır: gerçek bir SDK'nın yokluğu. Bir NuGet paketi, bir yöntem çağırma, HTTP tesisatı yok, oran sınırlamaları yok, dış sunuculara belge aktarma yok. $999 giriş fiyatı tek seferlik bir maliyettir; artan OCR.space abonelik maliyetleri, özellikle hacim arttıkça zaman içinde bunu aşacaktır. Uyum gereksinimleri olan ekipler için, yerel işlem maliyeti ne olursa olsun tek seçenektir.

Karşılaştırma sonunda tek bir soruya indirgenir: uygulama, harici bir REST bağımlılığı olarak mı yoksa bir kütüphane işlevi olarak mı OCR gerektirir? .NET üretim uygulamaları için cevap neredeyse her zaman ikincisidir.

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 nedir?

OCR.space API, geliştiriciler ve işletmeler tarafından görüntülerden ve belgelerden metin çıkarmak için kullanılan bir OCR çözümüdür. .NET uygulama geliştirmesi için IronOCR ile birlikte değerlendirilen birkaç OCR seçeneğinden biridir.

IronOCR, .NET geliştiricileri için OCR.space API ile nasıl karşılaştırılır?

IronOCR, IronTesseract'ı çekirdek motoru olarak kullanan, NuGet-native bir .NET OCR kütüphanesidir. OCR.space API ile karşılaştırıldığında, daha basit bir dağıtım (SDK yükleyicileri yok), sabit fiyatlandırma ve COM interop veya bulut bağımlılıkları olmadan temiz bir C# API sunar.

IronOCR, OCR.space API'den daha mı kolay kuruluyor?

IronOCR, tek bir NuGet paketi aracılığıyla yüklenir. SDK kurulumları, kopyalamak için lisans dosyaları, kaydedilecek COM bileşenleri veya yönetilecek ayrı çalışma zamanı ikili dosyaları yoktur. Tüm OCR motoru paket içinde yer alır.

OCR.space API ve IronOCR arasındaki doğruluk farkları nelerdir?

IronOCR, standart iş belgeleri, faturalar, makbuzlar ve taranmış formlar için yüksek tanıma doğruluğu sağlar. Çok kötü durumda olan belgeler ya da nadir yazılar için ise doğruluk, kaynak kalitesine göre değişiklik gösterebilir. IronOCR, düşük kaliteli girişlerde tanımayı geliştirmek için görüntü ön işleme filtreleri içerir.

IronOCR, PDF metin çıkarma desteği sunuyor mu?

Evet. IronOCR, tek bir çağrıda hem yerel PDF'lerden hem de taranmış PDF görüntülerinden metin çıkarır. Çok sayfalı TIFF dosyaları, görüntüler ve akıntılar da desteklenir. Taranmış PDF'ler için, OCR sayfa bazında uygulanır ve her sayfa için sonuç nesneleri sağlanır.

OCR.space API lisanslaması IronOCR ile nasıl karşılaştırılır?

IronOCR, sayfa veya tarama başına ücret içermeyen sabit oranlı bir süresiz lisans kullanır. Yüksek belge hacmi işleyen kuruluşlar, hacme rağmen aynı lisans maliyetini öder. Ayrıntılar ve hacim fiyatlandırması IronOCR lisans sayfasında mevcuttur.

IronOCR hangi dilleri destekliyor?

IronOCR, ayrı NuGet dil paketleri aracılığıyla 127 dili destekler. Bir dil eklemek için tek bir 'dotnet add package IronOcr.Languages.{Language}' komutu gerekir. Manuel dosya yerleştirme veya yol yapılandırması gerekmez.

.NET projesine IronOCR'yi nasıl kurarım?

NuGet üzerinden kurun: 'Install-Package IronOcr' Package Manager Console'da veya 'dotnet add package IronOcr' CLI'de. Ek dil paketleri aynı şekilde yüklenir. Yerel SDK kurucusu gerekmez.

IronOCR, OCR.space'ten farklı olarak Docker ve konteyner tabanlı dağıtımlar için uygun mudur?

Evet. IronOCR, NuGet paketi aracılığıyla Docker konteynerlerinde çalışır. Lisans anahtarı, bir ortam değişkeni aracılığıyla ayarlanır. Lisans dosyaları, SDK yolları veya OCR motoru için hacimlerin bağlanmasına gerek yoktur.

IronOCR'u OCR.space ile karşılaştırarak satın almadan önce deneyebilir miyim?

Evet. IronOCR deneme modu, belgeleri işler ve çıkış üzerine bir filigran eklemeli OCR sonuçları döndürür. Lisans satın almadan önce kendi belgeleriniz üzerinde doğruluğu kontrol edebilirsiniz.

IronOCR, metin çıkarma yanında barkod okuma desteği sunar mı?

IronOCR, metin çıkarma ve OCR'ye odaklanır. Barkod okuma için Iron Software, eşlik eden bir kütüphane olan IronBarcode'u sağlar. Her ikisi de ayrı ayrı veya Iron Suite paketi olarak mevcuttur.

OCR.space API'den IronOCR'a geçiş kolay mı?

OCR.space API'den IronOCR'a geçiş genellikle başlangıç dizilimlerini IronTesseract örneklemesiyle değiştirmek, COM yaşam döngüsü yönetimini kaldırmak ve API çağrılarını güncellemekle ilgilidir. Çoğu geçiş, kod karmaşıklığını önemli ölçüde azaltır.

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