IRONSOFTWAREHOME
동영상

ABBYY FineReader에서 IronOCR로 마이그레이션하기

칸나오팟 우돈판트
Kannapat Udonpant
Updated: 2026년 6월 20일

이 가이드는 .NET 개발자가 ABBYY FineReader 엔진 SDK를 IronOCR 로 교체하는 모든 단계를 안내합니다. 이 문서에서는 COM 종속성 및 SDK 설치 프로그램 아티팩트를 제거하는 기계적인 단계, ABBYY API를IronOCR의 해당 기능에 매핑하는 방법, 그리고 실제 ABBYY 통합에서 가장 흔히 발견되는 패턴에 대한 변경 전후 코드 예제를 다룹니다. 마이그레이션은 ABBYY의 Enterprise 비용과 배포 복잡성이 더 이상 프로젝트 요구 사항과 일치하지 않는다고 결정한 팀을 대상으로 합니다.

ABBYY FineReader에서 마이그레이션해야 하는 이유는 무엇일까요?

ABBYY FineReader Engine은 뛰어난 OCR 플랫폼이지만, 그 아키텍처는 전담 인프라 팀을 갖춘 Enterprise Windows 환경에 맞춰 설계되었습니다. .NET 팀의 실제 작업량이 송장 처리, 계약서 디지털화 또는 스캔한 양식 추출과 같은 작업일 경우, 해당 아키텍처는 자산이 아니라 오히려 부담이 됩니다.

COM 상호 운용성 관련 부채는 시간이 지날수록 누적됩니다. 모든 ABBYY .NET 통합은 COM 상호 운용성 계층을 거쳐 실행됩니다. COM 개체는 명시적 수명 주기 관리를 필요로 합니다: finally 블록에서 생성, 초기화, 처리 후 닫아야 하며, 그렇지 않으면 프로세스가 메모리를 누수합니다. ABBYY와 관련된 모든 코드 경로에는 이 패턴이 적용됩니다. 2~3년에 걸친 기능 추가 과정에서 이러한 생명주기 의식은 서비스 클래스, 백그라운드 작업자 및 요청 처리기를 통해 전파됩니다. 결과는 모든 OCR 관련 클래스에서 30-50%의 보일러플레이트를 차지하며, IronTesseract으로 전환하면 완전히 사라집니다.

SDK 설치 프로그램이 최신 배포 패턴을 차단합니다. ABBYY는 바이너리, 언어 데이터, 런타임 파일 및 라이선스 파일을 하드코딩된 경로에 배치하는 Windows SDK 설치 프로그램을 통해 배포합니다. ABBYY를 사용하는 서비스를 컨테이너화하려면 해당 설치 프로그램 출력에서 300MB 이상의 커스텀 베이스 이미지를 만드는 것 또는 시작 시 라이선스 파일을 포함하는 볼륨을 마운트하는 수밖에 없습니다. 이러한 접근 방식은 표준 Kubernetes나 클라우드 네이티브 파이프라인에 적합하지 않습니다. IronOCR은 NuGet 패키지로, 모든 다른 종속성을 가져오는 dotnet restore과 동일한 방식으로 완전한 OCR 엔진을 가져옵니다.

페이지당 라이선스 방식은 처리량에 따라 비용을 발생시킵니다. ABBYY의 볼륨 기반 라이선스 모델은 포함된 임계값을 초과하는 페이지 처리량에 따라 요금을 부과합니다. 출시 당시 월 5만 건의 문서를 처리하던 애플리케이션이 2년 후 50만 건에 도달했을 때, OCR 비용은 성공에 정비례하여 증가했습니다.IronOCR라이선스에 대해 고정 요금을 부과합니다. 즉, 한 달에 200만 페이지를 처리하는 팀과 2천 페이지를 처리하는 팀이 지불하는 라이선스 비용이 동일합니다.

언어 데이터는 수동 배포 조정이 필요합니다. ABBYY 언어 팩은 SDK 런타임 디렉터리에 파일로 존재합니다. 언어를 추가한다는 것은 올바른 데이터 파일을 식별하고, 모든 배포 대상의 올바른 경로에 복사하고, CI/CD 스크립트를 업데이트하여 해당 파일을 포함시키는 것을 의미합니다. IronOCR에서 프랑스어를 추가하는 것은 dotnet add package IronOcr.Languages.French로, 패키지 관리자가 나머지를 처리합니다.

