OCR Araçları Kullanarak Görsellerden Arapça Metin Nasıl Çıkartılır?
Bu kılavuz, bir .NET geliştiricisini tamamen bir GdPicture.NET OCR'den IronOCR'ye geçiş sürecine yönlendirmektedir. Paket değişimini, ad alanı değişimlerini ve her önemli OCR iş akışı için pratik önce/sonra kod desenlerini kapsamaktadır, özellikle GdPicture'in kaynak yönetimi modelini tanımlayan tamsayı görüntü ID yaşam döngüsünün ortadan kaldırılmasına odaklanarak. Karşılaştırma makalesinin önceden okunması gerekmez.
Neden GdPicture.NET'ten Geçiş Yapmalı
GdPicture.NET, bir satıcı tarafından tek bir yerden tarayıcı entegrasyonu, DICOM desteği, PDF düzenleme, açıklama ve OCR ihtiyacı olan ekipler için tasarlanmış bir belge tasvir platformudur. OCR tek gereksinim olduğunda, platformun fiyatlandırması ve API mimarisi zamanla biriken sürtüşme yaratır.
Temel Bir OCR İş Akışı İçin Eklenti Maliyeti. Tarama ile PDF'lerden metin çıkarma ve aranabilir çıktı üretilmesi, üç ayrı lisans bileşeni gerektirir: Yaklaşık $4.000 bedelli Çekirdek SDK, yaklaşık $2.000 bedelli OCR Eklentisi ve yaklaşık $2.000 bedelli PDF Eklentisi. Bu, $8.000 giriş maliyeti, artı %20 yıllık bakım anlamına gelir. Sadece OCR'ye ihtiyaç duyan ekipler, belge tarama platformunun tüm fiyatlandırma yapısını benimserler. IronOCR, bir paketten görüntü OCR, PDF OCR, ön işleme, arama yapılabilir PDF çıktısı — $999 ile $2,999 süresiz lisans olmak üzere ve özellik başına lisanslama olmadan kapsar. Tam seviye ayrımını görmek için IronOCR lisanslama sayfasını bakın.
Tam Sayı Görüntü Kimliği Yaşam Döngüsü. GdPicture aracılığıyla yüklenen her görüntü bir int döner. Bu tam sayıyı OCR işlemlerine geçirirsiniz ve işiniz bittiğinde ReleaseGdPictureImage ile çağırırsınız. Bu desen IDisposable'den önce vardı. Doğru şekilde takip edildiğinde çalışır; atlanan bir serbest bırakma çağrısı olduğunda bellek sızıntısı oluşur. Günde yüzlerce belgeyi işleyen üretim hizmetlerinde, hata dalında atlanan bir serbest bırakma çağrısı, gerçekten zor teşhis edilebilen bir bellek artışı üretir. IronOCR'un OcrInput, IDisposable'ı uygulamaktadır — using ifadesi tüm temizlik yükünü ortadan kaldırır.
Sürüm-Specifik Ad Alanı. GdPicture, ana sürüm numarasını kendi ad alanında gömülü tutar: using GdPicture14. Sonraki ana sürüme yükseltmek, GdPicture sınıflarına referans veren her kaynak dosyada bu using direktifinin güncellenmesini gerektirir. OCR'nin düzinelerce hizmete yayılmış olduğu büyük bir uygulama, bul-farklı-sayısı-değiştir görevi sunar ve bu işlevsel bir iyileştirme sağlamaz. IronOCR'un ad alanı tüm ana sürümler ile IronOcr kalmıştır.
Dış Kaynak Klasörü Gereksinimi. GdPicture OCR, çalıştırma sırasında bir ResourceFolder özelliği gerektirir ve bu özellik, .traineddata dil dosyalarının bulunduğu bir dizini belirtir. Bu yol gelişim makinesinde çalışır, ancak Linux sunucular, Docker konteynerleri ve dizin yapısının mevcut olmadığı Azure App Service dağıtımında bozulur. IronOCR, İngilizce dil desteğini NuGet paketi içine yerleştirir; ek diller, oluşturma çıktısı ile taşınan NuGet paketleri olarak yüklenir.
Üç Bileşenli Başlatma. GdPicture'da bir PDF OCR iş akışı, üç ayrı bileşenin bireysel imha gereksinimleri olan GdPictureImaging, GdPictureOCR ve GdPicturePDF oluşturulmasını; artı lisans yöneticisi kaydı ve kaynak klasör atanmasını gerektirir. IronOCR, başlangıçta bir satır ve çağrı zamanında bir sınıf gerektirir.
Yerli İş Parçacığı Güvenliği Yok. GdPicture OCR örnekleri iş parçacığı güvenli değildir. Paralel belge işleme, bozuk durumlardan kaçınmak için dikkatli örnek yönetimi ve senkronizasyon gerektirir.IronOCR eşzamanlı kullanım için tasarlanmıştır: her iş parçacığı için bir IronTesseract oluşturun veya yük altında tek bir örneği paylaşın — her iki desen de ek eşzamanlama olmadan çalışır.
Temel Sorun
GdPicture, her görüntü için bellek tahsis eder ve bunu bir çalışma zamanı yönetilen tamsayısal kulp olarak atar. TIFF işleme döngüsündeki her RenderPageToGdPictureImage çağrısı, elle serbest bırakılması gereken yeni bir ayırma oluşturur:
// GdPicture: every frame = new integer ID = manual release required
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("multi-page.tiff", false);
var frameIds = new List<int>();
try
{
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
int frameId = pdf.RenderPageToGdPictureImage(200, false); // new allocation
if (frameId != 0) frameIds.Add(frameId);
// ... OCR call here ...
}
}
finally
{
foreach (var id in frameIds) _imaging.ReleaseGdPictureImage(id); // manual per-frame release
}
// GdPicture: every frame = new integer ID = manual release required
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("multi-page.tiff", false);
var frameIds = new List<int>();
try
{
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
int frameId = pdf.RenderPageToGdPictureImage(200, false); // new allocation
if (frameId != 0) frameIds.Add(frameId);
// ... OCR call here ...
}
}
finally
{
foreach (var id in frameIds) _imaging.ReleaseGdPictureImage(id); // manual per-frame release
}
Imports System.Collections.Generic
' GdPicture: every frame = new integer ID = manual release required
Using pdf As New GdPicturePDF()
pdf.LoadFromFile("multi-page.tiff", False)
Dim frameIds As New List(Of Integer)()
Try
For i As Integer = 1 To pdf.GetPageCount()
pdf.SelectPage(i)
Dim frameId As Integer = pdf.RenderPageToGdPictureImage(200, False) ' new allocation
If frameId <> 0 Then frameIds.Add(frameId)
' ... OCR call here ...
Next
Finally
For Each id In frameIds
_imaging.ReleaseGdPictureImage(id) ' manual per-frame release
Next
End Try
End Using
IronOCR, bu yaşam döngüsünü tamamen ortadan kaldırır. OcrInput çerçeve numaralandırmasını ve temizliği yönetir:
// IronOCR: the using statement handles everything
using var input = new OcrInput();
input.LoadImageFrames("multi-page.tiff");
var result = new IronTesseract().Read(input);
// IronOCR: the using statement handles everything
using var input = new OcrInput();
input.LoadImageFrames("multi-page.tiff");
var result = new IronTesseract().Read(input);
Imports IronOcr
Dim input As New OcrInput()
Using input
input.LoadImageFrames("multi-page.tiff")
Dim result = New IronTesseract().Read(input)
End Using
IronOCR ve GdPicture.NET: Özellik Karşılaştırması
Aşağıdaki tablo, OCR odaklı iş akışları için iki kütüphane arasındaki özellik kapsamını eşler.
| Özellik | GdPicture.NET | IronOCR |
|---|---|---|
| Kurulum | Birden çok NuGet paketi | dotnet add package IronOcr |
| Lisans aktive etme | LicenseManager.RegisterKEY() |
IronOcr.License.LicenseKey = "..." |
| Ana sürüm yükseltmede ad alanı | Kapsamlı bul ve değiştir gerektirir (GdPicture14 → sonraki) |
Değişmedi (IronOcr) |
| Bileşen başlatma | GdPictureImaging + GdPictureOCR + GdPicturePDF |
new IronTesseract() |
| Kaynak bellek modeli | Manuel tamsayı kimliği izleme ve serbest bırakma | IDisposable / using ifadesi |
| Bellek sızıntısı riski | Yüksek (eksik ReleaseGdPictureImage) |
Yok (derleyici tarafından using yoluyla zorlanır) |
| Harici kaynak klasörü | Gerekli (_ocr.ResourceFolder = path) |
Gereksiz — pakete dahil |
| Görüntü OCR | Evet | Evet |
| - PDF OCR | Evet (PDF Eklentisi gereklidir) | Yerleşik, ek lisans gerekmez |
| Çok sayfalı TIFF | Manuel çerçeve döngüsü + çerçeve başına ID temizliği | input.LoadImageFrames() |
| Akış girişi | GdPictureImaging akış aşırı yüklenmesi aracılığıyla |
input.LoadImage(stream) |
| Aranabilir PDF çıktısı | pdf.OcrPage() + pdf.SaveToFile() |
result.SaveAsSearchablePdf() |
| Deskew ön işleme | Belge Görüntüleme Eklentisi gereklidir | input.Deskew() — dahili |
| Gürültü giderme | Belge Görüntüleme Eklentisi gereklidir | input.DeNoise() — dahili |
| Diller | Klasörde Tesseract temelli traineddata dosyaları | 125+ NuGet paketleri aracılığıyla |
| Çok Dilli OCR | Evet | OcrLanguage.French + OcrLanguage.German |
| Thread güvenliği | Manuel örnek yönetimi | Tasarımı gereği iş parçacığı güvenli |
| Asenkron OCR | Dahili değil | ReadAsync() |
| Barkod okuma | Ayrı barkod eklentisi | ocr.Configuration.ReadBarCodes = true |
| Yapısal çıktı | İndeks bazlı blok/satır/kelime erişimi | Tipli .Pages, .Words, .Characters |
| Güvenlik puanlaması | GetOCRResultConfidence(resultId) |
result.Confidence |
| Çapraz platform | Windows, Linux, macOS | Windows, Linux, macOS, Docker, AWS, Azure |
| Giriş maliyeti (PDF'lerden OCR) | ~8.000 $ (Çekirdek + OCR + PDF eklentileri) | $999–$2,999 |
| Fiyatlandırma modeli | Eklenti temelline dayalı süresiz + yıllık bakımlar için %20 | Düz süresiz, yıllık güncellemeler isteğe bağlı |
| Ticari destek | Evet | Evet |
Hızlı Başlangıç: GdPicture.NET'ten IronOCR'e Geçiş
Adım 1: NuGet Paketini Değiştirin
GdPicture paketlerini kaldırın:
dotnet remove package GdPicture.NET
dotnet remove package GdPicture.NET.OCR
dotnet remove package GdPicture.NET.PDF
dotnet remove package GdPicture.NET
dotnet remove package GdPicture.NET.OCR
dotnet remove package GdPicture.NET.PDF
NuGet paketi sayfasından IronOCR yükleyin:
dotnet add package IronOcr
İngilizce dışındaki diller için, ilgili dil paketini yükleyin:
dotnet add package IronOcr.Languages.French, IronOcr.Languages.German
Adım 2: Ad Alanlarını Güncelleyin
GdPicture ad alanınıIronOCR ad alanıyla değiştirin:
// Before (GdPicture)
using GdPicture14;
// After (IronOCR)
using IronOcr;
// Before (GdPicture)
using GdPicture14;
// After (IronOCR)
using IronOcr;
Imports IronOcr
Adım 3: Lisansa İzin Verin
Bu satırı Program.cs veya Startup.cs içine yerleştirin, herhangi bir OCR çağrısından önce:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
GdPicture lisans kayıt bloğunu tamamen kaldırın:
// Remove this
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
// Remove this
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
Satın almadan önce değerlendirmek için IronOCR ürün sayfasından ücretsiz bir deneme anahtarı mevcuttur.
Kod Göç Örnekleri
Çok Sayfalı TIFF Çerçeve İşleme
GdPicture'da çok sayfalı TIFF dosyalarını işlemek, PDF/tasvir API'si üzerinden her çerçeveyi seçmeyi, yeni bir görüntü ID'sine işlemeyi, OCR çalıştırmayı ve ID'yi serbest bırakmayı gerektirir. Bir çerçeve finally bloğunda serbest bırakılmazsa, DPI'ye bağlı olarak 10–50 MB sızdırır.
GdPicture.NET Yaklaşımı:
using GdPicture14;
public class GdPictureTiffProcessor
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public string ExtractTextFromTiff(string tiffPath)
{
var text = new StringBuilder();
// Load TIFF through the imaging component
int tiffId = _imaging.CreateGdPictureImageFromFile(tiffPath);
if (tiffId == 0)
throw new Exception($"TIFF load failed: {_imaging.GetStat()}");
// Outer try: release the original TIFF handle
try
{
int frameCount = _imaging.GetPageCount(tiffId);
for (int i = 1; i <= frameCount; i++)
{
// Switch to frame — modifies the existing ID in place
_imaging.SelectPage(tiffId, i);
// Clone frame to a new image ID for OCR
int frameId = _imaging.CloneImage(tiffId);
if (frameId == 0) continue;
// Inner try: release each cloned frame ID
try
{
_ocr.SetImage(frameId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (!string.IsNullOrEmpty(resultId))
{
text.AppendLine($"[Frame {i}] {_ocr.GetOCRResultText(resultId)}");
}
}
finally
{
// Release cloned frame — critical for each iteration
_imaging.ReleaseGdPictureImage(frameId);
}
}
}
finally
{
// Release original TIFF handle
_imaging.ReleaseGdPictureImage(tiffId);
}
return text.ToString();
}
}
using GdPicture14;
public class GdPictureTiffProcessor
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public string ExtractTextFromTiff(string tiffPath)
{
var text = new StringBuilder();
// Load TIFF through the imaging component
int tiffId = _imaging.CreateGdPictureImageFromFile(tiffPath);
if (tiffId == 0)
throw new Exception($"TIFF load failed: {_imaging.GetStat()}");
// Outer try: release the original TIFF handle
try
{
int frameCount = _imaging.GetPageCount(tiffId);
for (int i = 1; i <= frameCount; i++)
{
// Switch to frame — modifies the existing ID in place
_imaging.SelectPage(tiffId, i);
// Clone frame to a new image ID for OCR
int frameId = _imaging.CloneImage(tiffId);
if (frameId == 0) continue;
// Inner try: release each cloned frame ID
try
{
_ocr.SetImage(frameId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (!string.IsNullOrEmpty(resultId))
{
text.AppendLine($"[Frame {i}] {_ocr.GetOCRResultText(resultId)}");
}
}
finally
{
// Release cloned frame — critical for each iteration
_imaging.ReleaseGdPictureImage(frameId);
}
}
}
finally
{
// Release original TIFF handle
_imaging.ReleaseGdPictureImage(tiffId);
}
return text.ToString();
}
}
Imports GdPicture14
Imports System.Text
Public Class GdPictureTiffProcessor
Private ReadOnly _imaging As GdPictureImaging
Private ReadOnly _ocr As GdPictureOCR
Public Function ExtractTextFromTiff(tiffPath As String) As String
Dim text As New StringBuilder()
' Load TIFF through the imaging component
Dim tiffId As Integer = _imaging.CreateGdPictureImageFromFile(tiffPath)
If tiffId = 0 Then
Throw New Exception($"TIFF load failed: {_imaging.GetStat()}")
End If
' Outer try: release the original TIFF handle
Try
Dim frameCount As Integer = _imaging.GetPageCount(tiffId)
For i As Integer = 1 To frameCount
' Switch to frame — modifies the existing ID in place
_imaging.SelectPage(tiffId, i)
' Clone frame to a new image ID for OCR
Dim frameId As Integer = _imaging.CloneImage(tiffId)
If frameId = 0 Then Continue For
' Inner try: release each cloned frame ID
Try
_ocr.SetImage(frameId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If Not String.IsNullOrEmpty(resultId) Then
text.AppendLine($"[Frame {i}] {_ocr.GetOCRResultText(resultId)}")
End If
Finally
' Release cloned frame — critical for each iteration
_imaging.ReleaseGdPictureImage(frameId)
End Try
Next
Finally
' Release original TIFF handle
_imaging.ReleaseGdPictureImage(tiffId)
End Try
Return text.ToString()
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
public class IronOcrTiffProcessor
{
public string ExtractTextFromTiff(string tiffPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // all frames loaded, all cleanup automatic
var result = new IronTesseract().Read(input);
// Per-frame text is available on result.Pages
foreach (var page in result.Pages)
Console.WriteLine($"[Frame {page.PageNumber}] {page.Text}");
return result.Text;
}
}
using IronOcr;
public class IronOcrTiffProcessor
{
public string ExtractTextFromTiff(string tiffPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // all frames loaded, all cleanup automatic
var result = new IronTesseract().Read(input);
// Per-frame text is available on result.Pages
foreach (var page in result.Pages)
Console.WriteLine($"[Frame {page.PageNumber}] {page.Text}");
return result.Text;
}
}
Imports IronOcr
Public Class IronOcrTiffProcessor
Public Function ExtractTextFromTiff(tiffPath As String) As String
Using input As New OcrInput()
input.LoadImageFrames(tiffPath) ' all frames loaded, all cleanup automatic
Dim result = New IronTesseract().Read(input)
' Per-frame text is available on result.Pages
For Each page In result.Pages
Console.WriteLine($"[Frame {page.PageNumber}] {page.Text}")
Next
Return result.Text
End Using
End Function
End Class
LoadImageFrames, çok sayfalı TIFF'teki her kareyi OcrInput hattına yükler. using bloğu, kapsamın sonunda her kareyle ilişkili tüm belleği yönetir. Yönetilecek List<int> yok, iç içe try/finally blokları gerekmez. TIFF ve GIF giriş kılavuzu, çerçeve seçimi ve çok formatlı işleme konularını detaylı bir şekilde kapsar.
Eklenti Başlatmanın Yerine Veritabanı Temelli Giriş
Sunucu uygulamaları, genellikle dosya yollarından ziyade akışlar olarak belgeleri alır — HTTP yüklemelerinden, mesaj kuyruklarından veya veritabanı bloblarından. GdPicture, akışı GdPictureImaging üzerinden yüklemeyi gerektirir, bu da her işlemin öncesinde bileşen başlatma sırası ve kaynak klasörü yapılandırması gerektirir.
GdPicture.NET Yaklaşımı:
using GdPicture14;
public class GdPictureStreamOcr : IDisposable
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public GdPictureStreamOcr()
{
// Plugin initialization required before stream loading is possible
var lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR"; // path must exist at runtime
}
public string ExtractTextFromStream(Stream documentStream)
{
// Load stream into imaging component to get an image ID
int imageId = _imaging.CreateGdPictureImageFromStream(documentStream);
if (imageId == 0)
throw new Exception($"Stream load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
}
public void Dispose()
{
_ocr?.Dispose();
_imaging?.Dispose();
}
}
using GdPicture14;
public class GdPictureStreamOcr : IDisposable
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public GdPictureStreamOcr()
{
// Plugin initialization required before stream loading is possible
var lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR"; // path must exist at runtime
}
public string ExtractTextFromStream(Stream documentStream)
{
// Load stream into imaging component to get an image ID
int imageId = _imaging.CreateGdPictureImageFromStream(documentStream);
if (imageId == 0)
throw new Exception($"Stream load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
}
public void Dispose()
{
_ocr?.Dispose();
_imaging?.Dispose();
}
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
IronOCR Yaklaşımı:
using IronOcr;
public class IronOcrStreamOcr
{
public string ExtractTextFromStream(Stream documentStream)
{
using var input = new OcrInput();
input.LoadImage(documentStream); // stream accepted directly — no imaging component
return new IronTesseract().Read(input).Text;
}
}
using IronOcr;
public class IronOcrStreamOcr
{
public string ExtractTextFromStream(Stream documentStream)
{
using var input = new OcrInput();
input.LoadImage(documentStream); // stream accepted directly — no imaging component
return new IronTesseract().Read(input).Text;
}
}
Imports IronOcr
Public Class IronOcrStreamOcr
Public Function ExtractTextFromStream(documentStream As Stream) As String
Using input As New OcrInput()
input.LoadImage(documentStream) ' stream accepted directly — no imaging component
Return New IronTesseract().Read(input).Text
End Using
End Function
End Class
GdPicture yaklaşımı, üç nesne oluşturmayı ve ilk akışın tüketilmesinden önce bir dosya sistemi yolu yapılandırmayı gerektirir. IronOCR, önceden hiçbir yükleme olmadan akışı doğrudan OcrInput üzerinde kabul eder. akış girişi kılavuzu, geçici dosya yazımlarının istenmeyen olduğu hat mimarileri için bayt dizisi, MemoryStream ve FileStream desenlerini kapsar.
Durum Kodu Anketine Alternatif Olarak Asenkron OCR
GdPicture OCR senkron çalışır. ASP.NET Core uç noktaları veya arka plan hizmetlerinde belgeleri işleyen uygulamalar RunOCR'ı Task.Run içinde sarmalı ve talep iş parçacıklarını engellememelidir — ve ardından iş parçacığı sınırı boyunca görüntü kimliği yaşam döngüsünü yönetmelidir. IronOCR, ReadAsync aracılığıyla birinci sınıf eşzamansız destek sağlar.
GdPicture.NET Yaklaşımı:
using GdPicture14;
using System.Threading.Tasks;
public class GdPictureAsyncWrapper
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);
public async Task<string> ExtractTextAsync(string imagePath)
{
// Must acquire lock: GdPictureOCR is not thread-safe
await _lock.WaitAsync();
try
{
return await Task.Run(() =>
{
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
throw new Exception($"Load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
});
}
finally
{
_lock.Release();
}
}
}
using GdPicture14;
using System.Threading.Tasks;
public class GdPictureAsyncWrapper
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);
public async Task<string> ExtractTextAsync(string imagePath)
{
// Must acquire lock: GdPictureOCR is not thread-safe
await _lock.WaitAsync();
try
{
return await Task.Run(() =>
{
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
throw new Exception($"Load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
});
}
finally
{
_lock.Release();
}
}
}
Imports GdPicture14
Imports System.Threading.Tasks
Public Class GdPictureAsyncWrapper
Private ReadOnly _imaging As GdPictureImaging
Private ReadOnly _ocr As GdPictureOCR
Private ReadOnly _lock As New SemaphoreSlim(1, 1)
Public Async Function ExtractTextAsync(imagePath As String) As Task(Of String)
' Must acquire lock: GdPictureOCR is not thread-safe
Await _lock.WaitAsync()
Try
Return Await Task.Run(Function()
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(imagePath)
If imageId = 0 Then
Throw New Exception($"Load failed: {_imaging.GetStat()}")
End If
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then
Throw New Exception($"OCR failed: {_ocr.GetStat()}")
End If
Return _ocr.GetOCRResultText(resultId)
Finally
_imaging.ReleaseGdPictureImage(imageId)
End Try
End Function)
Finally
_lock.Release()
End Try
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
public class IronOcrAsyncService
{
private readonly IronTesseract _ocr = new IronTesseract();
public async Task<string> ExtractTextAsync(string imagePath)
{
// ReadAsync is natively async — no Task.Run wrapper, no lock required
var result = await _ocr.ReadAsync(imagePath);
return result.Text;
}
public async Task<string> ExtractFromStreamAsync(Stream stream)
{
using var input = new OcrInput();
input.LoadImage(stream);
var result = await _ocr.ReadAsync(input);
return result.Text;
}
}
using IronOcr;
public class IronOcrAsyncService
{
private readonly IronTesseract _ocr = new IronTesseract();
public async Task<string> ExtractTextAsync(string imagePath)
{
// ReadAsync is natively async — no Task.Run wrapper, no lock required
var result = await _ocr.ReadAsync(imagePath);
return result.Text;
}
public async Task<string> ExtractFromStreamAsync(Stream stream)
{
using var input = new OcrInput();
input.LoadImage(stream);
var result = await _ocr.ReadAsync(input);
return result.Text;
}
}
Imports IronOcr
Imports System.IO
Imports System.Threading.Tasks
Public Class IronOcrAsyncService
Private ReadOnly _ocr As New IronTesseract()
Public Async Function ExtractTextAsync(imagePath As String) As Task(Of String)
' ReadAsync is natively async — no Task.Run wrapper, no lock required
Dim result = Await _ocr.ReadAsync(imagePath)
Return result.Text
End Function
Public Async Function ExtractFromStreamAsync(stream As Stream) As Task(Of String)
Using input As New OcrInput()
input.LoadImage(stream)
Dim result = Await _ocr.ReadAsync(input)
Return result.Text
End Using
End Function
End Class
GdPicture yaklaşımı, paylaşılan GdPictureOCR örneğine erişimi serileştirmek için bir SemaphoreSlim, çağrı iş parçacığı üzerindeki senkronize engelleme işini taşımak için bir Task.Run ve bu lambda içinde tam görüntü kimliği yaşam döngüsünü gerektirir. IronOCR'un ReadAsync gerçekten engellemez ve iş parçacığı açısından güvenlidir. asenkron OCR kılavuzu, ASP.NET Core ara katmanları ve barındırılan arka plan servisleri ile entegrasyonu kapsar.
İş Parçacığı Güvenliği ile Paralel Toplu İşleme
Taranmış belgeler klasörünü olabildiğince hızlı işlemek, paralel yürütme gerektirir. GdPicture, her iş parçacığı için bir GdPictureOCR örneği gerektirir - paylaşılan bir örnek kullanımı, belirlenemeyen hatalara neden olur. Her iş parçacığı başına örnek ayrıca kendi GdPictureImaging bileşenini ve kaynak klasörü yapılandırmasını gerektirir ve bu, fabrika deseni olmadan iş parçacığı havuzu yaklaşımlarını pratik hale getirmez.
GdPicture.NET Yaklaşımı:
using GdPicture14;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class GdPictureParallelBatch
{
private readonly string _resourceFolder = @"C:\GdPicture\Resources\OCR";
public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// Each thread must have its own component instances
Parallel.ForEach(imagePaths, imagePath =>
{
// Create per-thread instances — shared instances cause failures
using var threadImaging = new GdPictureImaging();
using var threadOcr = new GdPictureOCR();
threadOcr.ResourceFolder = _resourceFolder;
// Re-register license per thread (may be required depending on SDK version)
var lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
int imageId = threadImaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
{
results[imagePath] = $"ERROR: {threadImaging.GetStat()}";
return;
}
try
{
threadOcr.SetImage(imageId);
threadOcr.Language = "eng";
string resultId = threadOcr.RunOCR();
results[imagePath] = string.IsNullOrEmpty(resultId)
? $"ERROR: {threadOcr.GetStat()}"
: threadOcr.GetOCRResultText(resultId);
}
finally
{
threadImaging.ReleaseGdPictureImage(imageId);
}
});
return results;
}
}
using GdPicture14;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class GdPictureParallelBatch
{
private readonly string _resourceFolder = @"C:\GdPicture\Resources\OCR";
public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// Each thread must have its own component instances
Parallel.ForEach(imagePaths, imagePath =>
{
// Create per-thread instances — shared instances cause failures
using var threadImaging = new GdPictureImaging();
using var threadOcr = new GdPictureOCR();
threadOcr.ResourceFolder = _resourceFolder;
// Re-register license per thread (may be required depending on SDK version)
var lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
int imageId = threadImaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
{
results[imagePath] = $"ERROR: {threadImaging.GetStat()}";
return;
}
try
{
threadOcr.SetImage(imageId);
threadOcr.Language = "eng";
string resultId = threadOcr.RunOCR();
results[imagePath] = string.IsNullOrEmpty(resultId)
? $"ERROR: {threadOcr.GetStat()}"
: threadOcr.GetOCRResultText(resultId);
}
finally
{
threadImaging.ReleaseGdPictureImage(imageId);
}
});
return results;
}
}
Imports GdPicture14
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Public Class GdPictureParallelBatch
Private ReadOnly _resourceFolder As String = "C:\GdPicture\Resources\OCR"
Public Function ProcessBatch(imagePaths As String()) As ConcurrentDictionary(Of String, String)
Dim results As New ConcurrentDictionary(Of String, String)()
' Each thread must have its own component instances
Parallel.ForEach(imagePaths, Sub(imagePath)
' Create per-thread instances — shared instances cause failures
Using threadImaging As New GdPictureImaging()
Using threadOcr As New GdPictureOCR()
threadOcr.ResourceFolder = _resourceFolder
' Re-register license per thread (may be required depending on SDK version)
Dim lm As New LicenseManager()
lm.RegisterKEY("GDPICTURE-LICENSE-KEY")
Dim imageId As Integer = threadImaging.CreateGdPictureImageFromFile(imagePath)
If imageId = 0 Then
results(imagePath) = $"ERROR: {threadImaging.GetStat()}"
Return
End If
Try
threadOcr.SetImage(imageId)
threadOcr.Language = "eng"
Dim resultId As String = threadOcr.RunOCR()
results(imagePath) = If(String.IsNullOrEmpty(resultId), $"ERROR: {threadOcr.GetStat()}", threadOcr.GetOCRResultText(resultId))
Finally
threadImaging.ReleaseGdPictureImage(imageId)
End Try
End Using
End Using
End Sub)
Return results
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class IronOcrParallelBatch
{
public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// IronTesseract is thread-safe — one instance handles all threads
var ocr = new IronTesseract();
Parallel.ForEach(imagePaths, imagePath =>
{
try
{
results[imagePath] = ocr.Read(imagePath).Text;
}
catch (Exception ex)
{
results[imagePath] = $"ERROR: {ex.Message}";
}
});
return results;
}
}
using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class IronOcrParallelBatch
{
public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// IronTesseract is thread-safe — one instance handles all threads
var ocr = new IronTesseract();
Parallel.ForEach(imagePaths, imagePath =>
{
try
{
results[imagePath] = ocr.Read(imagePath).Text;
}
catch (Exception ex)
{
results[imagePath] = $"ERROR: {ex.Message}";
}
});
return results;
}
}
Imports IronOcr
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Public Class IronOcrParallelBatch
Public Function ProcessBatch(imagePaths As String()) As ConcurrentDictionary(Of String, String)
Dim results As New ConcurrentDictionary(Of String, String)()
' IronTesseract is thread-safe — one instance handles all threads
Dim ocr As New IronTesseract()
Parallel.ForEach(imagePaths, Sub(imagePath)
Try
results(imagePath) = ocr.Read(imagePath).Text
Catch ex As Exception
results(imagePath) = $"ERROR: {ex.Message}"
End Try
End Sub)
Return results
End Function
End Class
GdPicture paralel uygulaması, iş parçacığı başına üç nesne oluşturur ve iş parçacığı başına lisans kaydı gerektirir. IronOCR, senkronizasyon yükü olmadan tek bir IronTesseract örneğinden eşzamanlı okumaları yönetir. çoklu iş parçacığı örneği, yüksek hacimli belge işleme iş yükleri için verimlilik kıyaslamalarını ve Parallel.ForEach desenlerini gösterir.
Bayt Dizisi Girişi ve Yapılandırılmış Paragraf Çıkarma
Veritabanlarından veya nesne depolarından belgeler alan uygulamalar genellikle dosya yolları yerine bayt dizileri ile çalışır. GdPicture, bayt dizisini bir akışa dönüştürmeyi ve GdPictureImaging'den geçirmeyi gerektirir. Sonuçtan yapılandırılmış paragraf düzeyinde verilerin çıkarılması, blok/çizgi dizini hiyerarşisinin dolaşılmasını gerektirir.
GdPicture.NET Yaklaşımı:
using GdPicture14;
public class GdPictureByteArrayOcr
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
{
var paragraphs = new List<string>();
// Byte array must go through MemoryStream to reach CreateGdPictureImageFromStream
using var ms = new MemoryStream(imageBytes);
int imageId = _imaging.CreateGdPictureImageFromStream(ms);
if (imageId == 0)
throw new Exception($"Byte array load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
// Paragraph-level data requires iterating block structure
int blockCount = _ocr.GetOCRResultBlockCount(resultId);
for (int b = 0; b < blockCount; b++)
{
var blockText = new StringBuilder();
int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);
for (int l = 0; l < lineCount; l++)
{
int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);
for (int w = 0; w < wordCount; w++)
{
blockText.Append(_ocr.GetOCRResultBlockLineWordText(resultId, b, l, w));
blockText.Append(" ");
}
}
string text = blockText.ToString().Trim();
if (!string.IsNullOrEmpty(text))
paragraphs.Add(text);
}
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
return paragraphs;
}
}
using GdPicture14;
public class GdPictureByteArrayOcr
{
private readonly GdPictureImaging _imaging;
private readonly GdPictureOCR _ocr;
public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
{
var paragraphs = new List<string>();
// Byte array must go through MemoryStream to reach CreateGdPictureImageFromStream
using var ms = new MemoryStream(imageBytes);
int imageId = _imaging.CreateGdPictureImageFromStream(ms);
if (imageId == 0)
throw new Exception($"Byte array load failed: {_imaging.GetStat()}");
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
throw new Exception($"OCR failed: {_ocr.GetStat()}");
// Paragraph-level data requires iterating block structure
int blockCount = _ocr.GetOCRResultBlockCount(resultId);
for (int b = 0; b < blockCount; b++)
{
var blockText = new StringBuilder();
int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);
for (int l = 0; l < lineCount; l++)
{
int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);
for (int w = 0; w < wordCount; w++)
{
blockText.Append(_ocr.GetOCRResultBlockLineWordText(resultId, b, l, w));
blockText.Append(" ");
}
}
string text = blockText.ToString().Trim();
if (!string.IsNullOrEmpty(text))
paragraphs.Add(text);
}
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
return paragraphs;
}
}
Imports GdPicture14
Imports System.IO
Imports System.Text
Public Class GdPictureByteArrayOcr
Private ReadOnly _imaging As GdPictureImaging
Private ReadOnly _ocr As GdPictureOCR
Public Function ExtractParagraphsFromBytes(imageBytes As Byte()) As List(Of String)
Dim paragraphs As New List(Of String)()
' Byte array must go through MemoryStream to reach CreateGdPictureImageFromStream
Using ms As New MemoryStream(imageBytes)
Dim imageId As Integer = _imaging.CreateGdPictureImageFromStream(ms)
If imageId = 0 Then
Throw New Exception($"Byte array load failed: {_imaging.GetStat()}")
End If
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then
Throw New Exception($"OCR failed: {_ocr.GetStat()}")
End If
' Paragraph-level data requires iterating block structure
Dim blockCount As Integer = _ocr.GetOCRResultBlockCount(resultId)
For b As Integer = 0 To blockCount - 1
Dim blockText As New StringBuilder()
Dim lineCount As Integer = _ocr.GetOCRResultBlockLineCount(resultId, b)
For l As Integer = 0 To lineCount - 1
Dim wordCount As Integer = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l)
For w As Integer = 0 To wordCount - 1
blockText.Append(_ocr.GetOCRResultBlockLineWordText(resultId, b, l, w))
blockText.Append(" "c)
Next
Next
Dim text As String = blockText.ToString().Trim()
If Not String.IsNullOrEmpty(text) Then
paragraphs.Add(text)
End If
Next
Finally
_imaging.ReleaseGdPictureImage(imageId)
End Try
End Using
Return paragraphs
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
public class IronOcrByteArrayOcr
{
public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
{
using var input = new OcrInput();
input.LoadImage(imageBytes); // byte array accepted directly
var result = new IronTesseract().Read(input);
// Paragraphs are a first-class typed collection
return result.Paragraphs
.Select(p => p.Text)
.Where(t => !string.IsNullOrWhiteSpace(t))
.ToList();
}
}
using IronOcr;
public class IronOcrByteArrayOcr
{
public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
{
using var input = new OcrInput();
input.LoadImage(imageBytes); // byte array accepted directly
var result = new IronTesseract().Read(input);
// Paragraphs are a first-class typed collection
return result.Paragraphs
.Select(p => p.Text)
.Where(t => !string.IsNullOrWhiteSpace(t))
.ToList();
}
}
Imports IronOcr
Public Class IronOcrByteArrayOcr
Public Function ExtractParagraphsFromBytes(imageBytes As Byte()) As List(Of String)
Using input As New OcrInput()
input.LoadImage(imageBytes) ' byte array accepted directly
Dim result = New IronTesseract().Read(input)
' Paragraphs are a first-class typed collection
Return result.Paragraphs _
.Select(Function(p) p.Text) _
.Where(Function(t) Not String.IsNullOrWhiteSpace(t)) _
.ToList()
End Using
End Function
End Class
IronOCR, byte[]'u doğrudan LoadImage üzerinde kabul eder, MemoryStream ara yöntemi olmadan. Sonuç, bir tür LINQ-sorgulanabilir koleksiyon olarak .Paragraphs açığa çıkarır — blok/çizgi/kelime üçlü döngüsü gerektirmez. sonuçları okuma kılavuzu koordinat erişimini, güven filtrelemeyi ve fatura ve form işleme iş akışları için yapılandırılmış çıktı desenlerini kapsar. Belirli belge alanlarını taramak için bölge tabanlı OCR bölümüne bakın.
GdPicture.NET API'yi IronOCR'e Eşleştirme Referansı
| GdPicture.NET | IronOCR Karşılığı |
|---|---|
using GdPicture14; |
using IronOcr; |
LicenseManager.RegisterKEY("key") |
IronOcr.License.LicenseKey = "key" |
new GdPictureImaging() |
Gerekli değil — OcrInput içeriğinde |
new GdPictureOCR() |
new IronTesseract() |
new GdPicturePDF() |
Gerekli değil — OcrInput.LoadPdf() bunu yönetir |
_ocr.ResourceFolder = path |
Gerekli değil — NuGet içinde kaynaklar paketlenmiş |
imaging.CreateGdPictureImageFromFile(path) |
input.LoadImage(path) |
imaging.CreateGdPictureImageFromStream(stream) |
input.LoadImage(stream) |
imaging.CreateGdPictureImageFromBytes(bytes) |
input.LoadImage(bytes) |
Her kare başına imaging.CloneImage(tiffId) |
input.LoadImageFrames(tiffPath) |
imaging.ReleaseGdPictureImage(imageId) |
using var input = new OcrInput() — otomatik |
ocr.SetImage(imageId) |
Gerekli değil — OcrInput görüntüyü tutar |
ocr.Language = "eng" |
ocr.Language = OcrLanguage.English |
ocr.RunOCR() → resultId dizesi |
ocr.Read(input) → tipli OcrResult |
ocr.GetOCRResultText(resultId) |
result.Text |
ocr.GetOCRResultConfidence(resultId) |
result.Confidence |
ocr.GetOCRResultBlockCount(resultId) |
result.Pages[i].Paragraphs.Count |
ocr.GetOCRResultBlockLineWordText(resultId, b, l, w) |
result.Words[i].Text |
imaging.GetStat() / ocr.GetStat() |
Standart .NET istisnaları |
Her çağrıdan sonra GdPictureStatus.OK kontrol |
Gerekli değil — istisnalar yayılır |
pdf.OcrPage("eng", resourcePath, "", 200) |
result.SaveAsSearchablePdf(outputPath) |
pdf.RenderPageToGdPictureImage(200, false) |
Gerekli değil —IronOCR dahili olarak işler |
pdf.SelectPage(i) |
Gerekli değil — tüm sayfalar varsayılan olarak işlenir |
pdf.GetPageCount() |
result.Pages.Count |
Task.Run(() => ocr.RunOCR()) + SemaphoreSlim |
await ocr.ReadAsync(input) |
Yaygın Göç Sorunları ve Çözümleri
Sorun 1: Yeniden Düzenlemeden Sonra Kodda Kalan Görüntü ID Değişkenleri
GdPicture.NET: Mevcut kod, yöntemlerin üstünde int imageId ilan eder, bunu try/finally üzerinden izler ve bunu birden fazla GdPicture çağrısına geçirir. GdPicture çağrıları değiştirildikten sonra, bu değişkenler ve onların ReleaseGdPictureImage çağrıları yetim ölü kod haline gelir.
Çözüm: Tüm resim ID desenini kaldırın. Beyanı, try, finally ve bırakma çağrısını bir using var input = new OcrInput() bloğu ile değiştirin. Kaldırılması gereken her temizlik çağrısını bulmak için ReleaseGdPictureImage'yi grep ile arayın:
grep -rn "ReleaseGdPictureImage\|imageId\|resultId" --include="*.cs" .
grep -rn "ReleaseGdPictureImage\|imageId\|resultId" --include="*.cs" .
// Remove all of this
int imageId = _imaging.CreateGdPictureImageFromFile(path);
try
{
_ocr.SetImage(imageId);
string resultId = _ocr.RunOCR();
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
// Replace with
using var input = new OcrInput();
input.LoadImage(path);
return new IronTesseract().Read(input).Text;
// Remove all of this
int imageId = _imaging.CreateGdPictureImageFromFile(path);
try
{
_ocr.SetImage(imageId);
string resultId = _ocr.RunOCR();
return _ocr.GetOCRResultText(resultId);
}
finally
{
_imaging.ReleaseGdPictureImage(imageId);
}
// Replace with
using var input = new OcrInput();
input.LoadImage(path);
return new IronTesseract().Read(input).Text;
' Remove all of this
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(path)
Try
_ocr.SetImage(imageId)
Dim resultId As String = _ocr.RunOCR()
Return _ocr.GetOCRResultText(resultId)
Finally
_imaging.ReleaseGdPictureImage(imageId)
End Try
' Replace with
Using input As New OcrInput()
input.LoadImage(path)
Return New IronTesseract().Read(input).Text
End Using
Sorun 2: Dağıtılmış Ortamda KaynakKlasör Yolu Bulunamıyor
GdPicture.NET: _ocr.ResourceFolder'de ayarlanan yol geliştirme makinesinde çözülür ancak üretimde başarısız olur. Yaygın belirtiler, eksik dosyayı adlandırmayan sessiz OCR hataları veya genel GdPictureStatus hatalarıdır.
Çözüm: ResourceFolder atamasını tamamen kaldırın. İngilizce desteği IronOCR NuGet paketine yerleştirilmiştir. Ek diller NuGet paketleri olarak yüklenir. Yapılandırılacak veya dağıtılacak bir dosya sistemi yolu yoktur:
# Remove the filesystem folder from deployment artifacts
# Add language NuGet packages to the project instead
:InstallCmd dotnet add package IronOcr.Languages.French, IronOcr.Languages.German
# Remove the filesystem folder from deployment artifacts
# Add language NuGet packages to the project instead
:InstallCmd dotnet add package IronOcr.Languages.French, IronOcr.Languages.German
Sorun 3: GdPictureStatus Hata İşlemesi İstisnalarla Değiştirildi
GdPicture.NET: Her işlem, hemen kontrol edilmesi gereken bir GdPictureStatus enum değeri döndürür veya ayarlar. Kod if (status != GdPictureStatus.OK) sınırları ile yoğundur. Bazı durum kodları genel olup (ör., Error, InvalidParameter) ve kök nedeni belirlemek için belgeleri incelemek gerektirir.
Çözüm:IronOCR türlenmiş .NET istisnaları fırlatır. Durum kontrollerini try/catch blokları ile değiştiril. Standart IOException ve FileNotFoundException giriş hatalarını kapsar; IronOcr.Exceptions.OcrException OCR'ye özgü hataları kapsar. Önerilen hata işleme desenleri için IronTesseract kurulum kılavuzunu okuyun:
try
{
var result = new IronTesseract().Read(imagePath);
return result.Text;
}
catch (FileNotFoundException ex)
{
_logger.LogError("Input file missing: {Path}", ex.FileName);
throw;
}
catch (IronOcr.Exceptions.OcrException ex)
{
_logger.LogError("OCR processing failed: {Message}", ex.Message);
throw;
}
try
{
var result = new IronTesseract().Read(imagePath);
return result.Text;
}
catch (FileNotFoundException ex)
{
_logger.LogError("Input file missing: {Path}", ex.FileName);
throw;
}
catch (IronOcr.Exceptions.OcrException ex)
{
_logger.LogError("OCR processing failed: {Message}", ex.Message);
throw;
}
Imports IronOcr
Imports System.IO
Try
Dim result = New IronTesseract().Read(imagePath)
Return result.Text
Catch ex As FileNotFoundException
_logger.LogError("Input file missing: {Path}", ex.FileName)
Throw
Catch ex As IronOcr.Exceptions.OcrException
_logger.LogError("OCR processing failed: {Message}", ex.Message)
Throw
End Try
Sorun 4: GdPicture14 Ad Alanı Çeşitli Dosyalarda
GdPicture.NET: Ad alanındaki sürüm numarası, onlarca dosyada projeyi kapsayan using GdPicture14; direktifi olduğu anlamına gelir. Geçiş sonrasında, bunlar hepsi using IronOcr; ile değiştirilmelidir.
Çözüm: Tüm .cs dosyalarında küresel bir bul ve değiştir kullanın, ardından hiçbir GdPicture referansı kalmadığını doğrulayın:
# Find all files with GdPicture namespace
grep -rln "using GdPicture" --include="*.cs" .
# After replacing, verify nothing remains
grep -rn "GdPicture14\|GdPictureOCR\|GdPictureImaging\|GdPicturePDF" --include="*.cs" .
# Find all files with GdPicture namespace
grep -rln "using GdPicture" --include="*.cs" .
# After replacing, verify nothing remains
grep -rn "GdPicture14\|GdPictureOCR\|GdPictureImaging\|GdPicturePDF" --include="*.cs" .
Sorun 5: TIFF Çerçeve Sayısı Mantığı
GdPicture.NET: TIFF karelerini yineleyen kod, dosyanın nasıl yüklendiğine bağlı olarak sıklıkla GdPictureImaging.GetPageCount(imageId) ve GdPicturePDF.GetPageCount() arasında çağrıları karıştırır. Çerçeve dizini 1 tabanlıdır.
Çözüm: input.LoadImageFrames(path) tüm kareleri otomatik olarak yönetir. Mevcut kodunuz sadece belirli kareleri işliyorsa, sıfır tabanlı indeks dizisi ile input.LoadImageFrames(path, frameNumbers) kullanın. Kare başına sonuçlara, aynı zamanda sıfır-indeksli olan result.Pages aracılığıyla erişin. TIFF giriş kılavuzu dizin davranışını açıkça belgeler.
Sorun 6: Ön İşleme Belge Görüntüleme Eklentisi Gerektirir
GdPicture.NET: İtiraz etme ve lekeleri silme işlemleri, ayrı bir lisans satın alımı gerektiren GdPictureDocumentImaging eklentisine aittir. Eklentiyi atlayan ekipler, kaymış veya gürültülü sayfalara sahip taranmış belgelerde sıklıkla OCR doğruluk sorunları yaşar.
Çözüm:IronOCR ön işleme yöntemleri temel paketin bir parçasıdır. Deskew() ve DeNoise() direkt olarak OcrInput üzerine ekleyin. görüntü kalitesi düzeltme kılavuzu, aşırı şekilde bozulmuş taramalar için mevcut tüm filtreleri, Contrast(), Sharpen(), Binarize() ve DeepCleanBackgroundNoise() dahil, içerir.
using var input = new OcrInput();
input.LoadImage("scanned-document.tiff");
input.Deskew(); // no separate plugin license
input.DeNoise();
input.Contrast();
var result = new IronTesseract().Read(input);
using var input = new OcrInput();
input.LoadImage("scanned-document.tiff");
input.Deskew(); // no separate plugin license
input.DeNoise();
input.Contrast();
var result = new IronTesseract().Read(input);
Imports IronOcr
Using input As New OcrInput()
input.LoadImage("scanned-document.tiff")
input.Deskew() ' no separate plugin license
input.DeNoise()
input.Contrast()
Dim result = New IronTesseract().Read(input)
End Using
GdPicture.NET Geçiş Kontrol Listesi
Öncesi-Geçiş
Değişiklik yapmadan önce kod tabanını inceleyerek her GdPicture bağımlılığını bulun:
# Find all GdPicture namespace imports
grep -rn "using GdPicture" --include="*.cs" .
# Find all image ID creation points
grep -rn "CreateGdPictureImageFromFile\|CreateGdPictureImageFromStream\|RenderPageToGdPictureImage\|CloneImage" --include="*.cs" .
# Find all release calls — these map to using block boundaries
grep -rn "ReleaseGdPictureImage" --include="*.cs" .
# Find all resource folder assignments
grep -rn "ResourceFolder" --include="*.cs" .
# Find all OCR result ID accesses
grep -rn "RunOCR\|GetOCRResult\|resultId" --include="*.cs" .
# Find all GdPictureStatus checks
grep -rn "GdPictureStatus\|GetStat()" --include="*.cs" .
# Count GdPicture-dependent files
grep -rln "GdPicture14" --include="*.cs" . | wc -l
# Find all GdPicture namespace imports
grep -rn "using GdPicture" --include="*.cs" .
# Find all image ID creation points
grep -rn "CreateGdPictureImageFromFile\|CreateGdPictureImageFromStream\|RenderPageToGdPictureImage\|CloneImage" --include="*.cs" .
# Find all release calls — these map to using block boundaries
grep -rn "ReleaseGdPictureImage" --include="*.cs" .
# Find all resource folder assignments
grep -rn "ResourceFolder" --include="*.cs" .
# Find all OCR result ID accesses
grep -rn "RunOCR\|GetOCRResult\|resultId" --include="*.cs" .
# Find all GdPictureStatus checks
grep -rn "GdPictureStatus\|GetStat()" --include="*.cs" .
# Count GdPicture-dependent files
grep -rln "GdPicture14" --include="*.cs" . | wc -l
Kodu değiştirmeden önce aşağıda belirtilenleri belgeleyin:
- Hangi dosyalar
GdPictureImaging,GdPictureOCR, veGdPicturePDFreferansları içerir - Kaç farklı resim ID oluşturma/salma çifti vardır
- Belg Imaging Plugin kullanılıyor mu (deskew, despeckle)
- Hangi dil
traineddatadosyaları kaynak klasöründe bulunmaktadır - Kaynak klasör yolunu referans eden hangi dağıtım komut dosyaları veya Docker dosyaları
Kod Geçişi
- Proje dosyasından tüm GdPicture NuGet paketlerini kaldırın
IronOcr'i NuGet üzerinden yükleyin- Önceden kaynak klasöründe bulunan her dil için
IronOcr.Languages.*paketlerini yükleyin IronOcr.License.LicenseKey = "..."'iProgram.csveyaStartup.cs'a ekleyinLicenseManager.RegisterKEY()çağrısını ve lisans yöneticisi nesnesini kaldırın- Tüm
GdPictureImagingalan tanımları ve yapılandırıcı başlatmalarını kaldırın - Tüm
GdPictureOCRalan tanımları veResourceFolderatamasını kaldırın - OCR iş akışları için kullanılan tüm
GdPicturePDFalan tanımlarını kaldırın - Her
int imageId = _imaging.CreateGdPictureImage*(...)bloğunuusing var input = new OcrInput(); ile değiştirin; input.Load*(...)ile değiştirin - Her
_ocr.SetImage(imageId); _ocr.Language = "..."; string resultId = _ocr.RunOCR();withvar result = new IronTesseract().Read(input); _ocr.GetOCRResultText(resultId)'iresult.Textile değiştirin- Tüm
_imaging.ReleaseGdPictureImage(imageId)çağrılarını kaldırın GdPictureStatusdenetimlerini try/catch blokları ile değiştirin- TIFF çerçeve döngülerini
input.LoadImageFrames(path)ile değiştirin pdf.OcrPage(...)+pdf.SaveToFile(...)'yiresult.SaveAsSearchablePdf(outputPath)ile değiştirin- Dağıtım komut dosyalarındaki ve Docker görüntülerindeki kaynak klasörü yolunu kaldırın
using GdPicture14;'yi tüm etkilenen dosyalar boyuncausing IronOcr;ile güncelleyin
Geçiş Sonrası
Tüm kod değişikliklerini tamamladıktan sonra üretime dağıtmadan önce aşağıdaki adımları doğrulayın:
- Tek bir görüntü OCR'ı, kaldırılan bileşenlerden
NullReferenceExceptionolmadan beklenen metni döndürür - Çok sayfalı TIFF işleme, tüm çerçeveleri kapsar ve
result.Pagesaracılığıyla sayfa başına metin üretir - PDF OCR, 50'den fazla belge içeren bir toplu işte bellek artışı olmadan tüm sayfaları işler
- Akış girişi,
MemoryStreamveFileStream'yı ara dosya yazımları olmadan kabul eder - Eşzamanlı Toplu İşleme, döngü engellemeden paralel toplu işlemeye ASP.NET Core istek işleyicileriyle entegre olur
Parallel.ForEachile paralel toplu işleme, tüm iş parçacıkları arasında doğru sonuçlar üretir- Tüm dil paketleri (Fransızca, Almanca vb.) NuGet paketleri üzerinden doğru şekilde etkinleştirilir
- Ön işleme filtreleri (deskew, denoise), taranmış belgeler üzerindeki doğruluğu artırır
- Aranabilir PDF çıktısı, PDF görüntüleyicileri ve metin arama uygulamaları tarafından okunabilir
- Taşınma sonrası hiçbir
.csdosyasında GdPicture ad alanı referansı kalmaz - Bellek profili tutarlı kullanım gösterir (kaçan resim ayırmaları yok) ve uzun süreli yük altında sabit kalır
- Dağıtım Linux ve Docker hedeflerinde dosya sistemi yol hataları olmadan başarılı olur
IronOCR'a Geçişin Ana Faydaları
Derleyici Tarafından Dayatılan Bellek Güvenliği. GdPicture, geliştiricilerin manuel olarak sürdürmesini gerektiren resim ID yaşam döngüsü tamamen ortadan kalkar. OcrInput, IDisposable'yi uygular ve using blokları her kapsamın sonunda — istisna yollarını da içeren temizlik sağlamak için yürütülür. Bakımı yapılacak List<int> yok, hatırlanacak finally blokları yok, kaçırılan salınım çağrılarından üretim bellek olayları yok.
Her OCR Senaryosu için Tek Paket. Görüntü OCR, PDF OCR, çok sayfalı TIFF işleme, arama yapılabilir PDF oluşturma, ön işleme filtreleri, barkod okuma ve 125+ dil paketi tümü IronOcr NuGet paketinden ve onun dil yardımcılarından kullanılabilir. Sık kullanılan bir iş akışı mümkün olmadan önce ikinci ya da üçüncü lisans satın alınmasını gerektiren bir özellik kapısı yoktur. Tüm yetenek listesi için IronOCR özellik genel bakışını okuyun.
Yerel Eşzamansızlık ve İş Parçacığı Güvenliği. ReadAsync gerçek bir eşzamansız yöntemdir, bir Task.Run sarmalayıcı değildir. IronTesseract senkronizasyon olmadan iş parçacıkları arasında kullanmak için güvenlidir. Önceleri iş parçacığı başına bileşen başlatma ve semafor serileştirmesi gerektiren belge işleme hizmetleri, Parallel.ForEach ile tek bir paylaşılan örneğe indirgenir. Hem ASP.NET Core hem de barındırılan hizmet desenlerini kapsayan async OCR kılavuzu bulunmaktadır.
Sıfır Dağıtım Yapılandırması. IronOCR, dosya sistemi yollarına, dış dil dosyalarına, yerel ikili yerleştirmelerine veya dağıtım komut dosyalarına ihtiyaç duymaz. NuGet geri yükleme adımı uygulamanın ihtiyacı olan her şeyi sağlar. Docker görüntüleri, Azure App Service dağıtımları ve Linux sunucuları hepsi geliştirme makinesi ile aynı şekilde çalışır. Docker dağıtım kılavuzu ve Azure dağıtım kılavuzu üretime hazır yapılandırmaları göstermektedir.
Sürüm Sabit Ad Alanı. using IronOcr, büyük sürüm yayınları arasında değişmemiştir. NuGet sürüm numaraları, standart paket yönetimi modeli aracılığıyla sürüm kontrolünü sağlar. Gelecek büyük güncellemeler, ad alanı ithalatını tüm kod tabanında bul ve değiştir gerektirmez.
Öngörülebilir Süresiz Lisanslama. IronOCR, $999 (Lite), $1,499 (Plus), $2,999 (Professional) ve $5,999 (Unlimited) fiyatlarıyla bir defalık süresiz alımlar olarak fiyatlandırılır ve bir yıl güncellemeleri kapsar, yıllık isteğe bağlı yenileme ile. Tüm özellikler her seviyede mevcuttur. Özellik başına eklentiler, sayfa başına maliyetler ve ilk yıldan sonraki bakım zorunluluğu yoktur. Daha önce sadece OCR işlerliği için GdPicture eklenti lisanslarına 8.000 $'dan fazla harcama yapan ekipler lisans süresi içinde bu farkı kapatır. Tam fiyat bilgileri IronOCR lisanslama sayfasında mevcuttur.
Sıkça Sorulan Sorular
GdPicture.NET OCR'dan neden IronOCR'a 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.
GdPicture.NET OCR'dan IronOCR'a geçişteki ana kod değişiklikleri nelerdir?
GdPicture.NET başlatma dizilerini IronTesseract oluşturma ile değiştirin, COM yaşam döngüsü yönetimini (açık Oluştur/Yükle/Kapat desenleri) kaldırın ve sonuç özellik adlarını güncelleyin. Sonuç, önemli ölçüde daha az sablon 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, GdPicture.NET OCR'nin standart iş belgeleri için OCR doğruluğuna eşit midir?
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, GdPicture.NET OCR'nin ayrı olarak yüklediği dil verilerini nasıl ele alır?
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.
GdPicture.NET OCR'dan IronOCR'a geçiş, dağıtım altyapısında değişiklikler gerektirir mi?
IronOCR, GdPicture.NET OCR'dan daha az altyapı değişikliği gerektirir. SDK ikili yolları, lisans dosyası yerleştirmeleri veya lisans sunucu yapılandırmaları yoktur. NuGet paketi, tamamıyla OCR motorunu içerir ve lisans anahtarı uygulama kodunda bir dize olarak ayarlanır.
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 GdPicture.NET 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'un fiyatlandırması, GdPicture.NET OCR'dan daha öngörülebilir mi? İş yüklerini artırırken?
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.
GdPicture.NET OCR'dan IronOCR'a geçişten sonra mevcut testlerime ne olur?
Çı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.

