IRONSOFTWAREHOME
동영상

테서랙트 OCR 래퍼에서 IronOCR로 마이그레이션하기

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

.NET 개발자로, TesseractOCR NuGet 패키지를 사용 중이고 IronOCR로의 명확한 단계별 경로가 필요한 분들을 위한 안내서입니다. 이 문서는 마이그레이션을 유발하는 구체적인 문제점(불완전한 API 지원 범위 및 일관성 없는 오류 보고)을 다루며, 이러한 문제점이 실제 애플리케이션에서 가장 큰 마찰을 일으키는 시나리오에 대한 변경 전후 코드를 제공합니다.

Tesseract OCR Wrapper에서 마이그레이션해야 하는 이유

TesseractOCR 패키지(커뮤니티 개발자 Oachkatzlschwoaf가 게시함)는 Tesseract 엔진을 관리형 .NET API로 노출시키는 기본 문제를 해결합니다. 개념 증명(PoC) 작업용으로는 충분합니다. 신뢰할 수 있는 오류 신호, 다양한 출력 형식, 그리고 완벽한 API 표면이 필요한 프로덕션 시스템의 경우, 래퍼의 설계 선택 사항이 장애 요인이 됩니다.

불완전한 API 표면. 이 래퍼는 텍스트 추출 기능과 집계 신뢰도(float)를 제공합니다. 공개 API에는 WORD 단위 데이터, 바운딩 박스, 줄 단위 탐색 및 단락 단위 그룹화 기능이 포함되어 있지 않습니다. 페이지 내 특정 값이 어디에 위치하는지 파악해야 하는 애플리케이션(예: 청구서 필드 추출, 정보 마스킹 파이프라인, 문서 분석)은 래퍼 내에서 처리할 수 있는 방법이 없습니다. 원시 Tesseract 데이터에서 hOCR을 파싱하기 위해 두 번째 라이브러리를 추가하면 시간이 지남에 따라 누적되는 통합 작업이 발생합니다.

잘못된 입력에 대한 무음 오류. Tesseract 엔진이 손상된 이미지, 지원되지 않는 형식, 내부 처리 오류를 만나면, 래퍼는 잡을 수 있는 관리 예외를 던지지 않고 page.GetText()에서 빈 문자열을 반환합니다. 호출 코드는 정상적인 빈 페이지와 구별할 수 없는 빈 결과를 반환받습니다. 하루에 수천 건의 문서를 처리하는 자동화 파이프라인은 감사 과정에서 문제가 드러나기 전까지 수개월 동안 데이터가 누락되는 것을 감지하지 못할 수 있습니다.

검색 가능한 PDF 형식의 출력은 지원되지 않습니다. 이 래퍼는 일반 텍스트를 생성합니다. 법률, 의료 및 금융 서비스 분야에서 표준 준수 요건으로 요구되는 검색 가능한 PDF로 해당 텍스트를 변환하려면 별도의 PDF 라이브러리, 수동 텍스트 레이어 조립 및 페이지 좌표 계산이 필요합니다. 해당 통합 코드는 150~300줄 규모이며, 독립적으로 유지 관리되어야 합니다.

네이티브 PDF 입력 없음. PDF를 처리하는 래퍼를 사용하는 모든 코드베이스는 PDF를 이미지로 래스터화하는 레이어를 포함하고 있습니다: 일반적으로 PdfiumViewer, Ghostscript, 또는 PDFSharp가 각 PDF 페이지를 엔진에 전달하기 전에 비트맵으로 변환하는 렌더링 API 호출을 합니다. 그러한 종속성은 복잡성을 증가시키고, 중간 래스터화에서 품질 손실 단계가 추가되며, 자체 배포 구성이 필요합니다.

다중 형식 입력 처리 안 됨. 래퍼의 기본 입력 경로는 Pix.Image.LoadFromFile에 전달되는 파일 경로 문자열입니다. 파일 업로드를 처리하는 ASP.NET 애플리케이션에서 흔히 볼 수 있는 스트림 기반 및 바이트 배열 기반 입력 방식은, 먼저 바이트 데이터를 임시 파일에 기록한 다음 해당 경로를 엔진에 전달하고, 마지막으로 임시 파일을 정리해야 합니다. 이러한 패턴은 오류가 발생하기 쉽고 불필요한 과정입니다.

엔진 구성의 유연성. 이 래퍼는 Tesseract 엔진 구성 옵션의 일부를 노출합니다. 페이지 분할 모드는 사용할 수 있지만, 해상도 정규화, 출력 유형 및 인식 매개변수에 대한 구성은 래퍼가 제공하는 수준보다 더 낮은 추상화 수준에서 작업해야 합니다.

근본적인 문제

래퍼의 오류 계약이 정의되지 않았습니다. 성공한 것처럼 보이는 호출이 결과를 조용히 버릴 수 있습니다:

// TesseractOCR: no way to tell failure from "no text on this page"
using var engine = new Engine(@"./tessdata", Language.English);
using var img = Pix.Image.LoadFromFile(imagePath);
using var page = engine.Process(img);