라이선스 파일 오류가 예고 없이 프로덕션에 영향을 미칩니다. ABBYY 라이선스는 .lic.key 파일로 존재하며, loader.GetEngineObject() 실행 시 특정 디스크 경로에 있어야 합니다. 새로운 프로덕션 서버에서 해당 파일이 누락된 경우(잘못된 배포 스크립트, 파일 복사 실패, 권한 문제 등) 시작 시 오류가 발생합니다. 라이선스가 만료된 경우에도 동일한 오류가 발생합니다. IronOCR의 라이선스는 시작 코드에 할당되는 문자열 키로, 모든 비밀 관리자에 저장 가능하며 애플리케이션이 트래픽을 받아들이기 전에 IronOcr.License.IsValidLicense에서 유효성을 검증합니다.

스레드 안전성은 단일 공유 엔진 인스턴스를 필요로 합니다. ABBYY의 엔진은 여러 스레드에서의 CreateFRDocument 호출에 있어서 간단히 스레드 안전하지 않습니다. 실제 운영 환경에서는 잠금 전략 또는 프로세서 풀을 사용합니다. IronOCR의 IronTesseract은 무상태입니다: 스레드당 하나의 인스턴스를 시작하고 락 없이 동시에 인식을 실행하며 완료 후 처리합니다.

근본적인 문제

// 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");
// IronOCR: the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();

##IronOCR과 ABBYY FineReader: 기능 비교

다음 표는 이번 마이그레이션을 평가하는 팀에 필요한 기능을 다룹니다.

기능ABBYY FineReader 엔진IronOCR
설치SDK 설치 프로그램(Windows)dotnet add package IronOcr
인수영업 담당자에게 문의하십시오 (4-12주 소요).셀프 서비스 NuGet
라이센스 모델Enterprise, 서버별 또는 페이지별영구 라이선스, $999에 단일 지불 $2,999
라이선스 관리.lic + .key 파일이 디스크에 존재함코드 또는 환경 변수의 문자열 키
.NET 통합COM 상호 운용성네이티브 .NET
COM 종속성아니요
스레드 안전성잠금 전략이 필요합니다완전 (스레드당 하나의 IronTesseract)
지원되는 언어190개 이상125+
언어 설치SDK 경로에 있는 런타임 데이터 파일NuGet 언어 패키지
PDF 입력예 (CreatePDFFile를 통해)예 (네이티브, input.LoadPdf())
검색 가능한 PDF 출력예 (내보내기 파이프라인)예 (result.SaveAsSearchablePdf())
자동 전처리프로필 기반내장 기능 (왜곡 보정, 노이즈 제거, 대비 조정, 이진화, 선명도 향상)
영역 기반 OCR영역 객체 (CreateZone, SetBounds)CropRectangle 매개변수
바코드 판독예 (ocr.Configuration.ReadBarCodes = true)
크로스 플랫폼윈도우, 리눅스, macOS윈도우, 리눅스, macOS, Docker, Azure, AWS
Docker 배포사용자 지정 기본 이미지가 필요합니다.표준 .NET 베이스 이미지 + libgdiplus
자신감 점수예 (result.Confidence)
첫 OCR 결과 도출 시간4~12주 (조달)당일

빠른 시작: ABBYY FineReader에서IronOCR로 마이그레이션

1단계: NuGet 패키지 교체

ABBYY FineReader Engine에는 NuGet 패키지가 없습니다. SDK를 제거하고 프로젝트 파일에서 수동 어셈블리 참조를 삭제하여 해당 문제를 해결하십시오.

<!-- Remove these lines from your .csproj -->
<Reference Include="FREngine">
  <HintPath>C:\Program Files\ABBYY SDK\FineReader Engine\Bin\FREngine.dll</HintPath>
</Reference>
XML

그런 후 Visual Studio의 참조 노드에서 FREngine.dll COM 상호 운용 참조를 제거하거나 프로젝트 파일에서 해당 항목을 직접 삭제하세요. NuGet 에서IronOCR설치하세요.

dotnet add package IronOcr

단계 2: 네임스페이스 업데이트

