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;
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 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
NuGet paketi sayfasından IronOCR yükleyin:
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;
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"Ü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.");
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;
}
}
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;
}
}
İş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;
}
}
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);
}
}
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;
}
}
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();
}
}
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;
}
}
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);
}
}
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;
}
}
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);
});
}
}
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.");
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" .
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;
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;
});
}
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);
}
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);
Ç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;
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" .
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.

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ılandırılmış, görsel olarak çekici kılavuzlar oluşturmayı seviyor.