var text = page.Text; // returns "" on engine failure — same as blank page
// Caller cannot distinguish OCR failure from legitimate empty result
C#

IronOCR은 엔진 오류가 발생하면 예외를 발생시키고, 성공적인 결과마다 수치형 신뢰도 점수를 반환합니다:

// IronOCR: failures throw, low-confidence results are detectable
var result = new IronTesseract().Read(imagePath);
// result.Confidence is 0-100; a score below 10 signals a processing problem
// An engine failure throws IronOcrException — never returns a silent empty string
Console.WriteLine($"Text: {result.Text}, Confidence: {result.Confidence}%");
C#

##IronOCR대 Tesseract OCR 래퍼: 기능 비교

아래 표는 실제 문서 처리 애플리케이션에 있어 가장 중요한 기능들을 다루고 있습니다.

기능Tesseract OCR 래퍼IronOCR
NuGet 패키지TesseractOCR + 수동 tessdata + 네이티브 바이너리IronOcr (모든 종속성 포함)
라이선스Apache 2.0 (무료)상업용 ($999–$2,399 영구적)
엔진 버전번들된 네이티브 바이너리에 따라 다름최적화된 Tesseract 5 (번들)
일반 텍스트 출력가능 (page.Text)가능 (result.Text)
검색 가능한 PDF 출력아니요가능 (result.SaveAsSearchablePdf())
hOCR 내보내기아니요가능 (result.SaveAsHocrFile())
WORD/줄/단락 단위의 구조화된 데이터아니요예 (바운딩 박스 좌표 포함)
단어별 신뢰도 점수아니요가능 (word.Confidence)
종합 신뢰도가능 (page.GetMeanConfidence(), float 0–1)가능 (result.Confidence, double 0–100)
일관된 오류 처리아니요 (실패 시 빈 문자열)예 (전체적으로 예외 처리 포함)
네이티브 PDF 입력아니요
비밀번호로 보호된 PDF 입력아니요
여러 페이지로 구성된 TIFF 입력제한적
스트림 및 바이트 배열 입력직접적인 지원 없음가능 (input.LoadImage(stream), input.LoadImage(bytes))
자동 기울기 보정아니요
자동 노이즈 제거아니요
자동 대비 향상아니요
이진화아니요
OCR 중 바코드 판독아니요가능 (ocr.Configuration.ReadBarCodes = true)
영역 기반 OCR공개된 API 없음가능 (CropRectangle)
나사 안전제한적전체 (각 스레드당 하나의 IronTesseract 인스턴스)
크로스 플랫폼 배포네이티브 바이너리 구성이 필요합니다윈도우, 리눅스, macOS, Docker, Azure, AWS
.NET Version 지원래퍼 버전에 따라 다름.NET Framework 4.6.2 이상, .NET Core, .NET 5/6/7/8/9
상업적 지원None예 (이메일, 상위 등급 우선)

빠른 시작: Tesseract OCR 래퍼에서 IronOCR로의 마이그레이션

1단계: NuGet 패키지 교체

기존 패키지 제거:

dotnet remove package TesseractOCR
SHELL

NuGet 에서IronOCR설치하세요.

dotnet add package IronOcr

프로젝트에서 여러 언어를 사용하는 경우, 해당 언어 팩을 설치하십시오:

dotnet add package IronOcr.Languages.French, IronOcr.Languages.German

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

기존 네임스페이스 참조를IronOCR네임스페이스로 대체하십시오:

// Before (Tesseract OCR Wrapper)
using TesseractOCR;
using TesseractOCR.Enums;

// After (IronOCR)
using IronOcr;
C#

단계 3: 라이선스 초기화

응용 프로그램 시작 시, OCR 작업이 실행되기 전에 라이선스 키 호출을 한 번 추가하십시오:

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

IronOCR 라이선스 페이지에서 무료 체험판 키를 받을 수 있으며, 이를 통해 체험 기간 동안 모든 기능을 사용할 수 있습니다.

코드 마이그레이션 예제

무음 오류 대신 신뢰할 수 있는 오류 처리

래퍼의 오류 동작은 대부분의 팀이 가장 먼저 마주치는 마이그레이션 트리거입니다. 자동화된 파이프라인이 몇 주 동안 실행된 후, 감사 결과 일부 레코드에 데이터가 포함되어 있지 않은 것으로 드러납니다. 이는 문서가 비어 있어서가 아니라, 엔진이 특정 이미지 조건에서 아무런 오류 메시지 없이 실패했기 때문입니다.

Tesseract OCR 래퍼 접근 방식:

using TesseractOCR;

public class DocumentProcessor
{
    private readonly string _tessDataPath = @"./tessdata";