// Before (ABBYY)
using FREngine;
using ABBYY.FineReader;

// After (IronOCR)
using IronOcr;

단계 3: 라이선스 초기화

애플리케이션 시작 시 OCR 호출 전에 다음 코드를 한 번만 추가하세요.

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

운영 환경에 배포할 경우 환경 변수 또는 비밀 관리자에 키를 저장하세요.

IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");

코드 마이그레이션 예제

Windows 서비스의 엔진 수명 주기와 상태 비저장 IronTesseract 비교

ABBYY의 엔진 초기화 절차는 EngineLoaderIEngine 객체 생성 비용이 높기 때문에 서비스 래퍼에 속합니다. 대부분의 실제 운영 환경에서는 엔진을 명시적인 시작 및 종료 메서드를 가진 싱글턴 서비스로 래핑합니다.

ABBYY FineReader 접근 방식:

using FREngine;

public class DocumentOcrService : IHostedService, IDisposable
{
    private IEngine _engine;

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // Step 1: Create loader — requires COM 상호 운용성 registration
        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;
}
C#

IronOCR 접근 방식:

using IronOcr;

public class DocumentOcrService
{
    // 아니요 startup, 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;
    }
}
C#

IronTesseract은 엔진 수명 주기가 없습니다. 이 기능은 처음 사용할 때 내부적으로 초기화되며 명시적인 종료가 필요하지 않습니다. 호스팅된 서비스 래퍼, IEngine 필드, StopAsync 메서드 모두가 사라집니다. 애플리케이션이 동시에 문서를 처리하는 경우, 각 스레드가 고유의 IronTesseract 인스턴스를 생성합니다 - 락이 필요하지 않습니다. IronTesseract 설정 가이드TesseractVersionConfiguration 속성을 포함한 구성 옵션을 다룹니다.

언어 인식 설정

ABBYY 언어 구성은 매개변수가 있는 언어 이름 문자열을 추가하고, 이들을 엔진과 문서 처리 전에 연결해야 하는 LanguageParams 객체를 생성하는 것을 포함합니다. 추가되는 언어마다 해당 데이터 파일이 런타임 경로에 배포되어야 합니다.

ABBYY FineReader 접근 방식:

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();
    }
}

IronOCR 접근 방식:

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);

언어 팩은 표준 NuGet 패키지 (dotnet add package IronOcr.Languages.French)로 설치됩니다. 수동으로 배포해야 할 데이터 파일이 없고, 경로 구성도 필요 없으며, 언어를 전환할 때 엔진을 다시 초기화할 필요도 없습니다. 다국어 가이드 에서는 언어 조합에 대해 설명하고, 언어 색인에는 사용 가능한 125개 이상의 팩 목록이 나와 있습니다.

다중 프레임 TIFF 처리

ABBYY는 프레임을 순차적으로 처리하고 각 프레임을 별도의 문서 페이지로 추가하는 방식으로 여러 페이지로 구성된 TIFF 파일을 처리합니다. 프레임 수는 TIFF 객체에서 가져와야 하며, 그 후 각 프레임을 문서 컨테이너에 개별적으로 추가해야 합니다.

ABBYY FineReader 접근 방식:

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();
    }
}

IronOCR 접근 방식:

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

OcrInput.LoadImageFrames은 수동 반복 없이 다중 페이지 TIFF의 모든 프레임을 읽습니다. 결과는 페이지별 result.Pages를 통해 접근할 수 있으며, 여기에는 텍스트 좌표 데이터 및 각 프레임별 신뢰도도 포함됩니다. TIFF 입력 가이드는 멀티프레임 TIFF와 애니메이션 GIF 처리 방법을 모두 다룹니다.

병렬 배치 처리

ABBYY의 COM 기반 엔진은 다중 스레드에서 CreateFRDocument을 동시에 호출하는 것이 동기화 전략 없이 안전하지 않습니다. 일반적으로 프로덕션 배치 프로세서는 엔진 인스턴스 풀을 유지하거나 잠금을 통해 액세스를 직렬화합니다. 두 접근 방식 모두IronOCR제거하는 인프라를 추가합니다.

ABBYY FineReader 접근 방식:

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

IronOCR 접근 방식:

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

