Windows'ta Tesseract OCR'ı C# ile Nasıl Yüklenir?
Bu kılavuz, .NET geliştiricilerini Google Cloud Vision'ı IronOCR ile değiştirmede birdenbire yerinde bir OCR motoru olarak geçirir. Yayınlanan dört yapısal değişimi kapsar: kimlik bilgisi kaldırma, Protobuf açıklama işleme yedeklemesi, toplu açıklama basitleştirme ve çok sayfalı belge işleme.
Google Cloud VisionOCR'den Neden Geçiş Yapılmalı
Taşınma kararı neredeyse her zaman iki farkındalıktan biriyle başlar: bir uyum denetimi bulut belge iletimini engeller ya da GCP kimlik bilgilerini, GCS kovalarını, asenkron anketleri ve görüntü başına ücretlendirmeyi yönetmenin operasyonel yüzeyi OCR'nin kendisinden daha pahalı hale gelir.
Servis Hesabı JSON Anahtar Yaşam Döngüsü. Uygulamanızın her dağıtımı — geliştirme makinesi, CI/CD hattı, hazırlık sunucusu, üretim sunucusu, Docker konteyneri, Kubernetes pod'u — aynı servis hesabı JSON anahtar dosyasını gerektirir. Dosya, bir RSA özel anahtarı içerir. Kaynak kontrole asla girmemeli, bir program çerçevesinde döndürülmeli, dosya sistemi izinleri ile korunmalı ve döndürülme gerçekleştiğinde tüm ortamlarda aynı anda güncellenmelidir. Bir tehlikeye atılmış anahtar, GCP Konsolunda manuel olarak iptal edilene kadar API erişimi verir. IronOCR, bu tüm operasyon yüzeyini uygulama başlangıcında bir kez ayarlanmış tek bir lisans anahtar dizisi ile değiştirir.
Ölçekli Hızlandırılmış Faturalandırma. 1.000 resim başına $1.50 ve PDF sayfası başına $0.0015 maliyetler, geliştirme sırasında görünmez, ancak üretimde can acıtıcıdır. Ayda 200.000 sayfa işleyeyen bir belge işleme hattı, yalnızca API ücretlerinde ayda $300 maliyete mal olur, GCS depolama maliyetlerinden ve çıkış maliyetlerinden önce. Bu $300 her ay süresiz yinelenir. IronOCR'nin süresiz lisansı, OCR'yi ölçüm bazlı işletim giderinden ikinci veya üçüncü yılda çalışması bedava olan sabit bir sermaye kalemi haline dönüştürür.
GCS Asenkron PDF Hattı. Google Cloud Vision, PDF'leri doğrudan API girdisi olarak kabul etmez. Tam boru hattı, ikinci bir NuGet paketini (Google.Cloud.Storage.V1), sağlanmış bir GCS bucket'ını, asenkron bir yüklemeyi, AsyncBatchAnnotateFilesAsync çağrısını, bir anket döngüsünü, GCS'den JSON çıktı analizini ve bir temizleme adımını gerektirir. Bu boru hattı, herhangi bir metin çıkarılmadan önce 50'den fazla kod satırını kapsar. IronOCR, dış bağımlılıklar olmadan senkron şekilde üç satırda bir PDF'yi okur.
Protobuf Sembol Birleştirme. DOCUMENT_TEXT_DETECTION yanıtı, Metin'leri bir Protobuf Sayfaları, Bloklar, Paragraflar, Kelimeler ve Semboller hiyerarşisi içerisinde sembol düzeyinde saklar. Paragraf metinlerini okumak, beş iç içe döngü boyunca yineleme yapılmasını ve .SelectMany(w => w.Symbols).Select(s => s.Text) çağrısının yapılmasını gerektirir.IronOCR paragraf metnini paragraph.Text olarak döndürür — türü belirli bir dizge özelliği.
Varsayılan Olarak Dakikada 1.800 İstek Limiti. Varsayılan kotanın üzerindeki toplu işler, boru hattını her aşım başına 60 saniye durduran StatusCode.ResourceExhausted yanıtlarını alır. Kota artırımı, bir GCP Konsolu isteği ve Google'ın onayını gerektirir. IronOCR, yerel olarak mevcut CPU çekirdekleri hızında işleme yapar — yönetilecek bir kota yok, onay alacak bir şey yok, ve oran sınırlama için herhangi bir tekrar mantığı gerekmiyor.
Çevrimdışı veya İzole Edilmiş Destek Yok. Google Cloud Vision, Google'ın uç noktalarına internet bağlantısı gerektirir. İzole edilmiş ağlar, sınıflandırılmış veri merkezleri ve endüstriyel kontrol sistemleri, herhangi bir mimari karmaşıklık seviyesinde kullanılamaz. IronOCR, başlangıç lisans doğrulaması sonrasında sıfır dışa giden ağ bağlantısı ile çalışır.
Temel Sorun
Google Cloud Vision, OCR kodunun ilk satırı çalıştırılmadan önce disk üzerinde bir JSON anahtar dosyası gerektirir:
// Google Cloud Vision: JSON key file deployed to every server before this line works
// GOOGLE_APPLICATION_CREDENTIALS="/etc/secrets/service-account.json" must be set
// Key contains RSA private key — rotate manually, revoke if compromised
_client = ImageAnnotatorClient.Create();
var image = Image.FromFile("document.jpg");
var response = _client.DetectText(image); // document leaves your infrastructure
string text = response[0].Description;
// Google Cloud Vision: JSON key file deployed to every server before this line works
// GOOGLE_APPLICATION_CREDENTIALS="/etc/secrets/service-account.json" must be set
// Key contains RSA private key — rotate manually, revoke if compromised
_client = ImageAnnotatorClient.Create();
var image = Image.FromFile("document.jpg");
var response = _client.DetectText(image); // document leaves your infrastructure
string text = response[0].Description;
' Google Cloud Vision: JSON key file deployed to every server before this line works
' GOOGLE_APPLICATION_CREDENTIALS="/etc/secrets/service-account.json" must be set
' Key contains RSA private key — rotate manually, revoke if compromised
_client = ImageAnnotatorClient.Create()
Dim image = Image.FromFile("document.jpg")
Dim response = _client.DetectText(image) ' document leaves your infrastructure
Dim text As String = response(0).Description
IronOCR, bir dize ile başlar ve tamamen yerel makinede çalışır:
// IronOCR: one string at startup, no key files, no environment variables
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read("document.jpg").Text; // local, no cloud
// IronOCR: one string at startup, no key files, no environment variables
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read("document.jpg").Text; // local, no cloud
Imports IronOcr
' IronOCR: one string at startup, no key files, no environment variables
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim text As String = New IronTesseract().Read("document.jpg").Text ' local, no cloud
IronOCR veGoogle Cloud VisionOCR: Özellik Karşılaştırması
Aşağıdaki tablo, geçiş için iş durumu oluşturan ekipler için özellikleri doğrudan eşler.
| Özellik | Google Cloud Vision OCR | IronOCR |
|---|---|---|
| İşleme yeri | Google Cloud (uzaktan) | Yerinde (yerel) |
| Kimlik Doğrulama | Servis hesabı JSON anahtarı + env değişken | Lisans anahtarı dizesi |
| PDF girdisi | GCS'ye Yükleme + asenkron API | input.LoadPdf() doğrudan |
| Şifre korumalı PDF | Desteklenmiyor | LoadPdf(path, Password: "...") |
| Çok sayfalı TIFF girişi | Sınırlı | input.LoadImageFrames() |
| Aranabilir PDF çıktısı | Mevcut değil | result.SaveAsSearchablePdf() |
| Yapılandırılmış veri erişimi | Protobuf: Sayfalar > Bloklar > Paragraflar > Kelimeler > Semboller | result.Paragraphs, result.Lines, result.Words (türlenmiş .NET nesneleri) |
| Paragraf metin özelliği | Hayır — sembol birleştirmesi gerekiyor | paragraph.Text doğrudan özellik |
| Güven skoru | Sembol başına (döngü gerekiyor) | result.Confidence, word.Confidence |
| Otomatik görüntü ön işleme | Hiçbiri (ML bunu ele alır) | Deskew, DeNoise, Karşıtlık, İkili, Keskinleştir |
| Bölge bazlı OCR | Yerel kırpma yok | CropRectangle üzerinde OcrInput |
| Barkod okuma | Ayrı API özelliği | ocr.Configuration.ReadBarCodes = true |
| Oran sınırlamaları | 1.800 istek/dakika varsayılan | Yok (CPU'ya bağlı) |
| Çevrimdışı / izole | Hayır | Evet |
| Belge başına maliyet | 1.000 resim başına $1.50; $0.0015/PDF sayfa | Hiçbiri (süresiz lisans) |
| Desteklenen diller | ~50 | 125+ |
| FedRAMP yetkilendirmesi | Yetkilendirilmemiş | Uygulanmaz (yerinde) |
| HIPAA uyumluluk yolu | İş Ortağı Sözleşmesi gerekli | Üçüncü taraf veri işleme yok |
| .NET Framework desteği | .NET Standard 2.0+ | .NET Framework 4.6.2+ ve .NET 5/6/7/8/9 |
| NuGet paketleri gerekli | Google.Cloud.Vision.V1 + Google.Cloud.Storage.V1 |
IronOcr yalnızca |
| Fiyatlandırma modeli | Başına istek ölçümlü faturalandırma | Perpetual ($999 Lite / $1,499 Plus / $2,999 Professional / $5,999 Unlimited) |
Hızlı Başlangıç:Google Cloud VisionOCR'den IronOCR'ye Geçiş
Adım 1: NuGet Paketini Değiştirin
Google Cloud paketlerini kaldırın:
dotnet remove package Google.Cloud.Vision.V1
dotnet remove package Google.Cloud.Storage.V1
dotnet remove package Google.Cloud.Vision.V1
dotnet remove package Google.Cloud.Storage.V1
NuGet paketi sayfasından IronOCR yükleyin:
dotnet add package IronOcr
Adım 2: Ad Alanlarını Güncelleyin
Google Cloud ad alanlarınıIronOCR ad alanı ile değiştirin:
// Before (Google Cloud Vision)
using Google.Cloud.Vision.V1;
using Google.Cloud.Storage.V1;
using Google.Protobuf;
using Grpc.Core;
// After (IronOCR)
using IronOcr;
// Before (Google Cloud Vision)
using Google.Cloud.Vision.V1;
using Google.Cloud.Storage.V1;
using Google.Protobuf;
using Grpc.Core;
// After (IronOCR)
using IronOcr;
Imports IronOcr
Adım 3: Lisansa İzin Verin
Lisans başlatma işlemini uygulama başlangıcında, herhangi bir IronTesseract örneği oluşturulmadan önce bir kere ekleyin:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Üretimde, anahtarı bir ortam değişkeninden veya sır yöneticiden okuyun:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
?? throw new InvalidOperationException("IRONOCR_LICENSE environment variable not set.");
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
?? throw new InvalidOperationException("IRONOCR_LICENSE environment variable not set.");
Imports System
Imports IronOcr
IronOcr.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONOCR_LICENSE"), Throw New InvalidOperationException("IRONOCR_LICENSE environment variable not set."))
Kod Göç Örnekleri
Servis Hesabı Kimlik Bilgileri Yapılandırmasını Ortadan Kaldırma
Google Cloud Vision istemci başlatması tek bir satır gibi görünse de, kapsamlı ön gereklilik altyapısı gerektirir. Projeye katılan her geliştirici, her dağıtım ortamı ve her CI/CD hattının yapılandırıcı tamamlanmadan ve hata atmadan önce tam kimlik bilgisi yapılandırmasına sahip olması gerekir.
Google Cloud Vision Yaklaşımı:
using Google.Cloud.Vision.V1;
// Prerequisites before this class can be instantiated:
// 1. GCP project created and Vision API enabled in GCP Console
// 2. Service account created with roles/cloudvision.user IAM role
// 3. JSON key file downloaded to every server that runs this code
// 4. GOOGLE_APPLICATION_CREDENTIALS env var pointing to the JSON file
// 5. JSON file excluded from source control via .gitignore
// 6. Key rotation schedule established (recommended: 90 days)
// 7. Separate credentials per environment (dev/staging/prod)
public class DocumentOcrService
{
private readonly ImageAnnotatorClient _client;
private readonly string _projectId;
public DocumentOcrService(string projectId)
{
_projectId = projectId;
// Throws RpcException(StatusCode.PermissionDenied) if any prerequisite is missing
_client = ImageAnnotatorClient.Create();
}
public string ReadDocument(string imagePath)
{
var image = Image.FromFile(imagePath);
var response = _client.DetectText(image);
return response.Count > 0 ? response[0].Description : string.Empty;
}
}
using Google.Cloud.Vision.V1;
// Prerequisites before this class can be instantiated:
// 1. GCP project created and Vision API enabled in GCP Console
// 2. Service account created with roles/cloudvision.user IAM role
// 3. JSON key file downloaded to every server that runs this code
// 4. GOOGLE_APPLICATION_CREDENTIALS env var pointing to the JSON file
// 5. JSON file excluded from source control via .gitignore
// 6. Key rotation schedule established (recommended: 90 days)
// 7. Separate credentials per environment (dev/staging/prod)
public class DocumentOcrService
{
private readonly ImageAnnotatorClient _client;
private readonly string _projectId;
public DocumentOcrService(string projectId)
{
_projectId = projectId;
// Throws RpcException(StatusCode.PermissionDenied) if any prerequisite is missing
_client = ImageAnnotatorClient.Create();
}
public string ReadDocument(string imagePath)
{
var image = Image.FromFile(imagePath);
var response = _client.DetectText(image);
return response.Count > 0 ? response[0].Description : string.Empty;
}
}
Imports Google.Cloud.Vision.V1
' Prerequisites before this class can be instantiated:
' 1. GCP project created and Vision API enabled in GCP Console
' 2. Service account created with roles/cloudvision.user IAM role
' 3. JSON key file downloaded to every server that runs this code
' 4. GOOGLE_APPLICATION_CREDENTIALS env var pointing to the JSON file
' 5. JSON file excluded from source control via .gitignore
' 6. Key rotation schedule established (recommended: 90 days)
' 7. Separate credentials per environment (dev/staging/prod)
Public Class DocumentOcrService
Private ReadOnly _client As ImageAnnotatorClient
Private ReadOnly _projectId As String
Public Sub New(projectId As String)
_projectId = projectId
' Throws RpcException(StatusCode.PermissionDenied) if any prerequisite is missing
_client = ImageAnnotatorClient.Create()
End Sub
Public Function ReadDocument(imagePath As String) As String
Dim image = Image.FromFile(imagePath)
Dim response = _client.DetectText(image)
Return If(response.Count > 0, response(0).Description, String.Empty)
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
// Prerequisites: set the license key once at app startup
//HayırJSON files, no environment variables beyond the key, no GCP Console configuration
//Hayırkey rotation, no IAM roles, no per-environment credential sets
public class DocumentOcrService
{
private readonly IronTesseract _ocr;
public DocumentOcrService()
{
// IronTesseract is ready immediately — no external validation required
_ocr = new IronTesseract();
}
public string ReadDocument(string imagePath)
{
return _ocr.Read(imagePath).Text;
}
}
using IronOcr;
// Prerequisites: set the license key once at app startup
//HayırJSON files, no environment variables beyond the key, no GCP Console configuration
//Hayırkey rotation, no IAM roles, no per-environment credential sets
public class DocumentOcrService
{
private readonly IronTesseract _ocr;
public DocumentOcrService()
{
// IronTesseract is ready immediately — no external validation required
_ocr = new IronTesseract();
}
public string ReadDocument(string imagePath)
{
return _ocr.Read(imagePath).Text;
}
}
Imports IronOcr
' Prerequisites: set the license key once at app startup
' HayırJSON files, no environment variables beyond the key, no GCP Console configuration
' Hayırkey rotation, no IAM roles, no per-environment credential sets
Public Class DocumentOcrService
Private ReadOnly _ocr As IronTesseract
Public Sub New()
' IronTesseract is ready immediately — no external validation required
_ocr = New IronTesseract()
End Sub
Public Function ReadDocument(imagePath As String) As String
Return _ocr.Read(imagePath).Text
End Function
End Class
İşlevsel fark somuttur:Google Cloud Visionçalışma zamanında beş RpcException kategorisi oluşturur — PermissionDenied, ResourceExhausted, Unavailable, DeadlineExceeded ve Unauthenticated — her biri farklı bir altyapı arızası modunu temsil eder. IronOCR'nin hata modları IOException (dosya bulunamadı veya kilitli) ve OcrException (işleme hatası) 'dır. IronTesseract kurulum kılavuzu için yapılandırma seçenekleri ve IronOCR ürün sayfasına bakın.
Çoklu Özellik Türleriyle Toplu Açıklama İsteklerini Değiştirme
Google Cloud Vision, birden fazla görüntüyü tek bir BatchAnnotateImagesRequest içine toplu işlemeyi destekler, her görüntü Feature türleri listesiyle yapılandırılmıştır. Bu model, bir aramada hem TEXT_DETECTION hem de DOCUMENT_TEXT_DETECTION sonuçlarını toplamak gerektiğinde veya bir gezinmesiz yükleme overhead'ini en aza indirmek için birçok görüntü gönderildiğinde kullanılır. Protobuf yanıtı, her AnnotateImageResponse'i kendi orijinal isteğine indeksle eşleştirmesini gerektirir.
Google Cloud Vision Yaklaşımı:
using Google.Cloud.Vision.V1;
using System.Collections.Generic;
public class BatchAnnotationService
{
private readonly ImageAnnotatorClient _client;
public BatchAnnotationService()
{
_client = ImageAnnotatorClient.Create();
}
public List<string> BatchAnnotateImages(string[] imagePaths)
{
// Build one request per image with TEXT_DETECTION feature
var requests = imagePaths.Select(path => new AnnotateImageRequest
{
Image = Image.FromFile(path),
Features =
{
new Feature { Type = Feature.Types.Type.TextDetection },
new Feature { Type = Feature.Types.Type.DocumentTextDetection }
}
}).ToList();
// Single round-trip for all images in the batch
var batchResponse = _client.BatchAnnotateImages(requests);
// Match responses back to requests by index
var results = new List<string>();
for (int i = 0; i < batchResponse.Responses.Count; i++)
{
var response = batchResponse.Responses[i];
if (response.Error != null)
{
// Per-item error in batch — must handle individually
results.Add($"Error on {imagePaths[i]}: {response.Error.Message}");
continue;
}
// Prefer DOCUMENT_TEXT_DETECTION full text if available
var fullText = response.FullTextAnnotation?.Text
?? response.TextAnnotations.FirstOrDefault()?.Description
?? string.Empty;
results.Add(fullText);
}
return results;
}
}
using Google.Cloud.Vision.V1;
using System.Collections.Generic;
public class BatchAnnotationService
{
private readonly ImageAnnotatorClient _client;
public BatchAnnotationService()
{
_client = ImageAnnotatorClient.Create();
}
public List<string> BatchAnnotateImages(string[] imagePaths)
{
// Build one request per image with TEXT_DETECTION feature
var requests = imagePaths.Select(path => new AnnotateImageRequest
{
Image = Image.FromFile(path),
Features =
{
new Feature { Type = Feature.Types.Type.TextDetection },
new Feature { Type = Feature.Types.Type.DocumentTextDetection }
}
}).ToList();
// Single round-trip for all images in the batch
var batchResponse = _client.BatchAnnotateImages(requests);
// Match responses back to requests by index
var results = new List<string>();
for (int i = 0; i < batchResponse.Responses.Count; i++)
{
var response = batchResponse.Responses[i];
if (response.Error != null)
{
// Per-item error in batch — must handle individually
results.Add($"Error on {imagePaths[i]}: {response.Error.Message}");
continue;
}
// Prefer DOCUMENT_TEXT_DETECTION full text if available
var fullText = response.FullTextAnnotation?.Text
?? response.TextAnnotations.FirstOrDefault()?.Description
?? string.Empty;
results.Add(fullText);
}
return results;
}
}
Imports Google.Cloud.Vision.V1
Imports System.Collections.Generic
Imports System.Linq
Public Class BatchAnnotationService
Private ReadOnly _client As ImageAnnotatorClient
Public Sub New()
_client = ImageAnnotatorClient.Create()
End Sub
Public Function BatchAnnotateImages(imagePaths As String()) As List(Of String)
' Build one request per image with TEXT_DETECTION feature
Dim requests = imagePaths.Select(Function(path) New AnnotateImageRequest With {
.Image = Image.FromFile(path),
.Features = {
New Feature With {.Type = Feature.Types.Type.TextDetection},
New Feature With {.Type = Feature.Types.Type.DocumentTextDetection}
}
}).ToList()
' Single round-trip for all images in the batch
Dim batchResponse = _client.BatchAnnotateImages(requests)
' Match responses back to requests by index
Dim results = New List(Of String)()
For i As Integer = 0 To batchResponse.Responses.Count - 1
Dim response = batchResponse.Responses(i)
If response.Error IsNot Nothing Then
' Per-item error in batch — must handle individually
results.Add($"Error on {imagePaths(i)}: {response.Error.Message}")
Continue For
End If
' Prefer DOCUMENT_TEXT_DETECTION full text if available
Dim fullText = If(response.FullTextAnnotation?.Text, response.TextAnnotations.FirstOrDefault()?.Description, String.Empty)
results.Add(fullText)
Next
Return results
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
public class BatchAnnotationService
{
public List<string> BatchAnnotateImages(string[] imagePaths)
{
var results = new ConcurrentDictionary<int, string>();
// Parallel processing — no batch size limit, no network round-trips
Parallel.For(0, imagePaths.Length, i =>
{
var ocr = new IronTesseract(); // thread-safe: one instance per thread
results[i] = ocr.Read(imagePaths[i]).Text;
});
// Reconstruct in original order
return Enumerable.Range(0, imagePaths.Length)
.Select(i => results[i])
.ToList();
}
public OcrResult BatchAsDocument(string[] imagePaths)
{
// Load all images into a single OcrInput for combined document output
using var input = new OcrInput();
foreach (var path in imagePaths)
input.LoadImage(path);
return new IronTesseract().Read(input);
}
}
using IronOcr;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
public class BatchAnnotationService
{
public List<string> BatchAnnotateImages(string[] imagePaths)
{
var results = new ConcurrentDictionary<int, string>();
// Parallel processing — no batch size limit, no network round-trips
Parallel.For(0, imagePaths.Length, i =>
{
var ocr = new IronTesseract(); // thread-safe: one instance per thread
results[i] = ocr.Read(imagePaths[i]).Text;
});
// Reconstruct in original order
return Enumerable.Range(0, imagePaths.Length)
.Select(i => results[i])
.ToList();
}
public OcrResult BatchAsDocument(string[] imagePaths)
{
// Load all images into a single OcrInput for combined document output
using var input = new OcrInput();
foreach (var path in imagePaths)
input.LoadImage(path);
return new IronTesseract().Read(input);
}
}
Imports IronOcr
Imports System.Collections.Concurrent
Imports System.Collections.Generic
Imports System.Threading.Tasks
Public Class BatchAnnotationService
Public Function BatchAnnotateImages(imagePaths As String()) As List(Of String)
Dim results = New ConcurrentDictionary(Of Integer, String)()
' Parallel processing — no batch size limit, no network round-trips
Parallel.For(0, imagePaths.Length, Sub(i)
Dim ocr = New IronTesseract() ' thread-safe: one instance per thread
results(i) = ocr.Read(imagePaths(i)).Text
End Sub)
' Reconstruct in original order
Return Enumerable.Range(0, imagePaths.Length) _
.Select(Function(i) results(i)) _
.ToList()
End Function
Public Function BatchAsDocument(imagePaths As String()) As OcrResult
' Load all images into a single OcrInput for combined document output
Using input As New OcrInput()
For Each path In imagePaths
input.LoadImage(path)
Next
Return New IronTesseract().Read(input)
End Using
End Function
End Class
IronOCR, toplu işlemi CPU çekirdekleri boyunca ağ yükü olmaksızın paralel hale getirir. Geri çekilme sınırı, yanıt-indeks eşleştirmesi ve ağ veya kimlik bilgisi hataları için madde başına hata işleme yok. Birden çok görüntüyü tek bir mantıksal belgede birleştiren işler için — bireysel JPEG'ler olarak gönderilen taranmış çok sayfalı formlar gibi — BatchAsDocument tüm görüntüleri bir OcrInput içerisine yükler ve OcrResult birleştirilmiş bir dönüş yapar, her bir giriş görüntüsüne indekslenmiş result.Pages ile. Çoklu iş parçacığı örneği, paralel işleme için performans ölçütlerini gösterir.
Protobuf Kelime Düzeyi Ek Açıklama Çıkarımı Geçişi
Google Cloud Vision'ın kelime düzeyi sınırlayıcı kutusu ve güven verileri, tam Protobuf hiyerarşisini dolaşmayı gerektirir: Sayfalar, ardından Bloklar, ardından Paragraflar, ardından Kelimeler, ardından Semboller. Kelime metnini çıkarmak, her Kelime'den Sembolleri birleştirmeyi gerektirir — Word nesnesi doğrudan .Text özelliğine sahip değildir. Sınır kutusu koordinatları, ayrı X, Y, Genislik, Yükseklik alanları yerine bir BoundingPoly ve Vertices listesinin bir bileşeni olarak saklanır.
Google Cloud Vision Yaklaşımı:
using Google.Cloud.Vision.V1;
using System.Collections.Generic;
public record WordAnnotation(string Text, int X, int Y, int Width, int Height, float Confidence);
public class WordLevelExtractor
{
private readonly ImageAnnotatorClient _client;
public WordLevelExtractor()
{
_client = ImageAnnotatorClient.Create();
}
public List<WordAnnotation> ExtractWordAnnotations(string imagePath)
{
var image = Image.FromFile(imagePath);
var annotation = _client.DetectDocumentText(image);
var words = new List<WordAnnotation>();
// Navigate: Pages -> Blocks -> Paragraphs -> Words
foreach (var page in annotation.Pages)
{
foreach (var block in page.Blocks)
{
foreach (var paragraph in block.Paragraphs)
{
foreach (var word in paragraph.Words)
{
// Word.Text does not exist — must concatenate Symbols
var text = string.Concat(word.Symbols.Select(s => s.Text));
// BoundingPoly has Vertices, not X/Y/Width/Height
var vertices = word.BoundingBox.Vertices;
int x = vertices[0].X;
int y = vertices[0].Y;
int width = vertices.Count > 1 ? vertices[1].X - vertices[0].X : 0;
int height = vertices.Count > 2 ? vertices[2].Y - vertices[0].Y : 0;
words.Add(new WordAnnotation(text, x, y, width, height, word.Confidence));
}
}
}
}
return words;
}
}
using Google.Cloud.Vision.V1;
using System.Collections.Generic;
public record WordAnnotation(string Text, int X, int Y, int Width, int Height, float Confidence);
public class WordLevelExtractor
{
private readonly ImageAnnotatorClient _client;
public WordLevelExtractor()
{
_client = ImageAnnotatorClient.Create();
}
public List<WordAnnotation> ExtractWordAnnotations(string imagePath)
{
var image = Image.FromFile(imagePath);
var annotation = _client.DetectDocumentText(image);
var words = new List<WordAnnotation>();
// Navigate: Pages -> Blocks -> Paragraphs -> Words
foreach (var page in annotation.Pages)
{
foreach (var block in page.Blocks)
{
foreach (var paragraph in block.Paragraphs)
{
foreach (var word in paragraph.Words)
{
// Word.Text does not exist — must concatenate Symbols
var text = string.Concat(word.Symbols.Select(s => s.Text));
// BoundingPoly has Vertices, not X/Y/Width/Height
var vertices = word.BoundingBox.Vertices;
int x = vertices[0].X;
int y = vertices[0].Y;
int width = vertices.Count > 1 ? vertices[1].X - vertices[0].X : 0;
int height = vertices.Count > 2 ? vertices[2].Y - vertices[0].Y : 0;
words.Add(new WordAnnotation(text, x, y, width, height, word.Confidence));
}
}
}
}
return words;
}
}
Imports Google.Cloud.Vision.V1
Imports System.Collections.Generic
Imports System.Linq
Public Class WordAnnotation
Public Property Text As String
Public Property X As Integer
Public Property Y As Integer
Public Property Width As Integer
Public Property Height As Integer
Public Property Confidence As Single
Public Sub New(text As String, x As Integer, y As Integer, width As Integer, height As Integer, confidence As Single)
Me.Text = text
Me.X = x
Me.Y = y
Me.Width = width
Me.Height = height
Me.Confidence = confidence
End Sub
End Class
Public Class WordLevelExtractor
Private ReadOnly _client As ImageAnnotatorClient
Public Sub New()
_client = ImageAnnotatorClient.Create()
End Sub
Public Function ExtractWordAnnotations(imagePath As String) As List(Of WordAnnotation)
Dim image = Image.FromFile(imagePath)
Dim annotation = _client.DetectDocumentText(image)
Dim words As New List(Of WordAnnotation)()
' Navigate: Pages -> Blocks -> Paragraphs -> Words
For Each page In annotation.Pages
For Each block In page.Blocks
For Each paragraph In block.Paragraphs
For Each word In paragraph.Words
' Word.Text does not exist — must concatenate Symbols
Dim text = String.Concat(word.Symbols.Select(Function(s) s.Text))
' BoundingPoly has Vertices, not X/Y/Width/Height
Dim vertices = word.BoundingBox.Vertices
Dim x As Integer = vertices(0).X
Dim y As Integer = vertices(0).Y
Dim width As Integer = If(vertices.Count > 1, vertices(1).X - vertices(0).X, 0)
Dim height As Integer = If(vertices.Count > 2, vertices(2).Y - vertices(0).Y, 0)
words.Add(New WordAnnotation(text, x, y, width, height, word.Confidence))
Next
Next
Next
Next
Return words
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
using System.Collections.Generic;
public record WordAnnotation(string Text, int X, int Y, int Width, int Height, double Confidence);
public class WordLevelExtractor
{
private readonly IronTesseract _ocr;
public WordLevelExtractor()
{
_ocr = new IronTesseract();
}
public List<WordAnnotation> ExtractWordAnnotations(string imagePath)
{
var result = _ocr.Read(imagePath);
// Words are a flat collection — no hierarchy traversal, no symbol concatenation
return result.Words.Select(w => new WordAnnotation(
Text: w.Text, // direct string property
X: w.X,
Y: w.Y,
Width: w.Width,
Height: w.Height,
Confidence: w.Confidence // double, no conversion needed
)).ToList();
}
}
using IronOcr;
using System.Collections.Generic;
public record WordAnnotation(string Text, int X, int Y, int Width, int Height, double Confidence);
public class WordLevelExtractor
{
private readonly IronTesseract _ocr;
public WordLevelExtractor()
{
_ocr = new IronTesseract();
}
public List<WordAnnotation> ExtractWordAnnotations(string imagePath)
{
var result = _ocr.Read(imagePath);
// Words are a flat collection — no hierarchy traversal, no symbol concatenation
return result.Words.Select(w => new WordAnnotation(
Text: w.Text, // direct string property
X: w.X,
Y: w.Y,
Width: w.Width,
Height: w.Height,
Confidence: w.Confidence // double, no conversion needed
)).ToList();
}
}
Imports IronOcr
Imports System.Collections.Generic
Public Class WordAnnotation
Public Property Text As String
Public Property X As Integer
Public Property Y As Integer
Public Property Width As Integer
Public Property Height As Integer
Public Property Confidence As Double
Public Sub New(text As String, x As Integer, y As Integer, width As Integer, height As Integer, confidence As Double)
Me.Text = text
Me.X = x
Me.Y = y
Me.Width = width
Me.Height = height
Me.Confidence = confidence
End Sub
End Class
Public Class WordLevelExtractor
Private ReadOnly _ocr As IronTesseract
Public Sub New()
_ocr = New IronTesseract()
End Sub
Public Function ExtractWordAnnotations(imagePath As String) As List(Of WordAnnotation)
Dim result = _ocr.Read(imagePath)
' Words are a flat collection — no hierarchy traversal, no symbol concatenation
Return result.Words.Select(Function(w) New WordAnnotation(
Text:=w.Text, ' direct string property
X:=w.X,
Y:=w.Y,
Width:=w.Width,
Height:=w.Height,
Confidence:=w.Confidence ' double, no conversion needed
)).ToList()
End Function
End Class
Google Cloud Vision sürümündeki sembol birleştirme döngüsü bir tasarım seçimi değildir — Protobuf şemasının bir gereğidir. Word.Text, yanıt nesnesinde bir özellik değildir. Kelime düzeyindeki API'yi kullanan her ekip eşdeğer bir döngü yazar. IronOCR'nin OcrResult.Words koleksiyonu Text, X, Y, Width, Height ve Confidence'i birinci sınıf özellikler olarak ortaya çıkarır. Sonuçları okuma kılavuzu, her ayrıntı seviyesinde mevcut olan tam özellik setini belgeler.
Aynı anda birden fazla sayfalı TIFF İşleme işlemi ile Aranabilir PDF Çıkışı
Google Cloud Vision çok sayfalı TIFF dosyalarını, ayrı ayrı bir API çağrısı gerektiren bir dizi görüntü olarak ele alır. Tüm kareler için yapılandırılmış çıktı döndüren tek bir API çağrısı bulunmamaktadır.Google Cloud Visionsonuçlarından aranabilir bir PDF üretmek, ayrı bir PDF oluşturma kütüphanesi gerektirir - API yalnızca metin döndürür.
Google Cloud Vision Yaklaşımı:
using Google.Cloud.Vision.V1;
using System.Collections.Generic;
using System.Drawing; // for TIFF frame extraction
using System.Drawing.Imaging;
public class TiffProcessingService
{
private readonly ImageAnnotatorClient _client;
public TiffProcessingService()
{
_client = ImageAnnotatorClient.Create();
}
public List<string> ProcessMultiPageTiff(string tiffPath)
{
var pageTexts = new List<string>();
// Load TIFF and extract frames manually using System.Drawing
using var tiff = System.Drawing.Image.FromFile(tiffPath);
var frameDimension = new FrameDimension(tiff.FrameDimensionsList[0]);
int frameCount = tiff.GetFrameCount(frameDimension);
for (int i = 0; i < frameCount; i++)
{
tiff.SelectActiveFrame(frameDimension, i);
// Save each frame to a temp file — Vision API does not accept TIFF frames directly
var tempPath = Path.Combine(Path.GetTempPath(), $"tiff-frame-{i}.jpg");
tiff.Save(tempPath, ImageFormat.Jpeg);
// One API call per frame — each call = one unit of quota
var visionImage = Google.Cloud.Vision.V1.Image.FromFile(tempPath);
var response = _client.DetectText(visionImage);
pageTexts.Add(response.FirstOrDefault()?.Description ?? string.Empty);
File.Delete(tempPath);
}
// Producing a searchable PDF requires a separate library (e.g., iTextSharp)
//Google Cloud Visionhas no PDF output capability
return pageTexts;
}
}
using Google.Cloud.Vision.V1;
using System.Collections.Generic;
using System.Drawing; // for TIFF frame extraction
using System.Drawing.Imaging;
public class TiffProcessingService
{
private readonly ImageAnnotatorClient _client;
public TiffProcessingService()
{
_client = ImageAnnotatorClient.Create();
}
public List<string> ProcessMultiPageTiff(string tiffPath)
{
var pageTexts = new List<string>();
// Load TIFF and extract frames manually using System.Drawing
using var tiff = System.Drawing.Image.FromFile(tiffPath);
var frameDimension = new FrameDimension(tiff.FrameDimensionsList[0]);
int frameCount = tiff.GetFrameCount(frameDimension);
for (int i = 0; i < frameCount; i++)
{
tiff.SelectActiveFrame(frameDimension, i);
// Save each frame to a temp file — Vision API does not accept TIFF frames directly
var tempPath = Path.Combine(Path.GetTempPath(), $"tiff-frame-{i}.jpg");
tiff.Save(tempPath, ImageFormat.Jpeg);
// One API call per frame — each call = one unit of quota
var visionImage = Google.Cloud.Vision.V1.Image.FromFile(tempPath);
var response = _client.DetectText(visionImage);
pageTexts.Add(response.FirstOrDefault()?.Description ?? string.Empty);
File.Delete(tempPath);
}
// Producing a searchable PDF requires a separate library (e.g., iTextSharp)
//Google Cloud Visionhas no PDF output capability
return pageTexts;
}
}
Imports Google.Cloud.Vision.V1
Imports System.Collections.Generic
Imports System.Drawing ' for TIFF frame extraction
Imports System.Drawing.Imaging
Imports System.IO
Public Class TiffProcessingService
Private ReadOnly _client As ImageAnnotatorClient
Public Sub New()
_client = ImageAnnotatorClient.Create()
End Sub
Public Function ProcessMultiPageTiff(tiffPath As String) As List(Of String)
Dim pageTexts As New List(Of String)()
' Load TIFF and extract frames manually using System.Drawing
Using tiff As System.Drawing.Image = System.Drawing.Image.FromFile(tiffPath)
Dim frameDimension As New FrameDimension(tiff.FrameDimensionsList(0))
Dim frameCount As Integer = tiff.GetFrameCount(frameDimension)
For i As Integer = 0 To frameCount - 1
tiff.SelectActiveFrame(frameDimension, i)
' Save each frame to a temp file — Vision API does not accept TIFF frames directly
Dim tempPath As String = Path.Combine(Path.GetTempPath(), $"tiff-frame-{i}.jpg")
tiff.Save(tempPath, ImageFormat.Jpeg)
' One API call per frame — each call = one unit of quota
Dim visionImage As Google.Cloud.Vision.V1.Image = Google.Cloud.Vision.V1.Image.FromFile(tempPath)
Dim response = _client.DetectText(visionImage)
pageTexts.Add(If(response.FirstOrDefault()?.Description, String.Empty))
File.Delete(tempPath)
Next
End Using
' Producing a searchable PDF requires a separate library (e.g., iTextSharp)
' Google Cloud Vision has no PDF output capability
Return pageTexts
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
public class TiffProcessingService
{
private readonly IronTesseract _ocr;
public TiffProcessingService()
{
_ocr = new IronTesseract();
}
public string ProcessMultiPageTiff(string tiffPath)
{
using var input = new OcrInput();
// LoadImageFrames handles all TIFF frames in one call — no temp files, no frame loop
input.LoadImageFrames(tiffPath);
var result = _ocr.Read(input);
return result.Text;
}
public void ProcessMultiPageTiffToSearchablePdf(string tiffPath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath);
var result = _ocr.Read(input);
//Google Cloud Visionhas no equivalent — this single call produces a searchable PDF
result.SaveAsSearchablePdf(outputPdfPath);
}
public void ProcessLowQualityTiff(string tiffPath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath);
// Preprocessing before OCR improves accuracy on degraded scans
input.Deskew();
input.DeNoise();
input.Contrast();
var result = _ocr.Read(input);
result.SaveAsSearchablePdf(outputPdfPath);
}
}
using IronOcr;
public class TiffProcessingService
{
private readonly IronTesseract _ocr;
public TiffProcessingService()
{
_ocr = new IronTesseract();
}
public string ProcessMultiPageTiff(string tiffPath)
{
using var input = new OcrInput();
// LoadImageFrames handles all TIFF frames in one call — no temp files, no frame loop
input.LoadImageFrames(tiffPath);
var result = _ocr.Read(input);
return result.Text;
}
public void ProcessMultiPageTiffToSearchablePdf(string tiffPath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath);
var result = _ocr.Read(input);
//Google Cloud Visionhas no equivalent — this single call produces a searchable PDF
result.SaveAsSearchablePdf(outputPdfPath);
}
public void ProcessLowQualityTiff(string tiffPath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath);
// Preprocessing before OCR improves accuracy on degraded scans
input.Deskew();
input.DeNoise();
input.Contrast();
var result = _ocr.Read(input);
result.SaveAsSearchablePdf(outputPdfPath);
}
}
Imports IronOcr
Public Class TiffProcessingService
Private ReadOnly _ocr As IronTesseract
Public Sub New()
_ocr = New IronTesseract()
End Sub
Public Function ProcessMultiPageTiff(tiffPath As String) As String
Using input As New OcrInput()
' LoadImageFrames handles all TIFF frames in one call — no temp files, no frame loop
input.LoadImageFrames(tiffPath)
Dim result = _ocr.Read(input)
Return result.Text
End Using
End Function
Public Sub ProcessMultiPageTiffToSearchablePdf(tiffPath As String, outputPdfPath As String)
Using input As New OcrInput()
input.LoadImageFrames(tiffPath)
Dim result = _ocr.Read(input)
' Google Cloud Vision has no equivalent — this single call produces a searchable PDF
result.SaveAsSearchablePdf(outputPdfPath)
End Using
End Sub
Public Sub ProcessLowQualityTiff(tiffPath As String, outputPdfPath As String)
Using input As New OcrInput()
input.LoadImageFrames(tiffPath)
' Preprocessing before OCR improves accuracy on degraded scans
input.Deskew()
input.DeNoise()
input.Contrast()
Dim result = _ocr.Read(input)
result.SaveAsSearchablePdf(outputPdfPath)
End Using
End Sub
End Class
Google Cloud Vision sürümü, kare çıkarımı için System.Drawing gerektirir, geçici JPEG dosyaları diskte yazılır, her kare başına bir API çağrısı (kare sayısına orantılı kota tüketimi) ve düz metnin ötesinde herhangi bir çıktı üretmek için ayrı bir PDF kütüphanesi gerektirir. IronOCR, çok çerçeveli TIFF'leri LoadImageFrames aracılığıyla yerel olarak işler, tüm kareleri tek bir Read çağrısında işler ve SaveAsSearchablePdf aracılığıyla aranabilir PDF çıktısı üretir. Tarayıcıydan gelen arşivlenmiş TIFF belgeleri için, ProcessLowQualityTiff'ndeki ön işleme boru hattı, tek bir geçişte en yaygın kalite sorunlarını çözer. Tam API için TIFF ve GIF girdisi ve aranabilir PDF çıktısı sekmelerine bakın.
İlerlemenin Takip Edildiği Kota Sınırlamalı Toplu Geçiş
Üretim ölçeğinde, Google Cloud Vision'ın dakikada 1.800 istek için varsayılan kotası, ya sınırlamayı ya da katlanarak geri çekilmeyle yeniden deneme mantığını gerektirir. 5.000 belgeyi tek seferde işlemek, kotayı birden fazla kez aşacaktır. Her kota aşımı, hattı zorunlu 60 saniyelik bir bekleme süresi için engeller. IronOCR'nin hız sınırlandırması yoktur — boru hattı sadece CPU çekirdekleri ve mevcut iş parçacıkları ile sınırlıdır.
Google Cloud Vision Yaklaşımı:
using Google.Cloud.Vision.V1;
using Grpc.Core;
using System.Collections.Generic;
public class ThrottledBatchProcessor
{
private readonly ImageAnnotatorClient _client;
private const int MaxRequestsPerMinute = 1800;
private const int RetryDelayMs = 60_000;
public ThrottledBatchProcessor()
{
_client = ImageAnnotatorClient.Create();
}
public async Task<Dictionary<string, string>> ProcessWithThrottlingAsync(
string[] imagePaths,
IProgress<(int completed, int total)> progress)
{
var results = new Dictionary<string, string>();
int completed = 0;
foreach (var path in imagePaths)
{
bool succeeded = false;
while (!succeeded)
{
try
{
var image = Google.Cloud.Vision.V1.Image.FromFile(path);
var response = _client.DetectText(image);
results[path] = response.FirstOrDefault()?.Description ?? string.Empty;
succeeded = true;
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.ResourceExhausted)
{
// Rate limit exceeded — wait and retry
await Task.Delay(RetryDelayMs);
}
}
progress.Report((++completed, imagePaths.Length));
}
return results;
}
}
using Google.Cloud.Vision.V1;
using Grpc.Core;
using System.Collections.Generic;
public class ThrottledBatchProcessor
{
private readonly ImageAnnotatorClient _client;
private const int MaxRequestsPerMinute = 1800;
private const int RetryDelayMs = 60_000;
public ThrottledBatchProcessor()
{
_client = ImageAnnotatorClient.Create();
}
public async Task<Dictionary<string, string>> ProcessWithThrottlingAsync(
string[] imagePaths,
IProgress<(int completed, int total)> progress)
{
var results = new Dictionary<string, string>();
int completed = 0;
foreach (var path in imagePaths)
{
bool succeeded = false;
while (!succeeded)
{
try
{
var image = Google.Cloud.Vision.V1.Image.FromFile(path);
var response = _client.DetectText(image);
results[path] = response.FirstOrDefault()?.Description ?? string.Empty;
succeeded = true;
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.ResourceExhausted)
{
// Rate limit exceeded — wait and retry
await Task.Delay(RetryDelayMs);
}
}
progress.Report((++completed, imagePaths.Length));
}
return results;
}
}
Imports Google.Cloud.Vision.V1
Imports Grpc.Core
Imports System.Collections.Generic
Imports System.Threading.Tasks
Public Class ThrottledBatchProcessor
Private ReadOnly _client As ImageAnnotatorClient
Private Const MaxRequestsPerMinute As Integer = 1800
Private Const RetryDelayMs As Integer = 60000
Public Sub New()
_client = ImageAnnotatorClient.Create()
End Sub
Public Async Function ProcessWithThrottlingAsync(
imagePaths As String(),
progress As IProgress(Of (completed As Integer, total As Integer))) As Task(Of Dictionary(Of String, String))
Dim results As New Dictionary(Of String, String)()
Dim completed As Integer = 0
For Each path In imagePaths
Dim succeeded As Boolean = False
While Not succeeded
Try
Dim image = Google.Cloud.Vision.V1.Image.FromFile(path)
Dim response = _client.DetectText(image)
results(path) = If(response.FirstOrDefault()?.Description, String.Empty)
succeeded = True
Catch ex As RpcException When ex.StatusCode = StatusCode.ResourceExhausted
' Rate limit exceeded — wait and retry
Await Task.Delay(RetryDelayMs)
End Try
End While
progress.Report((Threading.Interlocked.Increment(completed), imagePaths.Length))
Next
Return results
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class BatchProcessor
{
public Dictionary<string, string> ProcessBatch(
string[] imagePaths,
IProgress<(int completed, int total)> progress)
{
var results = new ConcurrentDictionary<string, string>();
int completed = 0;
//Hız sınırı yok— full parallelism, no retry logic needed
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract();
results[imagePath] = ocr.Read(imagePath).Text;
progress.Report((Interlocked.Increment(ref completed), imagePaths.Length));
});
return new Dictionary<string, string>(results);
}
public void ProcessBatchToSearchablePdfs(
string[] imagePaths,
string outputDirectory)
{
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
var outputPath = Path.Combine(
outputDirectory,
Path.GetFileNameWithoutExtension(imagePath) + "-searchable.pdf");
result.SaveAsSearchablePdf(outputPath);
});
}
}
using IronOcr;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class BatchProcessor
{
public Dictionary<string, string> ProcessBatch(
string[] imagePaths,
IProgress<(int completed, int total)> progress)
{
var results = new ConcurrentDictionary<string, string>();
int completed = 0;
//Hız sınırı yok— full parallelism, no retry logic needed
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract();
results[imagePath] = ocr.Read(imagePath).Text;
progress.Report((Interlocked.Increment(ref completed), imagePaths.Length));
});
return new Dictionary<string, string>(results);
}
public void ProcessBatchToSearchablePdfs(
string[] imagePaths,
string outputDirectory)
{
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
var outputPath = Path.Combine(
outputDirectory,
Path.GetFileNameWithoutExtension(imagePath) + "-searchable.pdf");
result.SaveAsSearchablePdf(outputPath);
});
}
}
Imports IronOcr
Imports System.Collections.Concurrent
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
Public Class BatchProcessor
Public Function ProcessBatch(imagePaths As String(), progress As IProgress(Of (completed As Integer, total As Integer))) As Dictionary(Of String, String)
Dim results As New ConcurrentDictionary(Of String, String)()
Dim completed As Integer = 0
'Hız sınırı yok— full parallelism, no retry logic needed
Parallel.ForEach(imagePaths, Sub(imagePath)
Dim ocr As New IronTesseract()
results(imagePath) = ocr.Read(imagePath).Text
progress.Report((Interlocked.Increment(completed), imagePaths.Length))
End Sub)
Return New Dictionary(Of String, String)(results)
End Function
Public Sub ProcessBatchToSearchablePdfs(imagePaths As String(), outputDirectory As String)
Parallel.ForEach(imagePaths, Sub(imagePath)
Dim ocr As New IronTesseract()
Dim result = ocr.Read(imagePath)
Dim outputPath = Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(imagePath) & "-searchable.pdf")
result.SaveAsSearchablePdf(outputPath)
End Sub)
End Sub
End Class
Google Cloud Vision sürümü sırasaldır çünkü paralel istekler hızı sınırını artıracaktır. Her ResourceExhausted istisnası, tam olarak 60 saniyelik bir durma sağlar. Kotaya 10 kez çarpan 5.000 belgeli bir parti, 10 dakika boş bekleme süresi ekler. IronOCR'nin versiyonu, kullanılabilir tüm çekirdekler arasında paralelleştirilerek beklemeden çalışır. Uzun süreli toplu işler için, ilerleme izleme API'si manuel Interlocked.Increment kurulum gerektirmeden yerleşik ilerleme geri çağrıları sağlar. Toplu taramalarda görüntü kalitesi sorunları için, görüntü kalitesi düzeltme kılavuzu, her Read çağrısından önce eklenebilecek ön işleme boru hattını kapsar.
Google Cloud Vision OCRAPI'sinden IronOCR'ye Haritalama Referansı
| Google Cloud Vision | IronOCR | Notlar |
|---|---|---|
ImageAnnotatorClient.Create() |
new IronTesseract() |
Müşteri başlatma; kimlik bilgisi dosyasına gerek yok |
Image.FromFile(path) |
_ocr.Read(path) veya input.LoadImage(path) |
Doğrudan yol okuma, IronTesseract üzerinde kullanılabilir |
_client.DetectText(image) |
_ocr.Read(path).Text |
TEXT_DETECTION eşdeğer |
_client.DetectDocumentText(image) |
_ocr.Read(path) |
DOCUMENT_TEXT_DETECTION eşdeğer; mod otomatik |
response[0].Description |
result.Text |
Tam belge metni |
TextAnnotation |
OcrResult |
Üst düzey sonuç konteyneri |
annotation.Text |
result.Text |
Tam metin dizisi |
annotation.Pages[i] |
result.Pages[i] |
Sayfa başına erişim |
page.Blocks[i].Paragraphs[j] |
result.Paragraphs[i] |
IronOCR paragrafları düz bir koleksiyon olarak sunar |
paragraph.Words.SelectMany(w => w.Symbols).Select(s => s.Text) |
paragraph.Text |
Doğrudan dize özelliği; sembol yinelemesi yok |
word.BoundingBox.Vertices |
word.X, word.Y, word.Width, word.Height |
Köşe listesi yerine bağımsız int özellikleri |
word.Confidence |
word.Confidence |
Kelime başına güven skoru |
page.Confidence |
result.Confidence |
Genel sonuç güveni |
Feature.Types.Type.DocumentTextDetection |
Otomatik | IronOCR işlem modunu otomatik seçer |
BatchAnnotateImagesRequest |
Parallel.ForEach + new IronTesseract() iş parçacığı başına |
Paralel yerel işleme; toplu boyut sınırlaması yok |
_client.BatchAnnotateImages(requests) |
new IronTesseract().Read(input) ile çoklu-görüntü OcrInput |
Çoklu görüntü girdisi için tek çağrı |
AsyncBatchAnnotateFilesAsync() |
input.LoadPdf(); _ocr.Read(input) |
PDF işleme senkronizasyondadır; GCS gerekli değil |
StorageClient.Create() |
Gerekli değil | GCS bağımlılığı yok |
storageClient.UploadObjectAsync() |
Gerekli değil | PDF'ler doğrudan yerel yoldan veya akıştan yüklenir |
operation.PollUntilCompletedAsync() |
Gerekli değil | İşleme senkronizedir |
RpcException (StatusCode.ResourceExhausted) |
Uygulanamaz | Hız sınırı yok |
RpcException (StatusCode.PermissionDenied) |
Uygulanamaz | Çalışma zamanı kimlik doğrulaması yok |
GOOGLE_APPLICATION_CREDENTIALS ortam değişkeni |
IronOcr.License.LicenseKey |
Dosya yolu değil, dize ataması |
Yaygın Göç Sorunları ve Çözümleri
Sorun 1: GOOGLE_APPLICATION_CREDENTIALS olmadan Yapıcı Atar
Google Cloud Vision: ImageAnnotatorClient.Create(), ortam değişkeni ayarlı değilse veya geçersiz bir dosyaya işaret ediyorsa, RpcException ile StatusCode.Unauthenticated veya StatusCode.PermissionDenied fırlatır. Bu hata başlangıçta meydana gelir, ilk API çağrısında değil, bu, herhangi bir ortamda kimlik bilgileri eksikse, tüm uygulamanın başlatılamayacağı anlamına gelir.
Çözüm:Google Cloud Visionpaketlerini kaldırdıktan sonra, ortam yapılandırmalarınızdan, CI/CD boru hattı gizli anahtarlarından, Kubernetes gizli anahtarlarından ve Docker Compose dosyalarından GOOGLE_APPLICATION_CREDENTIALS tüm referanslarını silin. Tek bir IRONOCR_LICENSE ortam değişkeni ile değiştirin:
// Remove this from every deployment environment:
// GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
// Add this once at application startup:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
?? throw new InvalidOperationException("IRONOCR_LICENSE environment variable is required.");
// Remove this from every deployment environment:
// GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
// Add this once at application startup:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
?? throw new InvalidOperationException("IRONOCR_LICENSE environment variable is required.");
' Remove this from every deployment environment:
' GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
' Add this once at application startup:
IronOcr.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONOCR_LICENSE"), Throw New InvalidOperationException("IRONOCR_LICENSE environment variable is required."))
Sorun 2: Ad Alanı Kaldırıldıktan Sonra Protobuf Sembol Birleştirme Kodu Bozulur
Google Cloud Vision: .SelectMany(w => w.Symbols).Select(s => s.Text) kullanılarak paragraf veya kelime metni çıkarılan kod tabanınızdaki her konum, Google.Cloud.Vision.V1 ad alanı kaldırıldıktan sonra derleme hataları üretecektir. Bu çağrılar, API yanıtını tüketen herhangi bir yardımcı veya servis sınıfına yayılmış durumdadır.
Çözüm: Kod tabanınızda tüm SelectMany ve w.Symbols desenlerini arayın ve bunlarıIronOCR sonuç nesneleri üzerinde doğrudan özellik erişimi ile değiştirin. sonuçları okuma kılavuzu, OcrResult, OcrResult.Page, OcrResult.Paragraph, OcrResult.Line ve OcrResult.Word üzerindeki mevcut her özelliği kapsar:
# Find all Protobuf symbol concatenation patterns
grep -rn "\.Symbols\." --include="*.cs" .
grep -rn "SelectMany.*Symbols" --include="*.cs" .
grep -rn "w\.Symbols\.Select" --include="*.cs" .
# Find all Protobuf symbol concatenation patterns
grep -rn "\.Symbols\." --include="*.cs" .
grep -rn "SelectMany.*Symbols" --include="*.cs" .
grep -rn "w\.Symbols\.Select" --include="*.cs" .
Her oluşumu değiştirin:
// Before: symbol concatenation required by Protobuf schema
var text = string.Join("", paragraph.Words.SelectMany(w => w.Symbols).Select(s => s.Text));
// After: direct property on OcrResult.Paragraph
var text = paragraph.Text;
// Before: symbol concatenation required by Protobuf schema
var text = string.Join("", paragraph.Words.SelectMany(w => w.Symbols).Select(s => s.Text));
// After: direct property on OcrResult.Paragraph
var text = paragraph.Text;
' Before: symbol concatenation required by Protobuf schema
Dim text = String.Join("", paragraph.Words.SelectMany(Function(w) w.Symbols).Select(Function(s) s.Text))
' After: direct property on OcrResult.Paragraph
Dim text = paragraph.Text
Sorun 3: Storage.V1 Kaldırıldıktan Sonra PDF İşleme Kodu Derlenmiyor
Google Cloud Vision: Google.Cloud.Storage.V1 kaldırıldıktan sonra, StorageClient, UploadObjectAsync, DeleteObjectAsync, AsyncAnnotateFileRequest, GcsSource, GcsDestination ve PollUntilCompletedAsync 'a başvuran tüm kodlar derlenemeyecektir. Bu kod birkaç hizmet sınıfı üzerinde yayılabilir ve genellikle tek en büyük değişiklik bloğunu temsil eder.
Çözüm: Tüm GCS hattını silin. 50'den fazla satırdan oluşan asenkron yöntemi IronOCR'nin üç satırlık eşdeğeri ile değiştirin. Çağırıcı uyumluluğu için asenkron bir imza koruyan kod için, Task.Run ile sarın:
// Delete: StorageClient, GCS upload, AsyncBatchAnnotateFilesAsync,
// PollUntilCompletedAsync, output download, DeleteObjectAsync
// Replace with:
public async Task<string> ProcessPdfAsync(string pdfPath)
{
return await Task.Run(() =>
{
using var input = new OcrInput();
input.LoadPdf(pdfPath);
return new IronTesseract().Read(input).Text;
});
}
// Delete: StorageClient, GCS upload, AsyncBatchAnnotateFilesAsync,
// PollUntilCompletedAsync, output download, DeleteObjectAsync
// Replace with:
public async Task<string> ProcessPdfAsync(string pdfPath)
{
return await Task.Run(() =>
{
using var input = new OcrInput();
input.LoadPdf(pdfPath);
return new IronTesseract().Read(input).Text;
});
}
Imports System.Threading.Tasks
Public Async Function ProcessPdfAsync(pdfPath As String) As Task(Of String)
Return Await Task.Run(Function()
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Return New IronTesseract().Read(input).Text
End Using
End Function)
End Function
Yeni kod için, Task.Run sarmalayıcı yerine yerel asenkron OCR desteğini kullanın. PDF girdi kılavuzu, sayfa aralığı seçimi ve şifre korumalı PDF yüklemeyi kapsar.
Sorun 4: Hız Sınırı Yeniden Deneme Mantığı Artık Gerekli Değil
Google Cloud Vision: RpcException'i StatusCode.ResourceExhausted ile yakalayan ve bir bekle-ve-yeniden dene modelini uygulayan herhangi bir kod, dakikada 1.800 istek kotasını karşılayacak şekilde yazılmıştır. Bu yeniden deneme mantığı, orta katmanda, boru hattı adımlarında veya toplu işleme döngülerinde gömülü olabilir.
Çözüm: Kota hatalarıyla ilişkili tüm yeniden deneme mantığını kaldırın. IronOCR, harici kota olmadan yerel olarak işler. Hata işleyici sözleşmesi, iki RpcException durumuna değişir.
// Remove: all RpcException handlers for ResourceExhausted, PermissionDenied,
// Unavailable, DeadlineExceeded, Unauthenticated
//IronOCR error surface:
try
{
var result = new IronTesseract().Read(imagePath);
if (result.Confidence < 50)
input.DeNoise(); // add preprocessing for low-confidence results
return result.Text;
}
catch (IOException ex)
{
// File not found or locked
throw new InvalidOperationException($"Cannot read: {imagePath}", ex);
}
catch (IronOcr.Exceptions.OcrException ex)
{
// Processing failure — not a transient network error
throw new InvalidOperationException($"OCR failed: {ex.Message}", ex);
}
// Remove: all RpcException handlers for ResourceExhausted, PermissionDenied,
// Unavailable, DeadlineExceeded, Unauthenticated
//IronOCR error surface:
try
{
var result = new IronTesseract().Read(imagePath);
if (result.Confidence < 50)
input.DeNoise(); // add preprocessing for low-confidence results
return result.Text;
}
catch (IOException ex)
{
// File not found or locked
throw new InvalidOperationException($"Cannot read: {imagePath}", ex);
}
catch (IronOcr.Exceptions.OcrException ex)
{
// Processing failure — not a transient network error
throw new InvalidOperationException($"OCR failed: {ex.Message}", ex);
}
Imports IronOcr
Imports System.IO
' Remove: all RpcException handlers for ResourceExhausted, PermissionDenied,
' Unavailable, DeadlineExceeded, Unauthenticated
'IronOCR error surface:
Try
Dim result = New IronTesseract().Read(imagePath)
If result.Confidence < 50 Then
input.DeNoise() ' add preprocessing for low-confidence results
End If
Return result.Text
Catch ex As IOException
' File not found or locked
Throw New InvalidOperationException($"Cannot read: {imagePath}", ex)
Catch ex As IronOcr.Exceptions.OcrException
' Processing failure — not a transient network error
Throw New InvalidOperationException($"OCR failed: {ex.Message}", ex)
End Try
Sorun 5: Çok Sayfalı TIFF Kare Çıkarma Döngüsü Gerektirir
Google Cloud Vision: Mevcut TIFF işleme kodu, muhtemelen System.Drawing.Image kullanarak kareleri çıkarır, her kareyi bir geçici dizine JPEG olarak kaydeder, her JPEG'i ayrı bir API çağrısı olarak gönderir ve ardından geçici dosyaları siler. Bu model her kare başına bir kota birimi tüketir ve çökme olduğunda yetim geçici dosyalar bırakabilir.
Çözüm: Çerçeve çıkarma döngüsünü ve geçici dosya yönetimini input.LoadImageFrames() ile değiştirin. Tüm System.Drawing kare döngüsü silinir:
// Remove: System.Drawing frame extraction, temp file writes, per-frame API calls
// Replace with:
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // all frames, no temp files
var result = new IronTesseract().Read(input);
// Remove: System.Drawing frame extraction, temp file writes, per-frame API calls
// Replace with:
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // all frames, no temp files
var result = new IronTesseract().Read(input);
Imports IronOcr
Dim input As New OcrInput()
input.LoadImageFrames(tiffPath) ' all frames, no temp files
Dim result = (New IronTesseract()).Read(input)
Çoklu kare işleme seçenekleri, çerçeve aralığı seçimi dahil, TIFF ve GIF giriş kılavuzuna bakın.
Sorun 6: BoundingPoly Köşe Hesaplamaları Bozulur
Google Cloud Vision: annotation.BoundingPoly.Vertices'dan sınır kutusu koordinatlarını okuyan kod, X, Y, Genislik ve Yükseklik'i köşe indeksi aritmetiği ile hesapladı: vertices[0].X ile X, vertices[1].X - vertices[0].X ile Genislik, vertices[2].Y - vertices[0].Y ile Yükseklik. Göçten sonra, bu ifadeler IronOCR'da bir karşılığı olmadığı için, çünkü Vertices yoktur.
Çözüm: Köşe aritmetiğini doğrudan int özellikleriyle değiştirin. Hesaplamaya gerek yok:
// Before: vertex index arithmetic
int x = word.BoundingBox.Vertices[0].X;
int y = word.BoundingBox.Vertices[0].Y;
int width = word.BoundingBox.Vertices[1].X - word.BoundingBox.Vertices[0].X;
int height = word.BoundingBox.Vertices[2].Y - word.BoundingBox.Vertices[0].Y;
// After: direct properties
int x = word.X;
int y = word.Y;
int width = word.Width;
int height = word.Height;
// Before: vertex index arithmetic
int x = word.BoundingBox.Vertices[0].X;
int y = word.BoundingBox.Vertices[0].Y;
int width = word.BoundingBox.Vertices[1].X - word.BoundingBox.Vertices[0].X;
int height = word.BoundingBox.Vertices[2].Y - word.BoundingBox.Vertices[0].Y;
// After: direct properties
int x = word.X;
int y = word.Y;
int width = word.Width;
int height = word.Height;
' Before: vertex index arithmetic
Dim x As Integer = word.BoundingBox.Vertices(0).X
Dim y As Integer = word.BoundingBox.Vertices(0).Y
Dim width As Integer = word.BoundingBox.Vertices(1).X - word.BoundingBox.Vertices(0).X
Dim height As Integer = word.BoundingBox.Vertices(2).Y - word.BoundingBox.Vertices(0).Y
' After: direct properties
Dim x As Integer = word.X
Dim y As Integer = word.Y
Dim width As Integer = word.Width
Dim height As Integer = word.Height
Google Cloud Vision OCRGeçiş Kontrol Listesi
Öncesi-Geçiş
Değişiklik yapmadan önce herGoogle Cloud Visionbağımlılığını belirlemek için kod tabanını denetleyin:
# Find allGoogle Cloud Visionnamespace imports
grep -rn "using Google.Cloud.Vision" --include="*.cs" .
grep -rn "using Google.Cloud.Storage" --include="*.cs" .
grep -rn "using Grpc.Core" --include="*.cs" .
# Find ImageAnnotatorClient usage
grep -rn "ImageAnnotatorClient" --include="*.cs" .
# Find GCS pipeline code
grep -rn "StorageClient\|UploadObjectAsync\|DeleteObjectAsync" --include="*.cs" .
grep -rn "AsyncBatchAnnotateFilesAsync\|PollUntilCompleted" --include="*.cs" .
# Find Protobuf symbol concatenation
grep -rn "\.Symbols\." --include="*.cs" .
grep -rn "SelectMany.*Symbols" --include="*.cs" .
# Find BoundingPoly vertex calculations
grep -rn "BoundingPoly\|BoundingBox\.Vertices" --include="*.cs" .
# Find rate limit retry handlers
grep -rn "ResourceExhausted\|StatusCode\." --include="*.cs" .
# Find environment variable references
grep -rn "GOOGLE_APPLICATION_CREDENTIALS" .
# Find allGoogle Cloud Visionnamespace imports
grep -rn "using Google.Cloud.Vision" --include="*.cs" .
grep -rn "using Google.Cloud.Storage" --include="*.cs" .
grep -rn "using Grpc.Core" --include="*.cs" .
# Find ImageAnnotatorClient usage
grep -rn "ImageAnnotatorClient" --include="*.cs" .
# Find GCS pipeline code
grep -rn "StorageClient\|UploadObjectAsync\|DeleteObjectAsync" --include="*.cs" .
grep -rn "AsyncBatchAnnotateFilesAsync\|PollUntilCompleted" --include="*.cs" .
# Find Protobuf symbol concatenation
grep -rn "\.Symbols\." --include="*.cs" .
grep -rn "SelectMany.*Symbols" --include="*.cs" .
# Find BoundingPoly vertex calculations
grep -rn "BoundingPoly\|BoundingBox\.Vertices" --include="*.cs" .
# Find rate limit retry handlers
grep -rn "ResourceExhausted\|StatusCode\." --include="*.cs" .
# Find environment variable references
grep -rn "GOOGLE_APPLICATION_CREDENTIALS" .
Başlamadan önce tamamlanacak envanter notları:
- OCR giriş/çıkışı için oluşturulan tüm GCS kovaliklerini listeleyin — geçişten sonra temizlemeyi planlayın
- GCP Konsolu'nda geçiş sonrası devre dışı bırakılabilmesi için hizmet hesabı e-posta adresini belgeleyin
GOOGLE_APPLICATION_CREDENTIALSyapılandırıldığı tüm ortamları belirleyin- Yapılandırmadan GCP proje kimliklerini veya kova adlarını okuyan herhangi bir kodu not edin — geçiş sonrası bunları kaldır
Kod Geçişi
- Tüm projelerden
Google.Cloud.Vision.V1NuGet paketini kaldırın - Tüm projelerden
Google.Cloud.Storage.V1NuGet paketini kaldırın - OCR işlemi gerçekleştiren tüm projelere
IronOcrNuGet paketini yükleyin - Uygulama başlangıcında
IronOcr.License.LicenseKeybaşlatmasını ekleyin - Tüm
using Google.Cloud.Vision.V1içe aktarımlarınıusing IronOcrile değiştirin - Tüm
using Google.Cloud.Storage.V1veusing Grpc.Coreiçe aktarımlarını değiştirin ImageAnnotatorClient.Create()ilenew IronTesseract()değiştirin- Tüm GCS boru hattı yöntemlerini (
StorageClient,UploadObjectAsync, asenkron açıklama, anket, indirme, silme) silin - Tüm PDF işleme yolları için
input.LoadPdf()değiştirin (asenkron GCS orkestrasyonunu kaldırma) - Tüm Protobuf sembol birleştirme döngülerini,
OcrResultnesnelerde doğrudan.Textözellik erişimi ile değiştirin BoundingPoly.Verticesindeks hesaplamalarınıword.X,word.Y,word.Width,word.Heightile değiştirinRpcExceptionyakalama bloklarının tümünü silin,ResourceExhausted,PermissionDenied,Unavailable,DeadlineExceededveUnauthenticatediçin.- Çerçeve başına TIFF döngüsünü
input.LoadImageFrames()ile değiştirin - Ardışık toplu işleri, iş parçacığı başına
IronTesseractolanParallel.ForEach'ye dönüştürün - Tüm ortam yapılandırmalarından, CI/CD boru hatlarından, Docker Compose dosyalarından ve Kubernetes gizli anahtarlarından
GOOGLE_APPLICATION_CREDENTIALS'i kaldırın
Geçiş Sonrası
RpcExceptionveyaGoogleApiExceptiontürlerinin hata işleme kodunda artık referans edilmediğinden emin olunGOOGLE_APPLICATION_CREDENTIALS'nın tüm dağıtım ortamı yapılandırmalarında yok olduğunu doğrulayın- Üretimde kullanılan aynı örnek belgeler üzerinde OCR boru hattını çalıştırın ve metin çıkış kalitesini karşılaştırın
- Daha önce GCS asenkron boru hattı tarafından işlenen belgeler üzerinde PDF işlemeyi test edin ve aynı metin çıktısını onaylayın
- Daha önce desteklenmeyen
input.LoadPdf(path, Password: "...")ile parola korumalı PDF'leri test edin input.LoadImageFrames()kullanarak çok sayfalı TIFF işleme test edin ve tüm karelerin işlendiğini doğrulayın- Temsilci bir örnek üzerinde toplu işleyiciyi çalıştırın ve çıktı kalitesinin önceki sonuçlarla eşleştiğini onaylayın
- Belge koleksiyonunuz için
result.Confidencedeğerlerinin kabul edilebilir aralıkta olduğundan emin olun - Daha önce ayrı bir PDF kütüphanesi gerektiren belgeler için
result.SaveAsSearchablePdf()kullanarak aranabilir PDF çıktısını doğrulayın - Çıkış internet bağlantısı olmayan bir ortamda uygulamayı çalıştırın ve OCR'nin doğru çalıştığını onaylayın
IronOCR'a Geçişin Ana Faydaları
Kimlik Bilgisi Yüzeyi Sıfır Dosyaya İndirildi. Göçten sonra, altyapınızda JSON anahtar dosyaları, GCS bucket yapılandırmaları, IAM rolleri, hizmet hesapları ve GOOGLE_APPLICATION_CREDENTIALS ortam değişkenleri yoktur. Tüm kimlik bilgisi yüzeyi, bir lisans anahtarı dizisi içeren bir ortam değişkenidir.Google Cloud Visionile zorunlu bir periyodik işlem olan anahtar döndürme artık uygulanan bir kavram değildir. Birden fazla bölgede veya bulut sağlayıcısında faaliyet gösteren ekipler için, dağıtım yapılandırma karmaşıklığının azaltılması anlık olarak fark edilir.
Dış Bağımlılıklar Olmadan PDF ve TIFF İşleme. GCS asenkron boru hattı ve System.Drawing TIFF kare döngüsü tamamen silinmiştir. input.LoadPdf() ve input.LoadImageFrames() ikame öğeleridir — her ikisi de senkron, her ikisi de yerel, her ikisi de çağrı ile sonuç arasında üç satır.Google Cloud Visionile olanaklı olmayan şifre korumalı PDF'ler, ek bir parametre ile çalışır. PDF OCR rehberi ve TIFF girdi rehberi, tam giriş API'sini kapsar.
CPU Hızıyla Toplu İşleme. Dakikada 1.800 istek kotasının kaldırılması ve zorunlu 60 saniyelik tekrar deneme sürelerinin ortadan kalkması, daha önce sınırlı hıza tabi olan toplu işlerin artık mevcut işlemci çekirdeklerinin hızında çalıştığı anlamına gelir. 16 çekirdekli bir makine, harici onay olmadan 16 belgeyi aynı anda işler. Parallel.ForEach deseni, boğulmuş sıralı döngünün doğrudan yedek parçasıdır, iş parçacığı başına IronTesseract örnekleri ile. hız optimizasyon kılavuzu, belirli belge türleri için verimliliği ayarlamak üzere motor yapılandırma seçeneklerini kapsar.
Protobuf Olmadan Yapılandırılmış Veri. Her OcrResult, türlenmiş .NET özellikleri olarak Text, Confidence, Pages, Paragraphs, Lines, Words ve Characters açığa çıkarır, hiçbir Protobuf ad alanı bağımlılığı, sembol birleştirme ve sınır kutuları için köşe aritmetiği yok. Daha önce paragraf metni çıkarmak için 20 satırlık iç içe döngüler gerektiren kod, result.Paragraphs.Select(p => p.Text)'ye indirgenir. Belge yerleşim analizi için kelime düzeyinde konumlandırma gereken kullanım durumları için, word.X, word.Y, word.Width ve word.Height doğrudan mevcuttur. OCR sonuçları özellikler sayfası, sonuç modelindeki her özelliği belgelendirir.
Aranabilir PDF Çıkışı Dahili Olarak Sunulur.Google Cloud Visionyalnızca metin döndürür — aranabilir bir PDF üretmek, başka bir API'yi öğrenmeyi ve başka bir lisanslamayı değerlendirmeyi gerektirirdi. IronOCR'nin result.SaveAsSearchablePdf(outputPath)'ı, herhangi bir OCR sonucundan bir satırda tamamen aranabilir bir PDF üretir. Belge arşivleme iş akışları ve yasal bulgu hatları için, bu bir bütün bağımlılığı ortadan kaldırır. Aranabilir PDF örneği, modeli baştan sona gösterir.
Düzenleyici Endüstriler İçin Veri Egemenliği.IronOCR tarafından işlenen belgeler sunucuyu asla terk etmez. HIPAA kapsamındaki sağlık kayıtları, ITAR kontrollü teknik veriler, CMMC kapsamındaki savunma müteahhit malzemeleri, avukat-müvekkil gizli yasal belgeler ve PCI-DSS kapsamında finansal kayıtlar için, yerel yerleşim mimarisi, üçüncü taraf veri işleyici kategorisini uyumluluk alanından tamamen çıkarır. Karşılıklı İş Ortağı Anlaşması yapmak, Veri Koruma Sözleşmesi imzalamak ve Google veri saklama politikasını gözden geçirmek gerekmez. IronOCR belgeleri merkezi, veri yerleşim gereksinimlerinin uygulandığı Docker, Linux, Azure ve AWS ortamları için dağıtım yapılandırmalarını kapsar.
Sıkça Sorulan Sorular
Neden Google Cloud Vision API'dan IronOCR'ye 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.
Google Cloud Vision API'dan IronOCR'ye geçişteki ana kod değişiklikleri nelerdir?
Google Cloud Vision 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, Google Cloud Vision 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, Google Cloud Vision 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.
Google Cloud Vision API'dan IronOCR'ye geçiş, dağıtım altyapısında değişiklik gerektiriyor mu?
IronOCR, Google Cloud Vision 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 Google Cloud Vision 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 Google Cloud Vision 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.
Google Cloud Vision 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.