    public string ProcessDocument(string imagePath)
    {
        using var engine = new Engine(_tessDataPath, Language.English);
        using var img = Pix.Image.LoadFromFile(imagePath);
        using var page = engine.Process(img);

        // Empty string on engine failure — indistinguishable from blank page
        // 아니요 exception thrown, no confidence signal, no recovery path
        var text = page.Text;

        // Caller cannot tell if this is "" because:
        // - The document is genuinely blank
        // - The image format was not supported
        // - The engine encountered an internal error
        // - The tessdata was corrupted or version-mismatched
        return text;
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class DocumentProcessor
{
    public string ProcessDocument(string imagePath)
    {
        try
        {
            var result = new IronTesseract().Read(imagePath);

            // Confidence below threshold means the result is unreliable
            if (result.Confidence < 15)
            {
                // Route to human review queue — do not silently write empty data
                throw new InvalidOperationException(
                    $"OCR confidence too low ({result.Confidence:F1}%) for: {imagePath}");
            }

            return result.Text;
        }
        catch (IronOcrException ex)
        {
            // Engine failures are typed exceptions — never silent empty strings
            // Log and rethrow with context so the pipeline can flag the document
            throw new ApplicationException(
                $"OCR engine failure processing '{imagePath}': {ex.Message}", ex);
        }
    }
}
C#

모든 오류 발생 시점은 catch 가능한 유형 지정 예외로 표출됩니다. 품질이 낮은 결과의 경우 신뢰도 점수가 표시되므로, 호출 코드는 전처리 후 재시도할지, 수동 검토로 넘길지, 아니면 입력을 거부할지 결정할 수 있습니다. 데이터 손실이 발생하지 않습니다.

전체 신뢰도 점수 API에 대해서는 신뢰도 점수 사용 가이드를 참조하십시오.

일반 텍스트에서 문서 아카이브 파이프라인으로의 출력 확장

문서 관리에서 흔히 요구되는 사항 중 하나는 스캔된 문서(종이 계약서, 청구서, 팩스 기록 등)를 문서 관리 시스템이 색인화할 수 있는 검색 가능한 PDF로 변환하는 것입니다. 이 래퍼는 일반 텍스트만 생성하며 그 외에는 아무것도 생성하지 않습니다. 해당 출력물을 기반으로 검색 가능한 PDF를 생성하려면 PDF 라이브러리, 수동 텍스트 오버레이, 페이지별 좌표 계산 및 글꼴 메트릭 처리가 필요합니다.

Tesseract OCR 래퍼 접근 방식:

using TesseractOCR;
// Also requires: a PDF library (PDFsharp, iText, or similar)
// Also requires: a PDF rasterizer (PdfiumViewer or Ghostscript) to convert input PDFs to images

public class ArchivePipeline
{
    private readonly string _tessDataPath = @"./tessdata";

    public string ExtractText(string imagePath)
    {
        using var engine = new Engine(_tessDataPath, Language.English);
        using var img = Pix.Image.LoadFromFile(imagePath);
        using var page = engine.Process(img);

        return page.Text; // Plain text only — searchable PDF requires a separate pipeline
    }

    // To create a searchable PDF from this text, you would need:
    // 1. Load the original image as a PDF page background
    // 2. Map character positions back to image coordinates
    // 3. Overlay an invisible text layer using a PDF library
    // 4. Handle multi-page documents with per-page iteration
    // That is approximately 150-300 lines of additional code
}
C#

IronOCR 접근 방식:

using IronOcr;

public class ArchivePipeline
{
    // Single method handles the full document archive pipeline
    public void ProcessArchive(string[] inputPaths, string outputDirectory)
    {
        var ocr = new IronTesseract();

        foreach (var inputPath in inputPaths)
        {
            var result = ocr.Read(inputPath);

            // Plain text for full-text search indexing
            var textPath = Path.Combine(outputDirectory,
                Path.GetFileNameWithoutExtension(inputPath) + ".txt");
            File.WriteAllText(textPath, result.Text);

            // Searchable PDF — invisible text layer aligned to original scan
            var pdfPath = Path.Combine(outputDirectory,
                Path.GetFileNameWithoutExtension(inputPath) + "-searchable.pdf");
            result.SaveAsSearchablePdf(pdfPath);
        }
    }

    // Input can be scanned image files or existing PDFs — same API
    public void ProcessScannedPdf(string scannedPdfPath, string outputPath)
    {
        var result = new IronTesseract().Read(scannedPdfPath);
        result.SaveAsSearchablePdf(outputPath);
    }
}
C#

같은 Read() 호출은 이미지 파일과 PDF 문서를 모두 수용합니다. SaveAsSearchablePdf() 호출은 올바른 위치의 보이지 않는 텍스트 레이어가 포함된 표준 색인 가능한 PDF 파일을 생성합니다. PDF 라이브러리 의존성 없음, 좌표 계산 없음, 텍스트 오버레이 조립 없음.

검색 가능한 PDF 출력 가이드검색 가능한 PDF 예제는 다중 페이지 및 일괄 처리 시나리오를 다룹니다.

배치 처리를 위한 엔진 구성 간소화

래퍼는 OCR 호출당 새로운 Engine 인스턴스를 필요로 하며, 그 인스턴스는 필수 생성자 인수로 tessdata 파일 시스템 경로를 필요로 합니다. 수천 개의 문서를 처리하는 일괄 처리 시나리오에서는, 이는 매 인스턴스화 시마다 tessdata 경로를 해결하고 검증해야 함을 의미하며, 각 호출 지점에서 엔진 초기화에 따른 오버헤드가 발생합니다.

Tesseract OCR 래퍼 접근 방식:

using TesseractOCR;

public class BatchOcrService
{
    // tessdata path must be configured correctly in every environment
    private readonly string _tessDataPath;

    public BatchOcrService(string tessDataPath)
    {
        // Path validation deferred to runtime — no early error on misconfiguration
        _tessDataPath = tessDataPath;
    }

    public IEnumerable<string> ProcessBatch(IEnumerable<string> imagePaths)
    {
        var results = new List<string>();

        foreach (var path in imagePaths)
        {
            // New engine created per document — tessdata path re-resolved each time
            using var engine = new Engine(_tessDataPath, Language.English);
            using var img = Pix.Image.LoadFromFile(path);
            using var page = engine.Process(img);

            results.Add(page.Text);
        }

        return results;
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class BatchOcrService
{
    // One IronTesseract instance for the lifetime of the service
    // Thread-safe — can be registered as a singleton in DI
    private readonly IronTesseract _ocr;

    public BatchOcrService()
    {
        _ocr = new IronTesseract();
        // Optional: tune for batch throughput
        _ocr.Configuration.TesseractVersion = TesseractVersion.Tesseract5;
    }

    public IEnumerable<string> ProcessBatch(IEnumerable<string> imagePaths)
    {
        // Reuse the initialized engine — no tessdata path re-resolution per call
        return imagePaths.Select(path => _ocr.Read(path).Text).ToList();
    }

    // Parallel batch processing — IronTesseract is thread-safe with separate instances
    public IEnumerable<string> ProcessBatchParallel(string[] imagePaths)
    {
        var results = new string[imagePaths.Length];

        Parallel.For(0, imagePaths.Length, i =>
        {
            // Separate instance per thread — thread-safe by design
            var ocr = new IronTesseract();
            results[i] = ocr.Read(imagePaths[i]).Text;
        });

        return results;
    }
}
C#

엔진 초기화에는 시작 시 오버헤드가 발생합니다. 순차 호출 전반에 걸쳐 IronTesseract 인스턴스를 재사용하면 해당 오버헤드가 제거됩니다. 병렬 작업 부하의 경우, 스레드당 하나의 인스턴스를 사용하는 패턴을 따릅니다. 각 인스턴스는 독립적으로 초기화되며 동시에 사용해도 안전합니다. 잠금 없음, 공유 상태 없음.

완전한 병렬 배치 처리 구현 예제는 멀티스레딩 예제를 참조하십시오.

임시 파일 없이 다양한 형식의 입력 처리

파일을 업로드받는 ASP.NET 애플리케이션은 해당 문서를 스트림 또는 바이트 배열로 처리합니다. 이 래퍼의 주요 입력 경로는 파일 시스템 경로입니다. 즉, 애플리케이션은 업로드된 바이트를 임시 파일에 기록한 후, 해당 경로를 엔진에 전달하고, 마지막으로 임시 파일을 삭제해야 합니다. 이러한 방식은 불안정할 뿐만 아니라 요청마다 I/O 오버헤드를 발생시킵니다.

Tesseract OCR 래퍼 접근 방식:

using TesseractOCR;

public class UploadOcrController
{
    private readonly string _tessDataPath = @"./tessdata";

    public async Task<string> ProcessUpload(Stream uploadStream)
    {
        // Must write to temp file — no direct stream input path in the wrapper
        var tempPath = Path.GetTempFileName();
        try
        {
            using (var fileStream = File.Create(tempPath))
            {
                await uploadStream.CopyToAsync(fileStream);
            }

            using var engine = new Engine(_tessDataPath, Language.English);
            using var img = Pix.Image.LoadFromFile(tempPath); // file path required
            using var page = engine.Process(img);

            return page.Text;
        }
        finally
        {
            // Cleanup — if this throws, temp file leaks
            if (File.Exists(tempPath))
                File.Delete(tempPath);
        }
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class UploadOcrController
{
    public string ProcessUpload(Stream uploadStream)
    {
        // Direct stream input — no temporary file, no I/O overhead, no cleanup
        using var input = new OcrInput();
        input.LoadImage(uploadStream);
        return new IronTesseract().Read(input).Text;
    }

    public string ProcessUploadBytes(byte[] imageBytes)
    {
        // Byte array input — works directly from memory
        using var input = new OcrInput();
        input.LoadImage(imageBytes);
        return new IronTesseract().Read(input).Text;
    }

    public string ProcessMultiPageTiff(Stream tiffStream)
    {
        // Multi-frame TIFF — all frames processed in one call
        using var input = new OcrInput();
        input.LoadImageFrames(tiffStream);
        return new IronTesseract().Read(input).Text;
    }
}
C#

OcrInput는 통합 로딩 API를 통해 스트림, 바이트 배열, 파일 경로 및 다중 프레임 TIFF를 수용합니다. 임시 파일도, I/O 오버헤드도, 정리 로직도 없습니다. using 블록은 OcrInput에서 리소스 폐기를 제대로 처리합니다.

스트림 입력 가이드와 이미지 입력 가이드는 메모리 매핑된 파일 및 네트워크 스트림을 포함하여 지원되는 모든 입력 소스를 다룹니다.

문서 분석을 위한 구조화된 데이터 추출

래퍼는 문서 전체를 page.Text에서 단일 문자열로 반환합니다. 청구서 금액, 날짜, 내역 항목 등 특정 필드를 식별해야 하는 애플리케이션은 공간적 맥락 없이 휴리스틱 또는 정규 표현식을 사용하여 해당 문자열을 파싱해야 합니다. 페이지 내 개별 단어의 위치에 접근할 수 있는 API는 없습니다.

Tesseract OCR 래퍼 접근 방식:

using TesseractOCR;
using System.Text.RegularExpressions;

public class InvoiceFieldExtractor
{
    private readonly string _tessDataPath = @"./tessdata";

    public Dictionary<string, string> ExtractFields(string imagePath)
    {
        using var engine = new Engine(_tessDataPath, Language.English);
        using var img = Pix.Image.LoadFromFile(imagePath);
        using var page = engine.Process(img);

        var fullText = page.Text;

        // Must parse the full string — no spatial context available
        // Pattern matching is fragile across different invoice layouts
        var fields = new Dictionary<string, string>();

        var totalMatch = Regex.Match(fullText, @"Total[:\s]+\$?([\d,]+\.\d{2})");
        if (totalMatch.Success)
            fields["Total"] = totalMatch.Groups[1].Value;

        var dateMatch = Regex.Match(fullText, @"Date[:\s]+(\d{1,2}/\d{1,2}/\d{4})");
        if (dateMatch.Success)
            fields["Date"] = dateMatch.Groups[1].Value;

        return fields;
        // 아니요 spatial fallback when text patterns fail — the data is lost
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class InvoiceFieldExtractor
{
    public Dictionary<string, string> ExtractFields(string imagePath)
    {
        var result = new IronTesseract().Read(imagePath);
        var fields = new Dictionary<string, string>();

        // Traverse structured result — words carry position and confidence
        foreach (var page in result.Pages)
        {
            foreach (var paragraph in page.Paragraphs)
            {
                var paraText = paragraph.Text.Trim();

                // Spatial proximity: find words near known label positions
                if (paraText.StartsWith("Total", StringComparison.OrdinalIgnoreCase))
                {
                    fields["Total"] = paraText;
                    // paragraph.X, paragraph.Y give position for layout validation
                }

                if (paraText.StartsWith("Invoice Date", StringComparison.OrdinalIgnoreCase))
                {
                    fields["Date"] = paraText;
                }
            }
        }

        // Flag low-confidence extractions for review rather than silently accepting them
        var lowConfidenceWords = result.Pages
            .SelectMany(p => p.Paragraphs)
            .SelectMany(para => para.Words)
            .Where(w => w.Confidence < 50)
            .Select(w => w.Text)
            .ToList();

        if (lowConfidenceWords.Any())
            fields["_LowConfidenceWarning"] = string.Join(", ", lowConfidenceWords);

        return fields;
    }
}
C#

result.Pages[].Paragraphs[].Words[] 계층 구조는 각 단어의 위치(X, Y, Width, Height)와 신뢰도를 노출합니다. 이전에는 불안정한 문자열 파싱에 의존했던 추출 로직은, 페이지에서 알려진 레이블의 오른쪽이나 바로 아래에 값이 나타난다는 사실을 활용하여 공간적 근접성을 활용할 수 있습니다.

'읽기 결과 가이드' 문서에는 일반적인 추출 패턴에 대한 코드 예제와 함께 전체 계층 구조가 설명되어 있습니다.

Tesseract OCR 래퍼 API와IronOCR매핑 참조

Tesseract OCR 래퍼IronOCR에 상응하는
new Engine(tessDataPath, Language.English)new IronTesseract() (경로 불필요)
new Engine(tessDataPath, "eng+fra")ocr.Language = OcrLanguage.English; ocr.AddSecondaryLanguage(OcrLanguage.French)
Pix.Image.LoadFromFile(imagePath)input.LoadImage(imagePath)
engine.Process(img)ocr.Read(input) 또는 ocr.Read(imagePath)
page.Textresult.Text
page.GetMeanConfidence() (float 0–1)result.Confidence (double 0–100)
해당 기능 없음 — 스트림 입력에는 임시 파일이 필요합니다input.LoadImage(stream)
해당 기능 없음 — 바이트 입력 시 임시 파일이 필요합니다input.LoadImage(byteArray)
해당 항목 없음 — PDF 미지원input.LoadPdf(pdfPath)
해당 항목 없음 — PDF 미지원input.LoadPdf(pdfPath, Password: "secret")
해당 항목 없음 — 다중 프레임 TIFF 제한input.LoadImageFrames(tiffPath)
해당 항목 없음 — 텍스트 이외의 출력 형식 없음result.SaveAsSearchablePdf(outputPath)
해당 항목 없음 — hOCR 출력 없음result.SaveAsHocrFile(outputPath)
해당 항목 없음 — 구조화된 데이터 없음result.Pages[i].Paragraphs[j].Words[k]
해당 용어 없음 — WORD 간 연관성 없음word.X, word.Y, word.Width, word.Height
해당 용어 없음 — WORD별 신뢰도 없음word.Confidence
해당 항목 없음 — 사전 처리 없음input.Deskew(), input.DeNoise(), input.Contrast()
해당 항목 없음 — 지역 선택 불가input.LoadImage(path, new CropRectangle(x, y, w, h))
해당 기능 없음 — BARCODE 지원 불가ocr.Configuration.ReadBarCodes = true; 결과.바코드
TesseractException (일관성 없음)IronOcrException (일관성 있음, 실패 시 항상 던져짐)

전체 클래스 및 메서드 문서는 IronTesseract API 참조OcrResult API 참조에서 확인할 수 있습니다.

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

문제 1: 마이그레이션 후 빈 문자열 결과가 사라짐

Tesseract OCR 래퍼: 실패와 빈 페이지를 모두 감지하기 위해 if (string.IsNullOrEmpty(result))를 체크하는 코드가 마이그레이션 후 다르게 작동할 것입니다. IronOCR은 실패 시 빈 값을 반환하는 대신 예외를 발생시키므로, 빈 문자열 확인 기능으로는 더 이상 엔진 오류를 감지할 수 없습니다.

해결책: 두 가지 문제를 분리하십시오. 엔진 오류에 대해 try/catch를 사용하고 품질 필터링을 위해 result.Confidence를 체크하세요:

try
{
    var result = new IronTesseract().Read(imagePath);
    if (result.Confidence < 10)
    {
        // Genuinely unreadable or blank — route to review
        return string.Empty;
    }
    return result.Text;
}
catch (IronOcrException)
{
    // Engine failure — log and handle separately from blank pages
    return null; // or rethrow
}
C#

이슈 2: 신뢰도 척도 변경

Tesseract OCR 래퍼: page.GetMeanConfidence()는 0과 1 사이의 float를 반환합니다. 0.7f와 같은 값에 임계값을 설정하는 코드는 모든IronOCR결과에서 작동합니다.

해결책: IronOCR의 result.Confidence는 백분율(0에서 100)로 표현되는 double입니다. 이전 값에 100을 곱하여 임계값 비교를 업데이트하십시오:

// Before (TesseractOCR): if (confidence < 0.7f)
// After (IronOCR):
if (result.Confidence < 70)
{
    // Below 70% confidence
}
C#

이슈 3: 언어 문자열 형식 변경

Tesseract OCR 래퍼: 언어는 Engine 생성자에서 +로 구분된 문자열로 지정됩니다: "eng+fra+deu". 관련 .traineddata 파일은 tessdata 디렉토리의 정확한 경로에 존재해야 합니다.

해결책: 언어 NuGet 패키지를 설치하고 OcrLanguage 열거형을 사용하세요. 배포 시 tessdata 디렉터리를 제외하십시오:

// dotnet add package IronOcr.Languages.French
// dotnet add package IronOcr.Languages.German

var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English;
ocr.AddSecondaryLanguage(OcrLanguage.French);
ocr.AddSecondaryLanguage(OcrLanguage.German);
C#

다국어 가이드에는 사용 가능한 125개 이상의 언어 패키지가 모두 나열되어 있습니다.

이슈 4: Tessdata 경로 구성 누락

Tesseract OCR 래퍼: Engine 생성자는 첫 번째 인수로 tessdata 파일 시스템 경로를 필요로 합니다. 이 경로는 일반적으로 구성에 저장되어 런타임에 주입됩니다. 마이그레이션 후에는 해당 구성 키가 사용되지 않습니다.

해결 방법: 구성 파일과 배포 스크립트에서 tessdata 경로를 제거하십시오. 저장소와 배포 아티팩트에서 tessdata 디렉터리를 삭제하십시오. Engine 생성자 호출에서 경로 매개변수를 제거하세요 — IronOCR은 설치된 NuGet 패키지에서 언어 데이터를 자동으로 해상합니다:

// Before: new Engine(configuration["TessDataPath"], Language.English)
// After:
var ocr = new IronTesseract(); // language resolved from NuGet package
ocr.Language = OcrLanguage.English;
C#

문제 5: PDF 입력 시 래스터화 레이어 제거 필요

Tesseract OCR Wrapper: PDF 처리를 위해서는 각 페이지를 엔진으로 전달하기 전에 비트맵으로 변환하는 래스터화 라이브러리(PdfiumViewer, Ghostscript 또는 이와 유사한 라이브러리)가 필요합니다. 이제 해당 라이브러리는 더 이상 필요하지 않습니다.

해결 방안: PDF 래스터화 라이브러리를 제거하고, 변환 후 OCR 처리 파이프라인 전체를IronOCR직접 호출로 대체합니다:

// Before: rasterize each PDF page to bitmap, OCR each bitmap, collect results
// After:
using var input = new OcrInput();
input.LoadPdf("document.pdf");
var result = new IronTesseract().Read(input);
Console.WriteLine(result.Text);
C#

PDF 입력 가이드에는 페이지 범위 선택 및 암호로 보호된 PDF에 대한 내용이 포함되어 있습니다.

이슈 6: 스트림 입력 시 임시 파일 불필요

Tesseract OCR Wrapper: ASP.NET 컨트롤러에 파일을 업로드하고 업로드된 스트림에 대해 OCR을 수행하려면 임시 파일에 바이트를 기록하고, 파일 경로를 통해 OCR을 수행한 다음, 임시 파일을 삭제해야 했습니다. 이 방식은 OCR 호출에서 예외가 발생하면 임시 파일이 남게 됩니다.

해결책: OcrInput을 사용하여 스트림에서 직접 로드하세요:

// Before: write to temp, OCR, delete temp
// After:
public async Task<string> OcrUpload(IFormFile file)
{
    using var stream = file.OpenReadStream();
    using var input = new OcrInput();
    input.LoadImage(stream);
    return new IronTesseract().Read(input).Text;
}
C#

임시 파일 없음, 정리 로직 없음, 예외 발생 시 고아 파일 없음.

Tesseract OCR 래퍼 마이그레이션 체크리스트

사전 마이그레이션

새로운 코드를 작성하기 전에 코드베이스에서 래퍼의 모든 사용처를 검토하십시오:

# Find all files using the TesseractOCR namespace
grep -r "using TesseractOCR" --include="*.cs" .

# Find Engine constructor calls — these carry the tessdata path
grep -rn "new Engine(" --include="*.cs" .

# Find tessdata path configuration references
grep -rn "tessdata" --include="*.cs" .
grep -rn "tessdata" --include="*.json" .
grep -rn "tessdata" --include="*.xml" .

# Find all page.Text and page.GetText() calls — the primary output pattern
grep -rn "page\.Text\|page\.GetText()" --include="*.cs" .

# Find GetMeanConfidence calls — confidence scale will change
grep -rn "GetMeanConfidence" --include="*.cs" .

# Find PDF rasterization libraries that can be removed after migration
grep -rn "PdfiumViewer\|Ghostscript\|PDFsharp" --include="*.cs" .
grep -rn "PdfiumViewer\|Ghostscript\|PdfSharp" --include="*.csproj" .
SHELL

코드를 작성하기 전에 결과를 문서화하십시오. tessdata 경로를 사용하는 호출 위치가 몇 개인지, 신뢰도 점수를 사용하는 경우가 몇 개인지, 그리고 오류 감지를 위해 빈 문자열 반환에 의존하는 코드가 있는지 여부를 확인하십시오.

코드 마이그레이션

  1. 프로젝트 파일에서 TesseractOCR NuGet 패키지를 제거하세요.
  2. IronOcrdotnet add package IronOcr를 통해 설치하세요.
  3. 이전에 .traineddata 파일로 다운로드된 각 언어에 대한 언어 팩을 설치하세요.
  4. 애플리케이션 시작 시 IronOcr.License.LicenseKey = "YOUR-KEY";을 추가하세요.
  5. 모든 using TesseractOCR;using TesseractOCR.Enums; 지시문을 using IronOcr;로 바꾸세요.
  6. 모든 new Engine(tessDataPath, language) 인스턴스를 new IronTesseract()로 바꾸세요.
  7. Pix.Image.LoadFromFile(path)engine.Process(img)ocr.Read(path) 또는 OcrInput 기반 호출로 교체하세요.
  8. page.Textpage.GetText()result.Text로 교체하세요.
  9. 신뢰도 임계값 비교를 업데이트하세요: 이전 float 임계값을 double 백분율 척도로 곱하세요.
  10. +-구분 언어 문자열을 ocr.Languageocr.AddSecondaryLanguage() 호출로 교체하세요.
  11. 빈 문자열 오류 감지를 try/catch IronOcrException로 교체하세요.
  12. 스트림 입력을 위한 임시 파일 패턴을 input.LoadImage(stream)로 교체하세요.
  13. IronOCR의 input.LoadPdf()이 래스터화 절차를 대체하는 경우 PDF 래스터화 라이브러리 참조를 제거하세요.
  14. 배포 아티팩트 및 구성 파일에서 tessdata 디렉터리를 제거하십시오.
  15. 순차적 작업 부하를 위해 DI 컨테이너에서 IronTesseract을 싱글턴으로 등록하세요. 병렬 워크로드의 경우 스레드당 하나의 인스턴스를 사용하십시오.

마이그레이션 이후

  • 이전에 테스트를 통과한 이미지에 대한 OCR 결과가 래퍼의 출력 품질과 동일하거나 그 이상인지 확인하십시오.
  • 엔진 오류가 이제 빈 문자열을 반환하는 대신 IronOcrException를 던지는지 확인하세요.
  • 신뢰도 점수가 0–100 범위 내에 있는지, 그리고 임계값 비교에 업데이트된 척도가 사용되었는지 확인하십시오.
  • 다국어 문서를 테스트하여 해당 언어의 NuGet 패키지가 올바르게 설치되고 인식되는지 확인하십시오.
  • 임시 파일이 생성되지 않는지 확인하기 위해 스트림 및 바이트 배열 입력 경로를 테스트하십시오.
  • PDF 입력을 직접 테스트(래스터화 없이)하여 페이지 수와 텍스트 내용이 정확한지 확인하십시오.
  • PDF 뷰어에서 검색 가능한 PDF 출력물을 테스트하고, 텍스트 검색 결과가 원본 스캔 이미지와 일치하는지 확인하십시오.
  • 배치 처리 경로를 실행하고 재사용되는 IronTesseract 인스턴스로 처리량을 확인하세요.
  • tessdata 디렉터리가 배포에서 제거되었는지, 그리고 해당 디렉터리 없이도 애플리케이션이 정상적으로 시작되는지 확인하십시오.
  • OCR을 수행하는 모든 ASP.NET 엔드포인트에 대해 부하 테스트를 실행하여 요청별 인스턴스를 사용한 스레드 안전성을 검증하십시오.

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

정의된 오류 계약. 마이그레이션 후에는 모든 OCR 오류 발생 시 의미 있는 메시지가 포함된, catch 가능한 타입 지정 예외가 발생합니다. 빈 문자열에 대한 무음 오류 모드가 사라졌습니다. 이전에는 파일 크기 확인, 이미지 분석 실행, 문자 수 비교와 같은 외부 품질 검증 로직이 필요했던 파이프라인은 이제 IronOCR의 예외 모델과 신뢰도 점수를 대신 활용할 수 있습니다.

추가 라이브러리 없는 출력 형식 커버리지. 모든 Read() 호출에서 돌아오는 OcrResult 객체는 추가 패키지 없이 일반 텍스트, 검색 가능한 PDF 및 hOCR 내보내기를 지원합니다. 규정 준수 아카이브를 위한 검색 가능한 PDF 생성 및 접근성 파이프라인을 위한 hOCR 내보내기가, 여러 라이브러리를 통합하는 대규모 프로젝트가 아닌 단 두 줄의 코드로 구현됩니다.

문서 인텔리전스를 위한 구조화된 데이터. 모든 결과 객체에는 페이지, 단락, 줄, 단어, 문자까지의 완전한 WORD 계층 구조와 함께 바운딩 박스 좌표 및 WORD별 신뢰도 정보가 제공됩니다. 이전에는 불안정한 정규 표현식을 사용하여 평면 문자열을 파싱하던 송장 추출기, 정보 마스킹 도구 및 양식 처리기가 공간적 컨텍스트를 확보함으로써, 레이아웃에 구애받지 않고 필드를 식별할 수 있게 되었습니다. OCR 결과 기능 페이지는 전체 데이터 모델을 다룹니다.

네이티브 PDF 및 다중 형식 입력. PDF 래스터화 라이브러리와 관련 구성 항목이 종속성 그래프에서 사라집니다. 스트림과 바이트 배열은 임시 파일 없이 OcrInput에 직접 로드됩니다. 단일 호출로 다중 프레임 TIFF를 처리합니다. 래퍼를 둘러싸고 있던 입력 처리 코드(형식 감지, 임시 파일 관리, 정리 로직)는 통합된 로딩 API로 대체되었습니다.

환경 구성 없이 배포. tessdata 디렉터리, 네이티브 바이너리 버전 확인, 플랫폼별 바이너리 배포 단계가 제거되었습니다. IronOCR은 엔진과 언어 데이터를 NuGet 패키지에 포함하여 제공합니다. Docker, Linux, Azure 또는 AWS에 배포할 , 한 줄짜리 라이브러리 종속성 설정 외에 별도의 환경별 구성은 필요하지 않습니다.

유료 지원 및 예측 가능한 라이선스. 이 래퍼는 커뮤니티에서 유지 관리하며 별도의 지원 계약은 없습니다. IronOCR은 이메일 지원, 전담 문서화 팀, 그리고 .NET Version 호환성을 보장하는 정기적인 릴리스를 제공합니다. 영구 라이선스 모델 — Lite 등급의 시작 가격이 $999에서 시작 — 은 페이지당 청구의 놀라움을 없애고 새로운 .NET 버전의 접근을 차단하는 구독 갱신이 없습니다. 라이선스 비용은 일반적으로 래퍼의 미비점으로 인해 발생하는 통합 작업을 제거하는 첫 번째 반복 과정에서 회수됩니다.

참고해 주세요: Ghostscript, PDFium, PDFSharp, Tesseract, 및 iText는 각각의 소유자의 등록 상표입니다. 이 사이트는 Artifex Software, Chromium Project, Google, empira Software GmbH 또는 iText Group와 관련이 없으며, 지지받거나 후원받지 않습니다. 모든 제품명, 로고 및 브랜드는 각각의 소유자의 자산입니다. 비교는 정보 제공 목적으로만 사용되며, 작성 시점에 공개적으로 이용 가능한 정보를 반영합니다.

관련 기사

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일 무료 체험판 키를 받으세요.
신용카드나 계정 생성은 필요하지 않습니다.