IronTesseract 인스턴스는 독립적입니다. Parallel.ForEach은 공유 상태, 락 혹은 직렬화 없이 사용 가능한 CPU 코어를 포화시킵니다. ABBYY 버전은 비동기 래퍼가 있음에도 불구하고 문서를 순차적으로 처리합니다.IronOCR버전은 이들을 완전히 병렬로 처리합니다. 멀티스레딩 예제는 시간 비교를 통해 이러한 패턴을 보여줍니다. 보다 높은 수준의 처리량 제어에 대해서는 속도 최적화 가이드를 참조하십시오.

문서 내보내기 파이프라인

ABBYY는 Export 메서드를 통해 다양한 내보내기 형식을 지원하며, FileExportFormatEnum 값을 사용합니다. DOCX, RTF 또는 일반 텍스트로 내보내기 위해서는 형식별 내보내기 매개변수 객체를 생성한 다음, 적절한 열거형 값 및 매개변수 객체와 함께 document.Export을 호출해야 합니다.

ABBYY FineReader 접근 방식:

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();
        }
    }
}

IronOCR 접근 방식:

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

IronOCR의 OcrResult.Text에 직접 접근할 수 있으며, 매개변수 객체나 형식 열거형 없이 출력 메서드를 제공합니다. SaveAsSearchablePdf 호출은 ABBYY의 세 단계 매개변수/내보내기 시퀀스에 비해 한 줄로 PDF 내보내기를 처리합니다. 검색 가능한 PDF 가이드에는 페이지 범위 옵션 및 압축 설정이 포함되어 있습니다. hOCR 내보내기 가이드는 위치 인식 OCR 출력을 사용하는 시스템을 위한 HOCR 형식을 다룹니다.

ABBYY FineReader API와IronOCR매핑 참조

ABBYY FineReader 엔진IronOCR에 상응하는
new EngineLoader()필요하지 않음
loader.GetEngineObject(sdkPath, licensePath)new IronTesseract()
engine.LoadPredefinedProfile("...")필수 사항이 아닙니다 (내부적으로 처리됩니다).
engine.CreateLanguageParams()필요하지 않음
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 루프input.LoadImageFrames(tiff)
engine.CreatePDFFile() 그 후 pdfFile.Open(path, null, null)input.LoadPdf(path)
document.Process(null)ocr.Read(input)
document.PlainText.Textresult.Text
frDocument.Pages[i].PlainText.Textresult.Pages[i].Text
page.Layout.Blocks + BlockTypeEnum.BT_Table 검사result.Pages + 단어 좌표 데이터
block.GetAsTableBlock()result.Pages[i].Lines (좌표 포함)
engine.CreatePDFExportParams()필요하지 않음
document.Export(path, FEF_PDF, params)result.SaveAsSearchablePdf(path)
document.Export(path, FEF_TextUnicodeDefaults, null)File.WriteAllText(path, result.Text)
engine.CreateDOCXExportParams() + 내보내기직접적인 지원은 제공되지 않습니다.
document.Close()using에 의해 OcrInput에서 처리됨
_engine.GetLicenseInfo().ExpirationDateIronOcr.License.IsValidLicense
라이선스 파일 (ABBYY.lic, ABBYY.key)IronOcr.License.LicenseKey = "key"
engine.CreateZone() + zone.SetBounds(x, y, w, h)new CropRectangle(x, y, width, height)

일반적인 마이그레이션 문제와 해결책

문제 1: SDK 제거 후 COM 등록 오류 발생

ABBYY: 프로젝트 참조에서 FREngine.dll를 제거한 후에도 여전히 Could not load type 'FREngine.EngineLoader' 또는 이전 네임스페이스를 유지한 클래스에서 COM 상호 운용 오류로 인해 빌드가 실패할 수 있습니다.

해결책: 참조를 제거하기 전에 모든 FREngineABBYY.FineReader 사용을 조사하십시오. IDisposable를 구현하여 특정 IEngine 필드를 무효화하는 모든 클래스는 그 폐기 논리를 OcrInputusing 블록으로 교체해야 합니다:

// 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);

문제 2: 인식 프로필에 상응하는 것이 없음

ABBYY: engine.LoadPredefinedProfile("DocumentConversion_Speed") 또는 engine.LoadPredefinedProfile("FieldLevelRecognition")을 호출하는 코드는 정확도와 처리량을 맞추기 위해 ABBYY 전용 프로필을 사용합니다. IronOCR에는 Profile라는 이름의 동등한 속성이 없습니다.

