ABBYY FineReader'dan IronOCR'a Geçiş
Bu kılavuz .NET geliştiricileriniABBYY FineReader EngineSDK'yı IronOCR ile değiştirmek üzere adım adım yönlendirir. COM bağımlılıklarını ve SDK yükleyici kalıntılarını kaldırma mekanik adımlarını kapsar, ABBYY'nin API'sini IronOCR eşdeğerleriyle eşleştirir ve üretim ABBYY entegrasyonlarında en sık rastlanılan desenler için öncesi/sonrası kod örnekleri sağlar. Geçiş, projeleri için ABBYY'nin kurumsal maliyet ve dağıtım karmaşıklığının artık uygun olmadığını belirleyen ekipleri hedefler.
Neden ABBYY FineReader'dan Geçiş Yapılmalı
ABBYY FineReader Engine, yetenekli bir OCR platformu, ancak mimarisi, özel altyapı ekiplerine sahip kurumsal Windows mağazaları için tasarlanmıştı. Bir .NET ekibinin gerçek iş yükü fatura işleme, sözleşme dijitalleştirme veya taranmış form çıkarımı olduğunda, bu mimari bir varlık değil, bir yük haline gelir.
COM Interop Borcu Zamanla Artar. .NET'teki her ABBYY entegrasyonu, bir COM birlikte çalışabilirlik katmanı üzerinden çalışır. COM nesneleri açık bir yaşam döngüsü yönetimi gerektirir: oluşturma, başlatma, işleme, ardından bir finally bloğunda kapama veya süreç hafıza kaçağı yapar. ABBYY'ye dokunan her kod yolu bu deseni taşır. İki veya üç yıldır özellik eklemeleri ile, yaşam döngüsü ritüeli hizmet sınıflarına, arka plan çalışanlarına ve istek işleyicilere yayılır. Sonuç, her OCR ile ilgili sınıfta %30-50 oranında standard kod öbeği olacaktır ki IronTesseract'e geçtiğinizde tamamen ortadan kalkar.
SDK Yükleyicisi Modern Dağıtım Desenlerini Engeller. ABBYY, ikili dosyalarını, dil verilerini, çalışma zamanı dosyalarını ve lisans dosyalarını kodlanmış yollara yerleştiren bir Windows SDK yükleyicisi aracılığıyla dağıtılır. ABBYY kullanan bir hizmeti kapsülleştirmek ya o kurulum çıktısından 300+ MB özel bir temel imaj oluşturmayı ya da başlatma sırasında lisans dosyalarıyla hacimleri bağlamayı gerektirir. Hiçbiri standart bir Kubernetes veya bulut-yerel hattına uymaz.IronOCR bir NuGet paketidir: diğer tüm bağımlılıkları çeken aynı dotnet restore, OCR motorunun tamamını da çeker.
Sayfa Başı Lisanslama, Hacmi Bir Maliyet Merkezi Haline Getirir. ABBYY'nin hacme dayalı lisanslama modelleri, belirli eşikleri aşan işleme başına sayfa başına ücret alır. Başlangıçta ayda 50.000 belge işleyen ve iki yıl sonra 500.000'e ulaşan bir uygulama, başarısına doğrudan orantılı olarak artan OCR maliyetlerine sahiptir. IronOCR, lisans için sabit bir ücret alır — ayda iki milyon sayfa işleyen bir ekip, iki bin sayfa işleyen bir ekiple aynı lisans maliyetini öder.
Dil Verileri Manuel Dağıtım Koordinasyonu Gerektirir. ABBYY dil paketleri, SDK çalışma zamanı dizininde dosyalar olarak bulunur. Bir dil eklemek, doğru veri dosyalarını belirlemeyi, bunları her dağıtım hedefinde doğru yola kopyalamayı ve CI/CD komut dosyalarını onları içermesi için güncellemeyi gerektirir. IronOCR'de Fransızca eklemek dotnet add package IronOcr.Languages.French gibidir — paket yöneticisi geri kalanını halleder.
Lisans Dosyası Hataları Uyarısız Üretime Vurur. ABBYY lisansları .lic ve .key dosyaları olarak belirli disk yollarında bulunmalı ve loader.GetEngineObject() çalıştığında mevcut olmalıdır. Bu dosyalar, yeni bir üretim sunucusunda eksikse — yanlış dağıtım komut dosyası, başarısız dosya kopyası, izin sorunu — çağrı başlangıçta atılır. Süresi dolmuş bir lisans da aynı şekilde başarısız olur. IronOCR'nin lisanslaması, başlatıcı kodda atanan, herhangi bir gizli yöneticiye kaydedilebilen bir string anahtardır, uygulama trafik kabul etmeden önce IronOcr.License.IsValidLicense tarafından doğrulama kontrolü yapılır.
Thread Güvenliği, Tek Bir Paylaşılmış Motor Örneği Gerektirir. ABBYY'nin motoru birden fazla thread'den eşzamanlı CreateFRDocument çağrıları için kolayca thread güvenli değildir. Üretim uygulamaları, kilit stratejileri veya işlemci havuzları kullanır. IronOCR'nin IronTesseract durumsuzdur: her thread başına bir örnek açın, kilitleme olmadan eşzamanlı olarak tanıma işlemi gerçekleştirin ve tamamlandığında kapatın.
Temel Sorun
// ABBYY: COM loader + license path validation + profile load — before a single pixel of OCR runs
var loader = new EngineLoader();
var engine = loader.GetEngineObject(
@"C:\Program Files\ABBYY SDK\FineReader Engine\Bin", // Breaks on every new machine
@"C:\Program Files\ABBYY SDK\License" // Fails if .lic file is missing
);
engine.LoadPredefinedProfile("DocumentConversion_Accuracy");
var langParams = engine.CreateLanguageParams();
langParams.Languages.Add("English");
// ABBYY: COM loader + license path validation + profile load — before a single pixel of OCR runs
var loader = new EngineLoader();
var engine = loader.GetEngineObject(
@"C:\Program Files\ABBYY SDK\FineReader Engine\Bin", // Breaks on every new machine
@"C:\Program Files\ABBYY SDK\License" // Fails if .lic file is missing
);
engine.LoadPredefinedProfile("DocumentConversion_Accuracy");
var langParams = engine.CreateLanguageParams();
langParams.Languages.Add("English");
' ABBYY: COM loader + license path validation + profile load — before a single pixel of OCR runs
Dim loader As New EngineLoader()
Dim engine = loader.GetEngineObject(
"C:\Program Files\ABBYY SDK\FineReader Engine\Bin", ' Breaks on every new machine
"C:\Program Files\ABBYY SDK\License" ' Fails if .lic file is missing
)
engine.LoadPredefinedProfile("DocumentConversion_Accuracy")
Dim langParams = engine.CreateLanguageParams()
langParams.Languages.Add("English")
// IronOCR: the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
// IronOCR: the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
Imports IronOcr
' IronOCR: the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim ocr As New IronTesseract()
IronOCR ve ABBYY FineReader: Özellik Karşılaştırması
Aşağıdaki tablo, bu geçişi değerlendiren ekipler için ilgili yetenekleri kapsar.
| Özellik | ABBYY FineReader Engine | IronOCR |
|---|---|---|
| Kurulum | SDK yükleyicisi (Windows) | dotnet add package IronOcr |
| Edinim | Satış ile iletişim (4-12 hafta) | Kendi kendine hizmet NuGet |
| Lisanslama Modeli | Enterprise, sunucu başına veya sayfa başına | Sürekli, $999-$2,999 tek seferlik |
| Lisans Yönetimi | .lic + .key diskteki dosyalar |
Kodu veya ortam değişkenindeki dize anahtarı |
| .NET Entegrasyonu | COM interop | Yerel .NET |
| COM Bağımlılığı | Evet | Hayır |
| İş Parçacığı Güvenliği | Kilitleme stratejisi gerektirir | Tam (thread başına bir IronTesseract) |
| Desteklenen Diller | 190+ | 125+ |
| Dil Kurulumu | Çalışma zamanı veri dosyaları SDK yolunda | NuGet dil paketleri |
| PDF Girişi | Evet (CreatePDFFile aracılığıyla) |
Evet (yerel, input.LoadPdf()) |
| Aranabilir PDF Çıktısı | Evet (ihracat hattı) | Evet (result.SaveAsSearchablePdf() ile) |
| Otomatik Ön İşleme | Profil tabanlı | Dahili (Deskew, DeNoise, Contrast, Binarize, Sharpen) |
| Bölge Tabanlı OCR | Bölge nesneleri (CreateZone, SetBounds) |
CropRectangle parametresi |
| Barkod Okuma | Evet | Evet (ocr.Configuration.ReadBarCodes = true ile) |
| Çapraz Platform | Windows, Linux, macOS | Windows, Linux, macOS, Docker, Azure, AWS |
| Docker Dağıtımı | Özel temel resim gereklidir | Standart .NET temel imajı + libgdiplus |
| Güven Skoru | Evet | Evet (result.Confidence ile) |
| İlk OCR Sonuç Süresi | 4-12 hafta (tedarik) | Aynı gün |
Hızlı Başlangıç: ABBYY FineReader'dan IronOCR'a Geçiş
Adım 1: NuGet Paketini Değiştirin
ABBYY FineReader Engine, herhangi bir NuGet paketine sahip değil. SDK'yı kaldırarak ve proje dosyanızdan manuel montaj referansını kaldırarak bunu kaldırın:
<Reference Include="FREngine">
<HintPath>C:\Program Files\ABBYY SDK\FineReader Engine\Bin\FREngine.dll</HintPath>
</Reference>
<Reference Include="FREngine">
<HintPath>C:\Program Files\ABBYY SDK\FineReader Engine\Bin\FREngine.dll</HintPath>
</Reference>
Ardından Visual Studio'nun Referanslar düğümünden FREngine.dll COM birlikte çalışma referansını kaldırın veya proje dosyanızdaki karşılık gelen girdiyi doğrudan silin. NuGet kullanarak IronOCR'u yükleyin:
dotnet add package IronOcr
Adım 2: Ad Alanlarını Güncelleyin
// Before (ABBYY)
using FREngine;
using ABBYY.FineReader;
// After (IronOCR)
using IronOcr;
// Before (ABBYY)
using FREngine;
using ABBYY.FineReader;
// After (IronOCR)
using IronOcr;
Imports IronOcr
Adım 3: Lisansa İzin Verin
OCR çağrılarından önce, uygulama başlangıcında bunu bir kez ekleyin:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Anahtarı, üretim dağıtımları için bir ortam değişkeninde veya gizli yöneticide saklayın:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
Imports System
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
Kod Göç Örnekleri
Bir Windows Hizmetindeki Motor Ömrü vs Stateless IronTesseract
ABBYY'nin motor başlatma töreni, EngineLoader ve IEngine nesneleri oluşturulması maliyetli olduğundan bir hizmet sargısında yer almalıdır. Çoğu üretim entegrasyonu, motoru tek bir hizmette belirgin başlangıç ve yıkım metotları ile sarar.
ABBYY FineReader Yaklaşımı:
using FREngine;
public class DocumentOcrService : IHostedService, IDisposable
{
private IEngine _engine;
public Task StartAsync(CancellationToken cancellationToken)
{
// Step 1: Create loader — requiresCOM interopregistration
var loader = new EngineLoader();
// Step 2: Load engine from SDK path — throws if license files are missing
_engine = loader.GetEngineObject(
@"C:\Program Files\ABBYY SDK\FineReader Engine\Bin",
@"C:\Program Files\ABBYY SDK\License"
);
// Step 3: Load profile before any recognition work
_engine.LoadPredefinedProfile("DocumentConversion_Accuracy");
return Task.CompletedTask;
}
public string ProcessDocument(string imagePath)
{
// Document must be created and destroyed per call
var document = _engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
return document.PlainText.Text;
}
finally
{
document.Close(); // Memory leaks if omitted
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_engine = null; // COM cleanup
return Task.CompletedTask;
}
public void Dispose() => _engine = null;
}
using FREngine;
public class DocumentOcrService : IHostedService, IDisposable
{
private IEngine _engine;
public Task StartAsync(CancellationToken cancellationToken)
{
// Step 1: Create loader — requiresCOM interopregistration
var loader = new EngineLoader();
// Step 2: Load engine from SDK path — throws if license files are missing
_engine = loader.GetEngineObject(
@"C:\Program Files\ABBYY SDK\FineReader Engine\Bin",
@"C:\Program Files\ABBYY SDK\License"
);
// Step 3: Load profile before any recognition work
_engine.LoadPredefinedProfile("DocumentConversion_Accuracy");
return Task.CompletedTask;
}
public string ProcessDocument(string imagePath)
{
// Document must be created and destroyed per call
var document = _engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
return document.PlainText.Text;
}
finally
{
document.Close(); // Memory leaks if omitted
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_engine = null; // COM cleanup
return Task.CompletedTask;
}
public void Dispose() => _engine = null;
}
Imports FREngine
Imports System.Threading
Imports System.Threading.Tasks
Public Class DocumentOcrService
Implements IHostedService, IDisposable
Private _engine As IEngine
Public Function StartAsync(cancellationToken As CancellationToken) As Task Implements IHostedService.StartAsync
' Step 1: Create loader — requires COM interop registration
Dim loader As New EngineLoader()
' Step 2: Load engine from SDK path — throws if license files are missing
_engine = loader.GetEngineObject(
"C:\Program Files\ABBYY SDK\FineReader Engine\Bin",
"C:\Program Files\ABBYY SDK\License"
)
' Step 3: Load profile before any recognition work
_engine.LoadPredefinedProfile("DocumentConversion_Accuracy")
Return Task.CompletedTask
End Function
Public Function ProcessDocument(imagePath As String) As String
' Document must be created and destroyed per call
Dim document = _engine.CreateFRDocument()
Try
document.AddImageFile(imagePath, Nothing, Nothing)
document.Process(Nothing)
Return document.PlainText.Text
Finally
document.Close() ' Memory leaks if omitted
End Try
End Function
Public Function StopAsync(cancellationToken As CancellationToken) As Task Implements IHostedService.StopAsync
_engine = Nothing ' COM cleanup
Return Task.CompletedTask
End Function
Public Sub Dispose() Implements IDisposable.Dispose
_engine = Nothing
End Sub
End Class
IronOCR Yaklaşımı:
using IronOcr;
public class DocumentOcrService
{
//Hayırstartup, no shutdown, no COM lifecycle
// IronTesseract is stateless — create per call or reuse per thread
public string ProcessDocument(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
}
using IronOcr;
public class DocumentOcrService
{
//Hayırstartup, no shutdown, no COM lifecycle
// IronTesseract is stateless — create per call or reuse per thread
public string ProcessDocument(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
}
Imports IronOcr
Public Class DocumentOcrService
'Hayırstartup, no shutdown, no COM lifecycle
' IronTesseract is stateless — create per call or reuse per thread
Public Function ProcessDocument(imagePath As String) As String
Return New IronTesseract().Read(imagePath).Text
End Function
End Class
IronTesseract bir motor yaşam döngüsüne sahip değildir. İlk kullanımda dahili olarak başlatılır ve açık bir kapatma gerektirmez. Barındırılan hizmet sargısı, IEngine alanı ve tüm StopAsync yöntemleri ortadan kalkıyor. Uygulama belgeleri eşzamanlı olarak işliyorsa, her thread kendi IronTesseract örneğini oluşturur — kilitleme gerekmez. IronTesseract kurulum kılavuzu, TesseractVersion ve Configuration özellikleri dahil olmak üzere yapılandırma seçeneklerini kapsar.
Tanıma Dili Kurulumu
ABBYY dil yapılandırması bir LanguageParams nesnesi oluşturmayı, yüklü veri dosyalarıyla eşleşmesi gereken dil adı dizgileri eklemeyi ve bu parametreleri herhangi bir belge işlenmeden önce motora bağlamayı içerir. Her ek dil, çalışma zamanı yolunda konuşlandırılmış karşılık gelen veri dosyalarını gerektirir.
ABBYY FineReader Yaklaşımı:
using FREngine;
// Engine must already be initialized with sdkPath and licensePath
private void ConfigureLanguages(IEngine engine, string[] languageCodes)
{
// Create language parameters object
var langParams = engine.CreateLanguageParams();
// Add each language — string names must match installed data file names
// Missing data file causes runtime failure
foreach (var lang in languageCodes)
{
langParams.Languages.Add(lang); // e.g., "English", "French", "German"
}
// Language params are associated at the profile level, not per-document
// Changing languages requires reloading profile or reinitializing engine
engine.LoadPredefinedProfile("DocumentConversion_Accuracy");
}
public string RecognizeFrenchDocument(IEngine engine, string imagePath)
{
var langParams = engine.CreateLanguageParams();
langParams.Languages.Add("French"); // Requires FrenchLanguage data files at runtime path
var document = engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
return document.PlainText.Text;
}
finally
{
document.Close();
}
}
using FREngine;
// Engine must already be initialized with sdkPath and licensePath
private void ConfigureLanguages(IEngine engine, string[] languageCodes)
{
// Create language parameters object
var langParams = engine.CreateLanguageParams();
// Add each language — string names must match installed data file names
// Missing data file causes runtime failure
foreach (var lang in languageCodes)
{
langParams.Languages.Add(lang); // e.g., "English", "French", "German"
}
// Language params are associated at the profile level, not per-document
// Changing languages requires reloading profile or reinitializing engine
engine.LoadPredefinedProfile("DocumentConversion_Accuracy");
}
public string RecognizeFrenchDocument(IEngine engine, string imagePath)
{
var langParams = engine.CreateLanguageParams();
langParams.Languages.Add("French"); // Requires FrenchLanguage data files at runtime path
var document = engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
return document.PlainText.Text;
}
finally
{
document.Close();
}
}
Imports FREngine
' Engine must already be initialized with sdkPath and licensePath
Private Sub ConfigureLanguages(engine As IEngine, languageCodes As String())
' Create language parameters object
Dim langParams = engine.CreateLanguageParams()
' Add each language — string names must match installed data file names
' Missing data file causes runtime failure
For Each lang In languageCodes
langParams.Languages.Add(lang) ' e.g., "English", "French", "German"
Next
' Language params are associated at the profile level, not per-document
' Changing languages requires reloading profile or reinitializing engine
engine.LoadPredefinedProfile("DocumentConversion_Accuracy")
End Sub
Public Function RecognizeFrenchDocument(engine As IEngine, imagePath As String) As String
Dim langParams = engine.CreateLanguageParams()
langParams.Languages.Add("French") ' Requires FrenchLanguage data files at runtime path
Dim document = engine.CreateFRDocument()
Try
document.AddImageFile(imagePath, Nothing, Nothing)
document.Process(Nothing)
Return document.PlainText.Text
Finally
document.Close()
End Try
End Function
IronOCR Yaklaşımı:
using IronOcr;
// Single language — install IronOcr.Languages.French via NuGet first
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.French;
var result = ocr.Read("french-document.jpg");
Console.WriteLine(result.Text);
// Multiple simultaneous languages — operator overload, no data file management
var multiOcr = new IronTesseract();
multiOcr.Language = OcrLanguage.French + OcrLanguage.German + OcrLanguage.English;
var multiResult = multiOcr.Read("multilingual-contract.jpg");
Console.WriteLine(multiResult.Text);
using IronOcr;
// Single language — install IronOcr.Languages.French via NuGet first
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.French;
var result = ocr.Read("french-document.jpg");
Console.WriteLine(result.Text);
// Multiple simultaneous languages — operator overload, no data file management
var multiOcr = new IronTesseract();
multiOcr.Language = OcrLanguage.French + OcrLanguage.German + OcrLanguage.English;
var multiResult = multiOcr.Read("multilingual-contract.jpg");
Console.WriteLine(multiResult.Text);
Imports IronOcr
' Single language — install IronOcr.Languages.French via NuGet first
Dim ocr As New IronTesseract()
ocr.Language = OcrLanguage.French
Dim result = ocr.Read("french-document.jpg")
Console.WriteLine(result.Text)
' Multiple simultaneous languages — operator overload, no data file management
Dim multiOcr As New IronTesseract()
multiOcr.Language = OcrLanguage.French + OcrLanguage.German + OcrLanguage.English
Dim multiResult = multiOcr.Read("multilingual-contract.jpg")
Console.WriteLine(multiResult.Text)
Dil paketleri, standart NuGet paketleri olarak yüklenir (dotnet add package IronOcr.Languages.French). Manuel olarak konuşlandırılacak veri dosyaları yok, yol yapılandırması yok, diller değiştirildiğinde motor yeniden başlatılması yok. çoklu diller kılavuzu, dilleri birleştirmeyi kapsar ve diller indeksi 125+'ten fazla mevcut paketleri listeler.
Çoklu Çerçeve TIFF İşleme
ABBYY, çok sayfalı TIFF dosyalarını çerçeveleri yineleyerek ve her çerçeveyi ayrı bir belge sayfası olarak ekleyerek işler. Çerçeve sayısı, TIFF nesnesinden alınmalı, ardından her çerçeve belge konteynerine ayrı olarak eklenmelidir.
ABBYY FineReader Yaklaşımı:
using FREngine;
public string ProcessMultiFrameTiff(IEngine engine, string tiffPath)
{
var document = engine.CreateFRDocument();
try
{
// Must add each frame individually — no automatic multi-frame handling
// Page count requires reading the TIFF metadata before processing
var imageInfo = engine.CreateImageInfo();
imageInfo.LoadImageFile(tiffPath);
int frameCount = imageInfo.FrameCount;
for (int i = 0; i < frameCount; i++)
{
// Each frame added with its frame index via image processing params
var imgParams = engine.CreateImageProcessingParams();
imgParams.FrameIndex = i;
document.AddImageFile(tiffPath, imgParams, null);
}
document.Process(null);
return document.PlainText.Text;
}
finally
{
document.Close();
}
}
using FREngine;
public string ProcessMultiFrameTiff(IEngine engine, string tiffPath)
{
var document = engine.CreateFRDocument();
try
{
// Must add each frame individually — no automatic multi-frame handling
// Page count requires reading the TIFF metadata before processing
var imageInfo = engine.CreateImageInfo();
imageInfo.LoadImageFile(tiffPath);
int frameCount = imageInfo.FrameCount;
for (int i = 0; i < frameCount; i++)
{
// Each frame added with its frame index via image processing params
var imgParams = engine.CreateImageProcessingParams();
imgParams.FrameIndex = i;
document.AddImageFile(tiffPath, imgParams, null);
}
document.Process(null);
return document.PlainText.Text;
}
finally
{
document.Close();
}
}
Imports FREngine
Public Function ProcessMultiFrameTiff(engine As IEngine, tiffPath As String) As String
Dim document = engine.CreateFRDocument()
Try
' Must add each frame individually — no automatic multi-frame handling
' Page count requires reading the TIFF metadata before processing
Dim imageInfo = engine.CreateImageInfo()
imageInfo.LoadImageFile(tiffPath)
Dim frameCount As Integer = imageInfo.FrameCount
For i As Integer = 0 To frameCount - 1
' Each frame added with its frame index via image processing params
Dim imgParams = engine.CreateImageProcessingParams()
imgParams.FrameIndex = i
document.AddImageFile(tiffPath, imgParams, Nothing)
Next
document.Process(Nothing)
Return document.PlainText.Text
Finally
document.Close()
End Try
End Function
IronOCR Yaklaşımı:
using IronOcr;
// LoadImageFrames handles multi-frame TIFF automatically
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff");
var ocr = new IronTesseract();
var result = ocr.Read(input);
// Per-page results accessible directly
foreach (var page in result.Pages)
{
Console.WriteLine($"Frame {page.PageNumber}: {page.Text.Length} characters");
Console.WriteLine(page.Text);
}
using IronOcr;
// LoadImageFrames handles multi-frame TIFF automatically
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff");
var ocr = new IronTesseract();
var result = ocr.Read(input);
// Per-page results accessible directly
foreach (var page in result.Pages)
{
Console.WriteLine($"Frame {page.PageNumber}: {page.Text.Length} characters");
Console.WriteLine(page.Text);
}
Imports IronOcr
' LoadImageFrames handles multi-frame TIFF automatically
Using input As New OcrInput()
input.LoadImageFrames("scanned-batch.tiff")
Dim ocr As New IronTesseract()
Dim result = ocr.Read(input)
' Per-page results accessible directly
For Each page In result.Pages
Console.WriteLine($"Frame {page.PageNumber}: {page.Text.Length} characters")
Console.WriteLine(page.Text)
Next
End Using
OcrInput.LoadImageFrames, manuel yineleme olmadan çok sayfalı bir TIFF'teki her kareyi okur. Sonuç, her kare için metin, koordinat verileri ve güvenilirlik dahil result.Pages aracılığıyla sayfa başına erişim sağlar. TIFF giriş kılavuzu, hem çoklu çerçeve TIFF hem de animasyonlu GIF işleme konularını kapsar.
Paralel Toplu İşleme
ABBYY'nin COM tabanlı motoru, bir eşzamanlama stratejisi olmadan birkaç thread'den eşzamanlı CreateFRDocument çağrısı yapmak için güvenli değildir. Üretim toplu işlemcileri genellikle motor örneklerinin bir havuzunu tutar veya kilitleme yoluyla erişimi seri hale getirir. Her iki yaklaşım da IronOCR'nin ortadan kaldırdığı altyapı ekler.
ABBYY FineReader Yaklaşımı:
using FREngine;
using System.Collections.Concurrent;
using System.Threading;
public class AbbyyBatchProcessor
{
// Pool required because engine is not safely concurrent
private readonly SemaphoreSlim _engineLock = new SemaphoreSlim(1, 1);
private IEngine _engine;
public async Task<Dictionary<string, string>> ProcessBatchAsync(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// Must serialize — one document at a time through single engine
foreach (var imagePath in imagePaths)
{
await _engineLock.WaitAsync();
try
{
var document = _engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
results[imagePath] = document.PlainText.Text;
}
finally
{
document.Close();
}
}
finally
{
_engineLock.Release();
}
}
return new Dictionary<string, string>(results);
}
}
using FREngine;
using System.Collections.Concurrent;
using System.Threading;
public class AbbyyBatchProcessor
{
// Pool required because engine is not safely concurrent
private readonly SemaphoreSlim _engineLock = new SemaphoreSlim(1, 1);
private IEngine _engine;
public async Task<Dictionary<string, string>> ProcessBatchAsync(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// Must serialize — one document at a time through single engine
foreach (var imagePath in imagePaths)
{
await _engineLock.WaitAsync();
try
{
var document = _engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
results[imagePath] = document.PlainText.Text;
}
finally
{
document.Close();
}
}
finally
{
_engineLock.Release();
}
}
return new Dictionary<string, string>(results);
}
}
Imports FREngine
Imports System.Collections.Concurrent
Imports System.Threading
Public Class AbbyyBatchProcessor
' Pool required because engine is not safely concurrent
Private ReadOnly _engineLock As New SemaphoreSlim(1, 1)
Private _engine As IEngine
Public Async Function ProcessBatchAsync(imagePaths As String()) As Task(Of Dictionary(Of String, String))
Dim results As New ConcurrentDictionary(Of String, String)()
' Must serialize — one document at a time through single engine
For Each imagePath In imagePaths
Await _engineLock.WaitAsync()
Try
Dim document = _engine.CreateFRDocument()
Try
document.AddImageFile(imagePath, Nothing, Nothing)
document.Process(Nothing)
results(imagePath) = document.PlainText.Text
Finally
document.Close()
End Try
Finally
_engineLock.Release()
End Try
Next
Return New Dictionary(Of String, String)(results)
End Function
End Class
IronOCR Yaklaşımı:
using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class OcrBatchProcessor
{
public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// IronTesseract is thread-safe — one instance per thread, fully parallel
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract(); // Each thread owns its instance
var result = ocr.Read(imagePath);
results[imagePath] = result.Text;
});
return new Dictionary<string, string>(results);
}
}
using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class OcrBatchProcessor
{
public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
// IronTesseract is thread-safe — one instance per thread, fully parallel
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract(); // Each thread owns its instance
var result = ocr.Read(imagePath);
results[imagePath] = result.Text;
});
return new Dictionary<string, string>(results);
}
}
Imports IronOcr
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Public Class OcrBatchProcessor
Public Function ProcessBatch(imagePaths As String()) As Dictionary(Of String, String)
Dim results = New ConcurrentDictionary(Of String, String)()
' IronTesseract is thread-safe — one instance per thread, fully parallel
Parallel.ForEach(imagePaths, Sub(imagePath)
Dim ocr = New IronTesseract() ' Each thread owns its instance
Dim result = ocr.Read(imagePath)
results(imagePath) = result.Text
End Sub)
Return New Dictionary(Of String, String)(results)
End Function
End Class
Her IronTesseract örneği bağımsızdır. Parallel.ForEach hiçbir paylaşılan durum, kilit ya da serileştirme olmadan mevcut CPU çekirdeklerini doyurur. ABBYY versiyonu, eşzamanlı sarmalayıcıya rağmen belgeleri sırasıyla işler;IronOCR versiyonu onları gerçekten paralel olarak işler. çok iş parçacığı örneği bu deseni zamanlama karşılaştırmaları ile gösterir. Daha üst düzey throughput kontrolü için hız optimizasyon kılavuzuna bakın.
Belge İhracat Yolu
ABBYY, Export yöntemiyle FileExportFormatEnum değerlerini kullanarak birçok dışa aktarma formatını destekler. DOCX, RTF veya düz metin olarak dışa aktarma, format spesifik dışa aktarma parametre nesneleri oluşturmayı ve ardından uygun enum değeri ve parametre nesnesiyle document.Export çağrısı yapmayı gerektirir.
ABBYY FineReader Yaklaşımı:
using FREngine;
public class AbbyyExporter
{
private IEngine _engine;
public void ExportToMultipleFormats(string imagePath, string outputDir)
{
var document = _engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
string baseName = Path.GetFileNameWithoutExtension(imagePath);
// Export as plain text
document.Export(
Path.Combine(outputDir, baseName + ".txt"),
FileExportFormatEnum.FEF_TextUnicodeDefaults,
null
);
// Export as searchable PDF (requires PDF export params)
var pdfParams = _engine.CreatePDFExportParams();
pdfParams.Scenario = PDFExportScenarioEnum.PDES_Balanced;
pdfParams.UseOriginalPaperSize = true;
document.Export(
Path.Combine(outputDir, baseName + ".pdf"),
FileExportFormatEnum.FEF_PDF,
pdfParams
);
// Export as DOCX
var docxParams = _engine.CreateDOCXExportParams();
document.Export(
Path.Combine(outputDir, baseName + ".docx"),
FileExportFormatEnum.FEF_DOCX,
docxParams
);
}
finally
{
document.Close();
}
}
}
using FREngine;
public class AbbyyExporter
{
private IEngine _engine;
public void ExportToMultipleFormats(string imagePath, string outputDir)
{
var document = _engine.CreateFRDocument();
try
{
document.AddImageFile(imagePath, null, null);
document.Process(null);
string baseName = Path.GetFileNameWithoutExtension(imagePath);
// Export as plain text
document.Export(
Path.Combine(outputDir, baseName + ".txt"),
FileExportFormatEnum.FEF_TextUnicodeDefaults,
null
);
// Export as searchable PDF (requires PDF export params)
var pdfParams = _engine.CreatePDFExportParams();
pdfParams.Scenario = PDFExportScenarioEnum.PDES_Balanced;
pdfParams.UseOriginalPaperSize = true;
document.Export(
Path.Combine(outputDir, baseName + ".pdf"),
FileExportFormatEnum.FEF_PDF,
pdfParams
);
// Export as DOCX
var docxParams = _engine.CreateDOCXExportParams();
document.Export(
Path.Combine(outputDir, baseName + ".docx"),
FileExportFormatEnum.FEF_DOCX,
docxParams
);
}
finally
{
document.Close();
}
}
}
Imports FREngine
Public Class AbbyyExporter
Private _engine As IEngine
Public Sub ExportToMultipleFormats(imagePath As String, outputDir As String)
Dim document = _engine.CreateFRDocument()
Try
document.AddImageFile(imagePath, Nothing, Nothing)
document.Process(Nothing)
Dim baseName As String = Path.GetFileNameWithoutExtension(imagePath)
' Export as plain text
document.Export(
Path.Combine(outputDir, baseName & ".txt"),
FileExportFormatEnum.FEF_TextUnicodeDefaults,
Nothing
)
' Export as searchable PDF (requires PDF export params)
Dim pdfParams = _engine.CreatePDFExportParams()
pdfParams.Scenario = PDFExportScenarioEnum.PDES_Balanced
pdfParams.UseOriginalPaperSize = True
document.Export(
Path.Combine(outputDir, baseName & ".pdf"),
FileExportFormatEnum.FEF_PDF,
pdfParams
)
' Export as DOCX
Dim docxParams = _engine.CreateDOCXExportParams()
document.Export(
Path.Combine(outputDir, baseName & ".docx"),
FileExportFormatEnum.FEF_DOCX,
docxParams
)
Finally
document.Close()
End Try
End Sub
End Class
IronOCR Yaklaşımı:
using IronOcr;
public class OcrExporter
{
public void ExportToMultipleFormats(string imagePath, string outputDir)
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
string baseName = Path.GetFileNameWithoutExtension(imagePath);
// Plain text — direct property access
File.WriteAllText(
Path.Combine(outputDir, baseName + ".txt"),
result.Text
);
// Searchable PDF — one method call, no parameter objects
result.SaveAsSearchablePdf(
Path.Combine(outputDir, baseName + ".pdf")
);
// hOCR format — for document management systems
result.SaveAsHocrFile(
Path.Combine(outputDir, baseName + ".hocr")
);
}
}
using IronOcr;
public class OcrExporter
{
public void ExportToMultipleFormats(string imagePath, string outputDir)
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
string baseName = Path.GetFileNameWithoutExtension(imagePath);
// Plain text — direct property access
File.WriteAllText(
Path.Combine(outputDir, baseName + ".txt"),
result.Text
);
// Searchable PDF — one method call, no parameter objects
result.SaveAsSearchablePdf(
Path.Combine(outputDir, baseName + ".pdf")
);
// hOCR format — for document management systems
result.SaveAsHocrFile(
Path.Combine(outputDir, baseName + ".hocr")
);
}
}
Imports IronOcr
Imports System.IO
Public Class OcrExporter
Public Sub ExportToMultipleFormats(imagePath As String, outputDir As String)
Dim ocr As New IronTesseract()
Dim result = ocr.Read(imagePath)
Dim baseName As String = Path.GetFileNameWithoutExtension(imagePath)
' Plain text — direct property access
File.WriteAllText(
Path.Combine(outputDir, baseName & ".txt"),
result.Text
)
' Searchable PDF — one method call, no parameter objects
result.SaveAsSearchablePdf(
Path.Combine(outputDir, baseName & ".pdf")
)
' hOCR format — for document management systems
result.SaveAsHocrFile(
Path.Combine(outputDir, baseName & ".hocr")
)
End Sub
End Class
IronOCR'nin OcrResult, .Text öğelerini doğrudan açığa çıkarır ve parametre nesneleri veya format enumları olmadan çıktı yöntemleri sağlar. ABBYY'nin üç adımlı parametre/dışa aktarma dizisine karşılık olarak, PDF dışa aktarmayı tek satırda yönetir SaveAsSearchablePdf. arama yapılabilir PDF kılavuzu, sayfa aralığı seçeneklerini ve sıkıştırma ayarlarını kapsar. hOCR ihracat kılavuzu, konum-bilinçli OCR çıktısını tüketen sistemler için HOCR formatını kapsar.
ABBYY FineReader API,IronOCR Eşlem Referansı
| ABBYY FineReader Engine | IronOCR Karşılığı |
|---|---|
new EngineLoader() |
Gerekli değil |
loader.GetEngineObject(sdkPath, licensePath) |
new IronTesseract() |
engine.LoadPredefinedProfile("...") |
Gerekli değil (dahili olarak ele alınır) |
engine.CreateLanguageParams() |
Gerekli değil |
langParams.Languages.Add("French") |
ocr.Language = OcrLanguage.French |
langParams.Languages.Add("English") + langParams.Languages.Add("German") |
ocr.Language = OcrLanguage.English + OcrLanguage.German |
engine.CreateFRDocument() |
new OcrInput() |
engine.CreateFRDocumentFromImage(path, null) |
ocr.Read(path) |
document.AddImageFile(path, null, null) |
input.LoadImage(path) |
imageInfo.LoadImageFile(tiff) + frameCount döngüsü |
input.LoadImageFrames(tiff) |
engine.CreatePDFFile() sonra pdfFile.Open(path, null, null) |
input.LoadPdf(path) |
document.Process(null) |
ocr.Read(input) |
document.PlainText.Text |
result.Text |
frDocument.Pages[i].PlainText.Text |
result.Pages[i].Text |
page.Layout.Blocks + BlockTypeEnum.BT_Table kontrolü |
result.Pages + kelime koordinat verileri |
block.GetAsTableBlock() |
result.Pages[i].Lines (koordinatlarla birlikte) |
engine.CreatePDFExportParams() |
Gerekli değil |
document.Export(path, FEF_PDF, params) |
result.SaveAsSearchablePdf(path) |
document.Export(path, FEF_TextUnicodeDefaults, null) |
File.WriteAllText(path, result.Text) |
engine.CreateDOCXExportParams() + Dışa Aktarma |
Doğrudan desteklenmez |
document.Close() |
using tarafından OcrInput üzerinde yönetilir |
_engine.GetLicenseInfo().ExpirationDate |
IronOcr.License.IsValidLicense |
Lisans dosyaları (ABBYY.lic, ABBYY.key) |
IronOcr.License.LicenseKey = "key" |
engine.CreateZone() + zone.SetBounds(x, y, w, h) |
new CropRectangle(x, y, width, height) |
Yaygın Göç Sorunları ve Çözümleri
Sorun 1: SDK'yı Kaldırdıktan Sonra COM Kayıt Hataları
ABBYY: Proje referanslarından FREngine.dll kaldırıldıktan sonra bile, sınıfların eski ad alanını koruduğu için Could not load type 'FREngine.EngineLoader' veya COM birlikte çalışma hatalarıyla yapının başarısız olabileceğini unutmayın.
Çözüm: Referansı kaldırmadan önce tüm FREngine ve ABBYY.FineReader kullanımlarını arayın. Özellikle bir IEngine alanını iptal etmek için uygulanan her sınıfın boşaltma mantığı using bloklarıyla OcrInput üzerine değiştirilmelidir:
// Before: explicit Close in finally
var document = _engine.CreateFRDocument();
try { document.Process(null); }
finally { document.Close(); }
// After: using pattern on OcrInput
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = new IronTesseract().Read(input);
// Before: explicit Close in finally
var document = _engine.CreateFRDocument();
try { document.Process(null); }
finally { document.Close(); }
// After: using pattern on OcrInput
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = new IronTesseract().Read(input);
Option Strict On
' Before: explicit Close in finally
Dim document = _engine.CreateFRDocument()
Try
document.Process(Nothing)
Finally
document.Close()
End Try
' After: using pattern on OcrInput
Using input As New OcrInput()
input.LoadImage(imagePath)
Dim result = New IronTesseract().Read(input)
End Using
Sorun 2: Tanıma Profili Karşılığı Yok
ABBYY: engine.LoadPredefinedProfile("DocumentConversion_Speed") veya engine.LoadPredefinedProfile("FieldLevelRecognition") çağrıları yapan kod, doğruluk ve hız arasında denge kurmak için ABBYY'e özgü profiller kullanır. Profile adında bir IronOCR eşdeğer özelliği yoktur.
Çözüm: IronOCR, IronTesseract.Configuration aracılığıyla aynı değiş-tokuşları yapar. Hız optimizasyonu için, ocr.Configuration.TesseractVersion = TesseractVersion.Tesseract5 ayarlayın (varsayılan) ve ön işleme filtrelerini azaltın. Maksimum doğruluk için tam ön işlem hattını ekleyin:
// Speed-optimized
var ocr = new IronTesseract();
//Hayırpreprocessing — fastest path
var result = ocr.Read("clean-document.jpg");
// Accuracy-optimized for difficult inputs
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("degraded-scan.jpg");
input.Deskew();
input.DeNoise();
input.Contrast();
input.Binarize();
var result = ocr.Read(input);
// Speed-optimized
var ocr = new IronTesseract();
//Hayırpreprocessing — fastest path
var result = ocr.Read("clean-document.jpg");
// Accuracy-optimized for difficult inputs
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("degraded-scan.jpg");
input.Deskew();
input.DeNoise();
input.Contrast();
input.Binarize();
var result = ocr.Read(input);
Imports IronTesseract
' Speed-optimized
Dim ocr As New IronTesseract()
' Hayırpreprocessing — fastest path
Dim result = ocr.Read("clean-document.jpg")
' Accuracy-optimized for difficult inputs
Dim ocr As New IronTesseract()
Using input As New OcrInput()
input.LoadImage("degraded-scan.jpg")
input.Deskew()
input.DeNoise()
input.Contrast()
input.Binarize()
Dim result = ocr.Read(input)
End Using
görüntü kalitesi düzeltme kılavuzu, hangi filtrelerin hangi girdi kalitesi sorunlarını çözdüğünü açıklar. hız optimizasyon kılavuzu, temiz belgelerde işleme süresini azaltan konfigürasyon özelliklerini kapsar.
Sorun 3: Lisans Dosyası Dağıtım Adımı CI/CD'de Kalmaktadır
ABBYY: Yapı hatları genellikle bir ABBYY.lic ve ABBYY.key güvenli bir depodan dağıtım hedefine kopyalayan bir adım içerir. Geçişten sonra, ekipler bazen bu adımı kaldırmayı unutur ve artık mevcut olmayan yolları referans alan ölü dağıtım kodu bırakır.
Çözüm: Lisans dosyası kopyalama adımını tamamen kaldırın. Onun yerine bir ortam değişkeni enjeksiyon adımı ekleyin:
# Remove these CI/CD steps after migration:
# - name: Copy ABBYY license files
# run: |
# cp $SECRETS_PATH/ABBYY.lic $DEPLOY_PATH/License/
# cp $SECRETS_PATH/ABBYY.key $DEPLOY_PATH/License/
# Add this instead (environment variable injection):
# - name: Set IronOCR license
# env:
# IRONOCR_LICENSE_KEY: ${{secrets.IRONOCR_LICENSE}}
# Remove these CI/CD steps after migration:
# - name: Copy ABBYY license files
# run: |
# cp $SECRETS_PATH/ABBYY.lic $DEPLOY_PATH/License/
# cp $SECRETS_PATH/ABBYY.key $DEPLOY_PATH/License/
# Add this instead (environment variable injection):
# - name: Set IronOCR license
# env:
# IRONOCR_LICENSE_KEY: ${{secrets.IRONOCR_LICENSE}}
Ve uygulama başlangıcında:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
?? throw new InvalidOperationException("IRONOCR_LICENSE_KEY not set");
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
?? throw new InvalidOperationException("IRONOCR_LICENSE_KEY not set");
Imports System
IronOcr.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY"), Throw New InvalidOperationException("IRONOCR_LICENSE_KEY not set"))
Sorun 4: Motorun İş Parçacığına Güvenirli Olmaması — Mevcut Kilitleme Kodu
ABBYY: Birden fazla thread'den ABBYY'yi çağıran uygulamalar tipik olarak SemaphoreSlim, lock ifadeleri veya COM birlikte çalışma sorunlarından kaçınmak için thread yerel motor örnekleri içerir. Bu senkronizasyon kodu ABBYY'nin iş parçacığı modeli için uygundur.
Çözüm: ABBYY çağrılarını saran tüm senkronizasyon kodunu silin. IronOCR'nin IronTesseract, thread başına örneklemek için güvenlidir:
// Remove all of this:
// private readonly SemaphoreSlim _engineLock = new SemaphoreSlim(1, 1);
// await _engineLock.WaitAsync();
// try { ... } finally { _engineLock.Release(); }
// Replace with:
Parallel.ForEach(documents, doc =>
{
var ocr = new IronTesseract(); // One per thread — no lock needed
results[doc.Id] = ocr.Read(doc.Path).Text;
});
// Remove all of this:
// private readonly SemaphoreSlim _engineLock = new SemaphoreSlim(1, 1);
// await _engineLock.WaitAsync();
// try { ... } finally { _engineLock.Release(); }
// Replace with:
Parallel.ForEach(documents, doc =>
{
var ocr = new IronTesseract(); // One per thread — no lock needed
results[doc.Id] = ocr.Read(doc.Path).Text;
});
Imports System.Threading.Tasks
Parallel.ForEach(documents, Sub(doc)
Dim ocr = New IronTesseract() ' One per thread — no lock needed
results(doc.Id) = ocr.Read(doc.Path).Text
End Sub)
Sorun 5: CreateImageInfo / FrameCount TIFF Deseni için
ABBYY: Sustalı bir TIFF dosyasından engine.CreateImageInfo() ve imageInfo.LoadImageFile() kullanarak çerçeve sayısını okuyan ve çerçeveler arasında yineleme yapan kod, IronOCR'de doğrudan bir eşdeğerine sahip değildir çünkü OcrInput.LoadImageFrames çerçeve numaralandırmayı dahili olarak halleder.
Çözüm: Çerçeve sayımı döngüsünü tamamen silin:
// Remove:
// var imageInfo = engine.CreateImageInfo();
// imageInfo.LoadImageFile(tiffPath);
// for (int i = 0; i < imageInfo.FrameCount; i++) { document.AddImageFile(...) }
// Replace with:
using var input = new OcrInput();
input.LoadImageFrames("multi-page-scan.tiff");
var result = new IronTesseract().Read(input);
// result.Pages contains one entry per TIFF frame
// Remove:
// var imageInfo = engine.CreateImageInfo();
// imageInfo.LoadImageFile(tiffPath);
// for (int i = 0; i < imageInfo.FrameCount; i++) { document.AddImageFile(...) }
// Replace with:
using var input = new OcrInput();
input.LoadImageFrames("multi-page-scan.tiff");
var result = new IronTesseract().Read(input);
// result.Pages contains one entry per TIFF frame
Imports IronOcr
' Remove:
' Dim imageInfo = engine.CreateImageInfo()
' imageInfo.LoadImageFile(tiffPath)
' For i As Integer = 0 To imageInfo.FrameCount - 1
' document.AddImageFile(...)
' Next
' Replace with:
Using input As New OcrInput()
input.LoadImageFrames("multi-page-scan.tiff")
Dim result = New IronTesseract().Read(input)
' result.Pages contains one entry per TIFF frame
End Using
Sorun 6: DOCX İhracatı İçin Doğrudan Karşılık Yok
ABBYY: document.Export(path, FileExportFormatEnum.FEF_DOCX, docxParams) bir Word belgesi üretir. IronOCR, DOCX çıktısını doğrudan üretmez.
Çözüm:IronOCR aranabilir PDF'ler ve yapılandırılmış veri üretir. DOCX çıktısı gerektiren iş akışları için pratik geçiş yolu, aranabilir bir PDF üretmek ve sonuç olarak dönüştürmek veya yapılandırılmış metni çıkarıp bir Dokümanı DOCX'e yazmak için Open XML SDK gibi bir kütüphane kullanmaktır:
//IronOCR to searchable PDF (closest equivalent)
var result = new IronTesseract().Read(inputPath);
result.SaveAsSearchablePdf(outputPath.Replace(".docx", ".pdf"));
// Or extract structured text for downstream DOCX generation
foreach (var paragraph in result.Paragraphs)
{
Console.WriteLine(paragraph.Text);
// Write to DOCX via Open XML SDK or similar
}
//IronOCR to searchable PDF (closest equivalent)
var result = new IronTesseract().Read(inputPath);
result.SaveAsSearchablePdf(outputPath.Replace(".docx", ".pdf"));
// Or extract structured text for downstream DOCX generation
foreach (var paragraph in result.Paragraphs)
{
Console.WriteLine(paragraph.Text);
// Write to DOCX via Open XML SDK or similar
}
Imports IronOcr
' IronOCR to searchable PDF (closest equivalent)
Dim result = New IronTesseract().Read(inputPath)
result.SaveAsSearchablePdf(outputPath.Replace(".docx", ".pdf"))
' Or extract structured text for downstream DOCX generation
For Each paragraph In result.Paragraphs
Console.WriteLine(paragraph.Text)
' Write to DOCX via Open XML SDK or similar
Next
sonuçları okuma kılavuzu, paragraf, satır, kelime ve karakter seviyesinde koordinat verilerine erişimi kapsar.
ABBYY FineReader Geçiş Kontrol Listesi
Geçiş Öncesi Görevler
Herhangi bir değişiklik yapmadan önce kod tabanını denetleyin:
# Find all files using ABBYY namespaces
grep -r "using FREngine" --include="*.cs" .
grep -r "using ABBYY" --include="*.cs" .
# Find engine lifecycle patterns
grep -r "EngineLoader\|GetEngineObject\|LoadPredefinedProfile" --include="*.cs" .
# Find document lifecycle patterns
grep -r "CreateFRDocument\|document\.Close\|AddImageFile\|document\.Process" --include="*.cs" .
# Find language configuration
grep -r "CreateLanguageParams\|langParams\.Languages" --include="*.cs" .
# Find export calls
grep -r "FileExportFormatEnum\|CreatePDFExportParams\|document\.Export" --include="*.cs" .
# Find license file references in CI/CD and deployment scripts
grep -r "ABBYY\.lic\|ABBYY\.key" .
# Find all files using ABBYY namespaces
grep -r "using FREngine" --include="*.cs" .
grep -r "using ABBYY" --include="*.cs" .
# Find engine lifecycle patterns
grep -r "EngineLoader\|GetEngineObject\|LoadPredefinedProfile" --include="*.cs" .
# Find document lifecycle patterns
grep -r "CreateFRDocument\|document\.Close\|AddImageFile\|document\.Process" --include="*.cs" .
# Find language configuration
grep -r "CreateLanguageParams\|langParams\.Languages" --include="*.cs" .
# Find export calls
grep -r "FileExportFormatEnum\|CreatePDFExportParams\|document\.Export" --include="*.cs" .
# Find license file references in CI/CD and deployment scripts
grep -r "ABBYY\.lic\|ABBYY\.key" .
Her IEngine veya IFRDocument alanı tutan sınıfı belgeleyin. Hangi ihracat biçimlerinin kullanıldığına dikkat edin — DOCX çıktısı alternatif bir yaklaşım gerektirir (Yukarıdaki Sorun 6'ya bakın).
Kod Güncelleme Görevleri
- Tüm
.csprojdosyalarındanFREngine.dllreferansını kaldırın - ABBYY kullanan her projede
dotnet add package IronOcrçalıştırın - Uygulama başlangıcında
IronOcr.License.LicenseKey = ...ekleyin (Program.csveya başlatıcı sınıf) - İngilizce olmayan her dil için dil NuGet paketlerini yükleyin (
dotnet add package IronOcr.Languages.Frenchvs.) - Tüm
EngineLoader,GetEngineObjectveLoadPredefinedProfileçağrılarını silin - Tüm
CreateLanguageParamsvelangParams.Languages.Addçağrılarını silin engine.CreateFRDocument()+document.AddImageFile()+document.Process()yerinenew IronTesseract().Read(path)kullanın- Çok çerçeveli TIFF döngülerini
input.LoadImageFrames(tiffPath)ile değiştirin document.PlainText.Textyerineresult.TextkullanınfrDocument.Pages[i].PlainText.Textyerineresult.Pages[i].Textkullanındocument.Export(..., FEF_PDF, pdfParams)yerineresult.SaveAsSearchablePdf(path)kullanın- Tüm
document.Close()çağrılarınıOcrInputüzerindekiusingbloklarıyla değiştirin SemaphoreSlimve ABBYY motor erişimini seri hale getiren kilitleme kodunu silinengine.CreateZone()/zone.SetBounds()/page.Zones.Add()yerineinput.LoadImage()'a iletilennew CropRectangle(x, y, width, height)kullanın- CI/CD boru hatlarından lisans dosyası kopyalama adımlarını kaldırın
- Docker görüntülerini güncelleyin — SDK yükleme katmanını kaldırın, Linux hedefleri için
libgdiplusekleyin
Geçiş Sonrası Testler
- Her belge türünün (faturalar, sözleşmeler, taranmış formlar) temsilci bir örneğinde metin çıkarma çıktısını doğrulayın
- Çoklu sayfalı TIFF işleminin ABBYY'nin ürettiği çerçeve sayısıyla aynı sayıda sayfa döndüğünü doğrulayın
- ABBYY temel karşılaştırması için kullanılan aynı girdilere karşı çok dilli belgeleri test edin
- Adobe Reader ve tarayıcı PDF görüntüleyicilerinde aranabilir PDF çıktısının metin aranabilir olduğunu doğrulayın
- Üretim eşzamanlılık seviyesiyle paralel toplu işlemciyi çalıştırın ve hata olmadığını doğrulayın
- Kalite kapıları için bir temel eşik oluşturmak adına bilinen iyi belgeler üzerinde
result.Confidencekontrolü yapın - Aşama dağıtım ortamında ortam değişkeninden lisans anahtarı başlatmasını test edin
- ABBYY SDK hacim yüklemesi olmadan Docker görüntüsünün OCR yapıp yapmadığını doğrulayın
- Lisans dosyası kopyalama adımı olmadan CI/CD boru hattının tamamlandığını doğrulayın
- Toplu işlemci üzerinde bir bellek profilini çalıştırarak hiçbir
OcrInputnesnesinin sızmadığını onaylayın (usingyerleşimini doğrulayın)
IronOCR'a Geçişin Ana Faydaları
Karmaşıklık Bir Büyüklük Sırasına Göre Düşer. Her ABBYY dağıtımı SDK kurulumu, lisans dosyası yerleştirme, çalışma zamanı yolu konfigürasyonu ve dosyaların doğru yollarında olduğunu doğrulama gerektiriyordu. IronOCR, bir NuGet bağımlılığı olarak dağıtılır. dotnet publish, OCR motorunu içeren bağımsız bir eser üretir. Docker dağıtım kılavuzu ve Azure kurulum kılavuzu, tam yapıyı gösterir — her ikisi de tek sayfaya sığar.
COM Birlikte Çalışma Gitti. COM katmanının kaldırılması, yeni makinelerdeki COM kayıt hataları, katman iş parçacığı uyumsuzlukları, RCW yaşam döngüsü hataları ve her ABBYY belge işleme çağrısının gerektirdiği 15-25 satırlık try/finally kod öbeği de dahil olmak üzere bir çalışma zamanı hataları kategorisinin tümünü ortadan kaldırır. Kod tabanı küçülür. Hata yüzeyi de küçülür.
Hacim Büyümesi Artık Bütçe Gözden Geçirmelerini Tetiklemez. IronOCR'nin süresiz lisansı, sınırsız belge hacmini kapsar. İlk yıl ayda 10.000 belge işleyen ve üçüncü yılda ayda 2.000.000 belge işleyen bir uygulama, aynı OCR lisanslama maliyetini taşır. Sayfa başına sayaç yok, aşım faturaları yok, hacim kademi yeniden müzakereleri yok. lisanslama sayfası tüm seviyeleri gösterir — 2.999 dolarlık Professional lisansı, çalışan her hacimi işleyen on geliştiriciyi kapsar.
Çapraz Platform Dağıtımı Yeni Altyapı Seçeneklerini Açıyor. ABBYY COM katmanı Windows gerektirir. Belge işleme maliyeti veya yoğunluk nedenleriyle Linux konteynerlerine taşıyan ekipler engellendi. IronOCR, aynı NuGet paketinden Windows, Linux ve macOS üzerinde aynı şekilde çalışır. ABBYY'den geçiş, uygulama yığınının OCR katmanından Windows kısıtlamasını kaldırır. Linux dağıtım kılavuzu ve AWS dağıtım kılavuzu her ortam için tam ayarı kapsar.
Paralel Throughput Ekstra Altyapı Çalışması Olmadan Kullanılabilir. ABBYY motor erişimi seri hale getiren kilit stratejileri yok oldu. IronTesseract örnekleri bağımsızdır: her thread için bir tane oluşturun, bir belge yığını boyunca Parallel.ForEach çalıştırın, sonuçları alın. Throughput, ekstra kod gerekmeksizin mevcut CPU çekirdekleriyle ölçeklenir. çoklu iş parçacığı örneği, çok çekirdekli donanımda duvar saati iyileştirmelerini gösterir.
Dil Konfigürasyonu Bir Paket Referansıdır. Almanca veya Japonca OCR işlevselliğini ABBYY entegrasyonuna eklemek, veri dosyalarını tanımlamayı, her hedef makinedeki çalışma zamanı yollarına dağıtmayı ve dosyaların eksik olması durumunda arıza yönetimini gerektiriyordu.IronOCR ile dotnet add package IronOcr.Languages.German dil paketini sürümlü, tekrarlanabilir bir NuGet bağımlılığı olarak ekler. Paket yöneticisi, her derlemede verinin mevcut olduğunu sağlar. özel dil paketi kılavuzu, uzman alanlar için özel dil modellerinin eğitimini ve konuşlandırmasını kapsar.
Sıkça Sorulan Sorular
Neden ABBYY FineReader Engine'den 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.
ABBYY FineReader Engine'den IronOCR'a geçişteki ana kod değişiklikleri nelerdir?
ABBYY FineReader 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, ABBYY FineReader Engine'in 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, ABBYY FineReader Engine'in 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.
ABBYY FineReader Engine'den IronOCR'a geçiş, dağıtım altyapısında değişiklikler gerektirir mi?
IronOCR, ABBYY FineReader Engine'den 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 ABBYY FineReader 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ı, ABBYY FineReader Engine'den 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.
ABBYY FineReader Engine'den 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.