해결책: IronOCR은 IronTesseract.Configuration를 통해 동일한 절충점을 노출합니다. 속도 최적화를 위해 ocr.Configuration.TesseractVersion = TesseractVersion.Tesseract5(기본값)를 설정하고 전처리 필터를 줄이세요. 정확도를 최대한 높이려면 전체 전처리 파이프라인을 추가하십시오.

// Speed-optimized
var ocr = new IronTesseract();
// 아니요 preprocessing — 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);
C#

이미지 품질 보정 가이드에서는 어떤 필터가 어떤 입력 품질 문제를 해결하는지 설명합니다. 속도 최적화 가이드에서는 깨끗한 문서의 처리 시간을 줄이는 구성 속성을 다룹니다.

문제 3: 라이선스 파일 배포 단계가 CI/CD에 남아 있음

ABBYY: 빌드 파이프라인에는 일반적으로 ABBYY.licABBYY.key을 안전한 저장소에서 배포 대상으로 복사하는 단계가 포함되어 있습니다. 마이그레이션 후 팀에서 이 단계를 제거하는 것을 잊어버리는 경우가 있어 더 이상 존재하지 않는 경로를 참조하는 사용되지 않는 배포 코드가 남게 됩니다.

해결책: 라이선스 파일 복사 단계를 완전히 삭제합니다. 이를 환경 변수 주입 단계로 대체하십시오.

# 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: SetIronOCR license
#   env:
#     IRONOCR_LICENSE_KEY: ${{secrets.IRONOCR_LICENSE}}
Text

그리고 애플리케이션 시작 시:

IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
    ?? throw new InvalidOperationException("IRONOCR_LICENSE_KEY not set");

문제 4: 엔진이 스레드 안전하지 않음 — 기존 잠금 코드

ABBYY: 여러 스레드에서 ABBYY를 호출하는 애플리케이션은 일반적으로 SemaphoreSlim, lock 문 또는 스레드 로컬 엔진 인스턴스를 포함하여 COM 쓰레딩 문제를 피합니다. 이 동기화 코드는 ABBYY의 스레딩 모델에 특화된 것입니다.

해결 방법: ABBYY 호출을 감싸는 모든 동기화 코드를 삭제하십시오. IronOCR의 IronTesseract은 스레드당 인스턴스화가 안전합니다:

// 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;
});

Issue 5: CreateImageInfo / FrameCount Pattern for TIFF

ABBYY: engine.CreateImageInfo()imageInfo.LoadImageFile()을 사용하여 TIFF 파일에서 프레임 수를 읽고 프레임을 순환하기 전에 내부적으로 프레임 열거를 처리하는 IronOCR에 직접적인 대응이 없습니다.

해결 방법: 프레임 카운팅 루프를 완전히 삭제합니다.

// 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

문제 6: DOCX 내보내기 기능에 직접적인 대응 기능이 없음

ABBYY: document.Export(path, FileExportFormatEnum.FEF_DOCX, docxParams)은 워드 문서를 생성합니다.IronOCR DOCX 출력 파일을 직접 생성하지 않습니다.

**해결책:**IronOCR검색 가능한 PDF 파일과 구조화된 텍스트 데이터를 생성합니다. DOCX 출력을 필요로 하는 워크플로의 경우, 실질적인 마이그레이션 경로는 검색 가능한 PDF를 생성한 후 하위 단계에서 변환하거나, Open XML SDK와 같은 라이브러리를 사용하여 구조화된 텍스트를 추출하고 DOCX로 저장하는 것입니다.

//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
}
C#

읽기 결과 가이드에서는 단락, 줄, 단어 및 문자 수준 좌표 데이터를 하위 처리에 활용하는 방법을 설명합니다.

ABBYY FineReader 마이그레이션 체크리스트

이동 전 작업

변경 작업을 하기 전에 코드베이스를 검토하십시오.

# 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" .
SHELL

모든 IEngine 또는 IFRDocument 필드를 보유한 클래스를 문서화하십시오. 사용 중인 내보내기 형식을 확인하십시오. DOCX 출력에는 다른 접근 방식이 필요합니다(위의 6번 문제 참조).

코드 업데이트 작업

  1. 모든 .csproj 파일에서 FREngine.dll 참조를 제거하세요.
  2. ABBYY를 사용한 각 프로젝트에서 dotnet add package IronOcr을 실행하세요.
  3. 애플리케이션 시작 시 IronOcr.License.LicenseKey = ...를 추가하세요 (Program.cs 또는 시작 클래스)
  4. 모든 비영어 언어에 대한 언어 NuGet 패키지를 설치하세요 (dotnet add package IronOcr.Languages.French 등).
  5. 모든 EngineLoader, GetEngineObject, LoadPredefinedProfile 호출을 삭제하세요.
  6. 모든 CreateLanguageParamslangParams.Languages.Add 호출을 삭제하세요.
  7. engine.CreateFRDocument() + document.AddImageFile() + document.Process()new IronTesseract().Read(path)로 대체하세요.
  8. 다중 프레임 TIFF 루프를 input.LoadImageFrames(tiffPath)로 대체하세요.
  9. document.PlainText.Textresult.Text로 대체하세요.
  10. frDocument.Pages[i].PlainText.Textresult.Pages[i].Text로 대체하세요.
  11. document.Export(..., FEF_PDF, pdfParams)result.SaveAsSearchablePdf(path)로 대체하세요.
  12. 모든 document.Close() 호출을 OcrInputusing 블록으로 교체하세요.
  13. ABBYY 엔진 액세스를 직렬화했던 SemaphoreSlim 및 잠금 코드를 삭제하세요.
  14. engine.CreateZone() / zone.SetBounds() / page.Zones.Add()input.LoadImage()에 전달되는 new CropRectangle(x, y, width, height)로 대체하세요.
  15. CI/CD 파이프라인에서 라이선스 파일 복사 단계를 제거합니다.
  16. Docker 이미지를 업데이트하세요 — SDK 설치 계층을 제거하고 Linux 대상에 대해 libgdiplus을 추가하세요.

마이그레이션 후 테스트

  • 각 문서 유형(송장, 계약서, 스캔한 양식)의 대표 샘플을 사용하여 텍스트 추출 결과를 검증합니다.
  • 다중 페이지 TIFF 처리 결과가 ABBYY에서 생성된 프레임 수와 동일한 페이지 수를 반환하는지 확인합니다.
  • ABBYY 기준 비교에 사용된 것과 동일한 입력값을 사용하여 다국어 문서를 테스트합니다.
  • 검색 가능한 PDF 출력물이 Adobe Reader 및 브라우저 PDF 뷰어에서 텍스트 검색이 가능한지 확인합니다.
  • 프로덕션 동시 실행 수준으로 병렬 배치 프로세서를 실행하고 예외가 발생하지 않는지 확인합니다.
  • 확인된 문서에서 result.Confidence을 확인하여 품질 게이트의 기준 임계값을 설정하세요.
  • 스테이징 배포 환경에서 환경 변수를 이용한 라이선스 키 초기화 테스트
  • ABBYY SDK 볼륨 마운트 없이 Docker 이미지가 빌드되고 OCR이 실행되는지 확인합니다.
  • 라이선스 파일 복사 단계를 제외하고 CI/CD 파이프라인이 완료되는지 확인합니다.
  • 배치 프로세서에 메모리 프로파일러를 실행하여 OcrInput 객체가 누출되지 않았는지 확인합니다 (확인 using 위치).

##IronOCR로 마이그레이션할 때의 주요 이점

배포 복잡성이 10분의 1로 줄어듭니다. 이전에는 모든 ABBYY 배포 시 SDK 설치, 라이선스 파일 배치, 런타임 경로 구성, 그리고 애플리케이션 실행 전에 파일이 올바른 경로에 있는지 확인하는 검증 작업이 필요했습니다.IronOCR NuGet 종속성으로 배포됩니다. dotnet publish은 OCR 엔진이 포함된 독립적인 아티팩트를 생성합니다. Docker 배포 가이드Azure 설정 가이드는 전체 구성 과정을 한 페이지에 모두 보여줍니다.

COM 상호 운영이 사라졌습니다. COM 계층을 제거하면 새 기계에서의 COM 등록 오류, 아파트 쓰레딩 불일치, RCW 수명 주기 버그, 그리고 모든 ABBYY 문서 처리 호출에 필요한 15-25 줄의 try/finally 보일러플레이트를 제거함으로써 런타임 오류 범주 전체를 제거합니다. 코드베이스 크기가 줄어듭니다. 오차면의 크기도 함께 줄어듭니다.

더 이상 문서량 증가가 예산 검토를 유발하지 않습니다. IronOCR의 영구 라이선스는 문서량에 제한이 없습니다. 첫 해에 월 1만 건의 문서를 처리하고 3년 차에 월 200만 건의 문서를 처리하는 애플리케이션의 OCR 라이선스 비용은 동일합니다. 페이지당 사용량 계산이나 초과 사용 요금 청구, 사용량 등급별 재협상은 없습니다. 라이선스 페이지에는 모든 등급이 표시됩니다. 2,999달러의 Professional 라이선스는 10명의 개발자가 배포 대상 수에 관계없이 모든 볼륨을 처리할 수 있도록 지원합니다.

크로스 플랫폼 배포로 새로운 인프라 옵션이 제공됩니다. ABBYY COM 레이어는 Windows를 필요로 합니다. 비용 절감이나 용량 증대를 위해 문서 처리를 리눅스 컨테이너로 이전하려던 팀들은 제지를 받았습니다.IronOCR동일한 NuGet 패키지를 사용하여 Windows, Linux 및 macOS에서 동일하게 실행됩니다. ABBYY에서 마이그레이션하면 애플리케이션 스택의 OCR 계층에서 Windows 제약 조건이 제거됩니다. Linux 배포 가이드AWS 배포 가이드는 각 환경에 대한 전체 설정 과정을 다룹니다.

인프라 구축 작업 없이 병렬 처리량을 사용할 수 있습니다. ABBYY 엔진 접근을 직렬화하는 데 사용되던 잠금 전략이 사라졌습니다. IronTesseract 인스턴스는 독립적입니다: 스레드당 하나씩 가동하고 문서 배치에 대해 Parallel.ForEach을 실행하며 결과를 가져옵니다. 추가 코드 없이 사용 가능한 CPU 코어 수에 따라 처리량이 확장됩니다. 멀티스레딩 예제는 멀티코어 하드웨어에서 실제 성능 향상을 보여줍니다.

언어 구성은 패키지 참조입니다. ABBYY 통합에 독일어 또는 일본어 OCR 지원을 추가하려면 데이터 파일을 식별하고, 모든 대상 시스템의 런타임 경로에 배포하고, 파일이 누락되었을 때 오류를 처리해야 했습니다. IronOCR을 통해 dotnet add package IronOcr.Languages.German은 언어 팩을 버전 관리된, 재현 가능한 NuGet 종속성으로 추가합니다. 패키지 관리자는 모든 빌드에 데이터가 포함되도록 보장합니다. 사용자 지정 언어 팩 가이드에서는 특정 도메인을 위한 사용자 지정 언어 모델을 학습하고 배포하는 방법을 다룹니다.

참고해 주세요: ABBYY FineReader와 Tesseract는 각각의 소유자의 등록 상표입니다. 이 사이트는 ABBYY 또는 Google과 제휴, 승인, 후원되지 않았습니다. 모든 제품명, 로고 및 브랜드는 해당 소유자의 자산입니다. 비교는 정보 제공 목적으로만 사용되며, 작성 시점에 공개적으로 이용 가능한 정보를 반영합니다.

관련 기사

Key in blue circle

무료 30일 체험 키를 즉시 받으세요.

Your trial license will be sent to your email address

제한 없음. 100% 무제한 이용. 신용카드 불필요.

bullet_checked신용카드나 계정 생성은 필요하지 않습니다.제한 없음. 100% 무제한 이용. 신용카드 불필요.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
부담 없는 무료 상담을 받아보세요
아래 양식을 작성하시거나 sales@ironsoftware.com으로 이메일을 보내주세요.
고객님의 정보는 항상 비밀로 유지됩니다.
전 세계 수백만 엔지니어들이 신뢰하는 제품입니다.
Iron Software의 고객 로고
지금 바로 30일 무료 체험판 키를 받으세요.
신용카드나 계정 생성은 필요하지 않습니다.