푸터 콘텐츠로 바로가기
동영상

C#에서 여러 프레임 페이지로 구성된 GIF 및 TIFF 파일을 읽는 방법

이 가이드는 .NET 개발자가 PaddleSharp OCR(Sdcb.PaddleOCR)에서 IronOCR로 완전히 마이그레이션하는 과정을 안내합니다. 이 내용은 추론 세션 관리 교체, OpenCV 전처리 종속성 제거, CPU, GPU 및 OpenVINO에 대한 백엔드 선택 로직 제거, 테이블 인식 워크플로 마이그레이션 등을 다룹니다. 각 섹션은 일반적인 OCR 비교에는 나타나지 않는 PaddleSharp 고유 패턴에서 추출한 변환 전후 코드를 제공합니다.

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

PaddleSharp는 애플리케이션 계층에서 딥러닝 추론 파이프라인을 제공합니다. 해당 아키텍처를 사용하면 PaddlePaddle 모델의 성능을 활용할 수 있지만, 애플리케이션이 인프라 관련 문제를 직접 관리해야 합니다. 대부분의 .NET 팀이 대안을 찾는 주된 이유는 다음과 같은 문제점 때문입니다.

추론 백엔드 구성은 애플리케이션 코드입니다. PaddleSharp에서 CPU, GPU 및 OpenVINO 백엔드를 선택하려면 PaddleConfig 객체를 구성하고 올바른 네이티브 런타임 NuGet 패키지를 배포 대상에 선택하며 런타임에 하드웨어에 따라 초기화 코드를 조건적으로 분기해야 합니다. 이 로직은 라이브러리가 아닌 애플리케이션에 존재하며, 대상 환경이 변경되면 작동하지 않습니다.

이미지 입력을 위해서는 OpenCV가 필수적입니다. PaddleSharp는 파일 경로 또는 스트림을 직접 입력받을 수 없습니다. 모든 이미지는 OCR 엔진에 도달하기 전에 OpenCV의 Cv2.ImRead()을(를) 통과합니다. 이는 OpenCvSharp4과 플랫폼 특정 OpenCvSharp4.runtime.* 패키지를 의존성 그래프에 포함시킵니다. 한 플랫폼의 런타임만 업데이트하고 다른 플랫폼의 런타임을 업데이트하지 않으면 환경 간에 재현하기 어려운 런타임 오류가 발생합니다.

추론 세션 수명은 명시적인 설계를 요구합니다. PaddleOcrAll는 생성 시 세 가지 모델 바이너리를 디스크에서 로드합니다. 수백 밀리초로 측정 가능한 그 비용은 객체를 요청 시마다 인스턴스화할 수 없다는 것을 의미합니다. 팀은 싱글톤, 풀링, 또는 범위 지정된 생활 주기 전략을 설계해야 합니다. ASP.NET Core에서는 일반적으로 PaddleOcrAll가 기본 네이티브 상태를 공유하기 때문에, 세심한 스레드 안전성 분석과 함께 등록된 서비스를 의미합니다.

표 인식을 위해서는 별도의 모델 다운로드가 필요합니다. PaddleSharp에서 구조화된 문서를 추출하려면 표준 3단계 탐지/분류/인식 파이프라인 외에 전용 표 인식 모델이 필요합니다. 이 모델은 다운로드, 버전 관리 및 구성해야 하는 네 번째 파일입니다. 통합된 API 인터페이스는 없습니다. 테이블 인식은 별도의 코드 경로와 고유한 결과 유형을 사용합니다.

검색 가능한 PDF 출력이 없습니다. PaddleSharp는 텍스트 문자열을 생성합니다. 검색 가능한 PDF 파일을 생성할 수 없습니다. 스캔한 문서를 텍스트 검색이 가능한 PDF로 보관해야 하는 팀은 별도의 PDF 라이브러리를 통합하고, 해당 추가 종속성을 관리하고, 변환 레이어를 작성해야 합니다. 출력 형식에 있어서 완전한 공백이 생겼습니다. hOCR도 없고, 구조화된 검색 가능한 PDF도 없고, 텍스트 레이어 오버레이도 없습니다.

상위 종속성 체인은 .NET 커뮤니티의 소유가 아닙니다. PaddleSharp는 Baidu의 PaddlePaddle 추론 프레임워크를 래핑합니다. PaddleOCR 버전 간 모델 형식 변경으로 인해 과거에 .NET 바인딩 계층이 제대로 작동하지 않았던 사례가 있습니다. 문제 추적, 문서 작성 및 릴리스 관련 논의는 대부분 중국어로 진행됩니다. 중국어 구사자가 없는 .NET 팀이 상위 프로젝트를 모니터링할 때, 호환성을 깨뜨리는 변경 사항이 예고 없이 발생합니다.

근본적인 문제

PaddleSharp에서 백엔드를 선택하고 초기화하려면 OCR 로직이 아닌 인프라에 속하는 구성 코드가 필요합니다.

// PaddleSharp: Backend selection sprawls into application startup
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;

// CPU-only deployment
var config = PaddleConfig.FromModelDir("models/det");
config.SetCpuMathLibraryNumThreads(4);

// GPU deployment — different package, different init path
// var config = PaddleConfig.FromModelDir("models/det");
// config.EnableGpu(500, 0);  // memoryMB, deviceId

// OpenVINO deployment — third conditional branch
// config.EnableMkldnn();

// Application code now owns the hardware topology decision
// PaddleSharp: Backend selection sprawls into application startup
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;

// CPU-only deployment
var config = PaddleConfig.FromModelDir("models/det");
config.SetCpuMathLibraryNumThreads(4);

// GPU deployment — different package, different init path
// var config = PaddleConfig.FromModelDir("models/det");
// config.EnableGpu(500, 0);  // memoryMB, deviceId

// OpenVINO deployment — third conditional branch
// config.EnableMkldnn();

// Application code now owns the hardware topology decision
Imports Sdcb.PaddleInference
Imports Sdcb.PaddleOCR

' PaddleSharp: Backend selection sprawls into application startup
' Simplified — see Sdcb.PaddleInference documentation for full API

' CPU-only deployment
Dim config = PaddleConfig.FromModelDir("models/det")
config.SetCpuMathLibraryNumThreads(4)

' GPU deployment — different package, different init path
' Dim config = PaddleConfig.FromModelDir("models/det")
' config.EnableGpu(500, 0)  ' memoryMB, deviceId

' OpenVINO deployment — third conditional branch
' config.EnableMkldnn()

' Application code now owns the hardware topology decision
$vbLabelText   $csharpLabel
// IronOCR: 아니요 backend selection. 아니요 config objects. Zero hardware decisions.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var result = new IronTesseract().Read("document.jpg");
Console.WriteLine(result.Text);
// Runs on CPU, Linux, Docker, or ARM without a code change
// IronOCR: 아니요 backend selection. 아니요 config objects. Zero hardware decisions.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var result = new IronTesseract().Read("document.jpg");
Console.WriteLine(result.Text);
// Runs on CPU, Linux, Docker, or ARM without a code change
Imports IronOcr

' IronOCR: 아니요 backend selection. 아니요 config objects. Zero hardware decisions.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

Dim result = New IronTesseract().Read("document.jpg")
Console.WriteLine(result.Text)
' Runs on CPU, Linux, Docker, or ARM without a code change
$vbLabelText   $csharpLabel

IronOCR과 PaddleSharp OCR: 기능 비교

다음은 마이그레이션 과정에서 가장 중요한 요소들을 기준으로 한 직접적인 기능 비교입니다.

기능 패들샤프 OCR IronOCR
NuGet 패키지가 필요합니다. 최소 3~4개 1
이미지 입력 ​​방식 OpenCV Cv2.ImRead() 직접 경로, 스트림 또는 바이트 배열
PDF 입력(기본) 아니요
비밀번호로 보호된 PDF 아니요
여러 페이지로 구성된 TIFF 파일 OpenCV를 통해 내부 지원
검색 가능한 PDF 출력 아니요 예 (result.SaveAsSearchablePdf())
hOCR 내보내기 아니요
백엔드 선택 (CPU/GPU/OpenVINO) 수동 PaddleConfig 자동
전처리 파이프라인 OpenCV 수동 작업 내장형 (Deskew, DeNoise, Contrast 등)
추론 세션 수명 주기 관리 수동식(고가의 시공 방식) 경량 IronTesseract
테이블 인식 모델 다운로드 경로와 코드 경로를 분리하세요. input.LoadImage() + 구조화된 결과
지원되는 언어 ~10~20 125+
언어 설치 모델 파일 다운로드 NuGet 패키지
다국어 동시 제한적 예 (OcrLanguage.French + OcrLanguage.German)
영역 기반 OCR 내장형 없음 CropRectangle
OCR 중 바코드 판독 아니요 예 (ocr.Configuration.ReadBarCodes = true)
신뢰도 점수 지역별 단어당, 줄당, 페이지당
구조화된 출력 계층 구조 평평한 지역 목록 페이지 → 단락 → 줄 → 단어 → 문자
크로스 플랫폼 배포 복잡한 (플랫폼 런타임 패키지) 단일 NuGet, 모든 플랫폼 지원
Docker 배포 다중 레이어, 런타임 패키지 단층
상업적 지원 GitHub 이슈(주로 중국어) 이메일 지원
라이선스 모델 Apache 2.0 영구 ($999 Lite, $1,499 Pro, $2,999 Enterprise)

빠른 시작: PaddleSharp OCR에서IronOCR로 마이그레이션

1단계: NuGet 패키지 교체

PaddleSharp와 해당 OpenCV 종속성을 제거하세요.

dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleInference
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleInference
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
SHELL

NuGet 에서IronOCR설치하세요.

dotnet add package IronOcr

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

PaddleSharp 네임스페이스를IronOCR네임스페이스 하나로 대체하십시오.

// Before (PaddleSharp)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleInference;
using OpenCvSharp;

// After (IronOCR)
using IronOcr;
// Before (PaddleSharp)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleInference;
using OpenCvSharp;

// After (IronOCR)
using IronOcr;
Imports IronOcr
$vbLabelText   $csharpLabel

단계 3: 라이선스 초기화

애플리케이션 시작 시 한 번 라이선스 초기화 추가 - Program.cs, Startup.cs 또는 귀하의 컴포지션 루트:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

코드 마이그레이션 예제

추론 세션 수명 주기 교체

PaddleSharp의 PaddleOcrAll은(는) 인스턴스화 시 세 가지 모델 바이너리를 동기적으로 로드하기 때문에 구축하는 데 비용이 많이 듭니다. 실제 운영 환경에서는 이를 수명이 긴 객체로 취급해야 하므로 특정 의존성 주입 패턴이 적용됩니다. 폐기 과정 또한 주의가 필요한데, 기본이 되는 네이티브 리소스가 올바른 순서로 해제되어야 하기 때문입니다.

PaddleSharp OCR 접근 방식:

// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;
using Microsoft.Extensions.DependencyInjection;

// Expensive: loads 3 model files from disk on construction (~300–800ms)
public class PaddleOcrEngine : IDisposable
{
    private readonly PaddleOcrAll _ocr;
    private bool _disposed;

    public PaddleOcrEngine()
    {
        var detModel = LocalFullModels.ChineseV3.DetectionModel;
        var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
        var recModel = LocalFullModels.ChineseV3.RecognitionModel;

        // Must be singleton — cannot afford per-request construction
        _ocr = new PaddleOcrAll(detModel, clsModel, recModel);
    }

    public string Read(string imagePath)
    {
        using var mat = Cv2.ImRead(imagePath); // OpenCV required even for a file path
        var result = _ocr.Run(mat);
        return string.Join(" ", result.Regions.Select(r => r.Text));
    }

    public void Dispose()
    {
        if (!_disposed)
        {
            _ocr?.Dispose();
            _disposed = true;
        }
    }
}

// Startup.cs — forced singleton because of construction cost
services.AddSingleton<PaddleOcrEngine>();
// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;
using Microsoft.Extensions.DependencyInjection;

// Expensive: loads 3 model files from disk on construction (~300–800ms)
public class PaddleOcrEngine : IDisposable
{
    private readonly PaddleOcrAll _ocr;
    private bool _disposed;

    public PaddleOcrEngine()
    {
        var detModel = LocalFullModels.ChineseV3.DetectionModel;
        var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
        var recModel = LocalFullModels.ChineseV3.RecognitionModel;

        // Must be singleton — cannot afford per-request construction
        _ocr = new PaddleOcrAll(detModel, clsModel, recModel);
    }

    public string Read(string imagePath)
    {
        using var mat = Cv2.ImRead(imagePath); // OpenCV required even for a file path
        var result = _ocr.Run(mat);
        return string.Join(" ", result.Regions.Select(r => r.Text));
    }

    public void Dispose()
    {
        if (!_disposed)
        {
            _ocr?.Dispose();
            _disposed = true;
        }
    }
}

// Startup.cs — forced singleton because of construction cost
services.AddSingleton<PaddleOcrEngine>();
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models
Imports OpenCvSharp
Imports Microsoft.Extensions.DependencyInjection

' Expensive: loads 3 model files from disk on construction (~300–800ms)
Public Class PaddleOcrEngine
    Implements IDisposable

    Private ReadOnly _ocr As PaddleOcrAll
    Private _disposed As Boolean

    Public Sub New()
        Dim detModel = LocalFullModels.ChineseV3.DetectionModel
        Dim clsModel = LocalFullModels.ChineseV3.ClassifierModel
        Dim recModel = LocalFullModels.ChineseV3.RecognitionModel

        ' Must be singleton — cannot afford per-request construction
        _ocr = New PaddleOcrAll(detModel, clsModel, recModel)
    End Sub

    Public Function Read(imagePath As String) As String
        Using mat = Cv2.ImRead(imagePath) ' OpenCV required even for a file path
            Dim result = _ocr.Run(mat)
            Return String.Join(" ", result.Regions.Select(Function(r) r.Text))
        End Using
    End Function

    Public Sub Dispose() Implements IDisposable.Dispose
        If Not _disposed Then
            _ocr?.Dispose()
            _disposed = True
        End If
    End Sub
End Class

' Startup.vb — forced singleton because of construction cost
services.AddSingleton(Of PaddleOcrEngine)()
$vbLabelText   $csharpLabel

IronOCR 접근 방식:

using IronOcr;
using Microsoft.Extensions.DependencyInjection;

// IronTesseract has lightweight initialization — no model loading on construction
public class OcrEngine
{
    public string Read(string imagePath)
    {
        return new IronTesseract().Read(imagePath).Text;
    }
}

// Flexible registration — singleton, scoped, or transient all work
services.AddTransient<OcrEngine>();

// Or skip the wrapper entirely and inject IronTesseract directly
services.AddTransient<IronTesseract>();
using IronOcr;
using Microsoft.Extensions.DependencyInjection;

// IronTesseract has lightweight initialization — no model loading on construction
public class OcrEngine
{
    public string Read(string imagePath)
    {
        return new IronTesseract().Read(imagePath).Text;
    }
}

// Flexible registration — singleton, scoped, or transient all work
services.AddTransient<OcrEngine>();

// Or skip the wrapper entirely and inject IronTesseract directly
services.AddTransient<IronTesseract>();
Imports IronOcr
Imports Microsoft.Extensions.DependencyInjection

' IronTesseract has lightweight initialization — no model loading on construction
Public Class OcrEngine
    Public Function Read(imagePath As String) As String
        Return New IronTesseract().Read(imagePath).Text
    End Function
End Class

' Flexible registration — singleton, scoped, or transient all work
services.AddTransient(Of OcrEngine)()

' Or skip the wrapper entirely and inject IronTesseract directly
services.AddTransient(Of IronTesseract)()
$vbLabelText   $csharpLabel

강제 단일 수명 방식에서 유연한 수명 방식으로의 Shift 매우 중요합니다. PaddleSharp의 건설 비용은 서비스 이용 기간 결정에 중요한 영향을 미칩니다.IronOCR사용하면 애플리케이션의 스레딩 및 요청 격리 요구 사항에 따라 선택할 수 있습니다. IronTesseract 설정 가이드에서는 인스턴스 수준에 적용되는 구성 옵션을 다룹니다.

OpenCV 전처리 파이프라인 마이그레이션

PaddleSharp 팀은 일반적으로 스캔 품질이 낮은 경우 OCR 엔진을 호출하기 전에 OpenCV 전처리 파이프라인을 구축합니다. 이 파이프라인은 OpenCV API의 다양한 기능에 대한 지식을 필요로 하는데, 이는 실제 OCR 전처리 작업에 필요한 것보다 훨씬 방대합니다. 일반적인 작업 — 탈왜곡, 잡음 제거, 대비 확장 —는 여러 Mat 작업과 기본 메모리 누수를 방지하기 위해 using 블록 내에서 주의 깊은 메모리 관리를 필요로 합니다.

PaddleSharp OCR 접근 방식:

// Simplified — see OpenCvSharp documentation for full API
using OpenCvSharp;
using Sdcb.PaddleOCR;

public string ReadWithPreprocessing(string imagePath, PaddleOcrAll ocr)
{
    using var original = Cv2.ImRead(imagePath);

    // Step 1: Grayscale conversion
    using var gray = new Mat();
    Cv2.CvtColor(original, gray, ColorConversionCodes.BGR2GRAY);

    // Step 2: Denoise (Gaussian blur to reduce noise)
    using var denoised = new Mat();
    Cv2.GaussianBlur(gray, denoised, new Size(3, 3), 0);

    // Step 3: Adaptive threshold for binarization
    using var binary = new Mat();
    Cv2.AdaptiveThreshold(denoised, binary, 255,
        AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2);

    // Step 4: Deskew — requires custom rotation detection logic (not shown)
    // Several dozen lines of custom Mat operations

    var result = ocr.Run(binary);
    return string.Join(" ", result.Regions.Select(r => r.Text));
    // Each Mat must be disposed; missing a using block leaks native memory
}
// Simplified — see OpenCvSharp documentation for full API
using OpenCvSharp;
using Sdcb.PaddleOCR;

public string ReadWithPreprocessing(string imagePath, PaddleOcrAll ocr)
{
    using var original = Cv2.ImRead(imagePath);

    // Step 1: Grayscale conversion
    using var gray = new Mat();
    Cv2.CvtColor(original, gray, ColorConversionCodes.BGR2GRAY);

    // Step 2: Denoise (Gaussian blur to reduce noise)
    using var denoised = new Mat();
    Cv2.GaussianBlur(gray, denoised, new Size(3, 3), 0);

    // Step 3: Adaptive threshold for binarization
    using var binary = new Mat();
    Cv2.AdaptiveThreshold(denoised, binary, 255,
        AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2);

    // Step 4: Deskew — requires custom rotation detection logic (not shown)
    // Several dozen lines of custom Mat operations

    var result = ocr.Run(binary);
    return string.Join(" ", result.Regions.Select(r => r.Text));
    // Each Mat must be disposed; missing a using block leaks native memory
}
Imports OpenCvSharp
Imports Sdcb.PaddleOCR

Public Function ReadWithPreprocessing(imagePath As String, ocr As PaddleOcrAll) As String
    Using original As Mat = Cv2.ImRead(imagePath)

        ' Step 1: Grayscale conversion
        Using gray As New Mat()
            Cv2.CvtColor(original, gray, ColorConversionCodes.BGR2GRAY)

            ' Step 2: Denoise (Gaussian blur to reduce noise)
            Using denoised As New Mat()
                Cv2.GaussianBlur(gray, denoised, New Size(3, 3), 0)

                ' Step 3: Adaptive threshold for binarization
                Using binary As New Mat()
                    Cv2.AdaptiveThreshold(denoised, binary, 255, AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2)

                    ' Step 4: Deskew — requires custom rotation detection logic (not shown)
                    ' Several dozen lines of custom Mat operations

                    Dim result = ocr.Run(binary)
                    Return String.Join(" ", result.Regions.Select(Function(r) r.Text))
                End Using
            End Using
        End Using
    End Using
End Function
$vbLabelText   $csharpLabel

IronOCR 접근 방식:

using IronOcr;

public string ReadWithPreprocessing(string imagePath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);

    // Named operations replace OpenCV knowledge requirements
    input.Deskew();
    input.DeNoise();
    input.Contrast();
    input.Binarize();

    var result = new IronTesseract().Read(input);
    return result.Text;
    // OcrInput implements IDisposable; using block handles cleanup
}
using IronOcr;

public string ReadWithPreprocessing(string imagePath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);

    // Named operations replace OpenCV knowledge requirements
    input.Deskew();
    input.DeNoise();
    input.Contrast();
    input.Binarize();

    var result = new IronTesseract().Read(input);
    return result.Text;
    // OcrInput implements IDisposable; using block handles cleanup
}
Imports IronOcr

Public Function ReadWithPreprocessing(imagePath As String) As String
    Using input As New OcrInput()
        input.LoadImage(imagePath)

        ' Named operations replace OpenCV knowledge requirements
        input.Deskew()
        input.DeNoise()
        input.Contrast()
        input.Binarize()

        Dim result = New IronTesseract().Read(input)
        Return result.Text
        ' OcrInput implements IDisposable; using block handles cleanup
    End Using
End Function
$vbLabelText   $csharpLabel

아니요 Mat 할당. 적응형 임계값 매개변수에 대한 지식이 없습니다. 사용자 지정 기울기 보정 회전 계산은 없습니다. 이전에는 30~50줄의 OpenCV 코드가 필요했던 전처리 파이프라인이 이제는 네 번의 메서드 호출만으로 구현됩니다. 이미지 품질 보정 가이드 에는 사용 가능한 모든 필터와 보정 전후 예시가 자세히 설명되어 있습니다. 강한 백그라운드 노이즈가 있는 문서의 경우, input.DeepCleanBackgroundNoise()는 추가 매개변수 없이 DeNoise()보다 더 나아갑니다.

전처리 요구 사항이 표준적이지 않은 팀의 경우 필터 마법사는 코드를 작성하기 전에 특정 문서 유형에 대한 필터 조합을 평가할 수 있는 대화형 도구를 제공합니다.

백엔드 선택 제거

PaddleSharp는 추론 백엔드를 애플리케이션 수준의 문제로 노출합니다. CPU 전용 클라우드 VM에서 실행해야 하는 배포는 GPU 워크스테이션이나 Intel OpenVINO 지원 엣지 디바이스를 대상으로 하는 배포와 초기화 코드가 다릅니다. 이러한 조건부 로직은 일반적으로 애플리케이션 시작 코드, 환경 변수 검사 또는 기능 플래그와 같은 인프라 작업에 포함되며, 이미지에서 텍스트를 읽는 작업과는 전혀 관련이 없습니다.

PaddleSharp OCR 접근 방식:

// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;

public PaddleOcrAll CreateOcrEngine(string backendMode)
{
    // Each backend requires a different NuGet runtime package installed
    switch (backendMode)
    {
        case "gpu":
            // Requires: Sdcb.PaddleInference.runtime.win64.cuda
            // Requires: CUDA toolkit + cuDNN installed on host
            var gpuConfig = PaddleConfig.FromModelDir("models/");
            gpuConfig.EnableGpu(500, deviceId: 0); // Simplified
            break;

        case "openvino":
            // Requires: Sdcb.PaddleInference.runtime.win64.mkl
            var oviConfig = PaddleConfig.FromModelDir("models/");
            oviConfig.EnableMkldnn(); // Simplified
            break;

        default:
            // CPU-only — still requires platform-specific runtime package
            var cpuConfig = PaddleConfig.FromModelDir("models/");
            cpuConfig.SetCpuMathLibraryNumThreads(Environment.ProcessorCount);
            break;
    }

    // Backend-specific config passed to model constructors — Simplified
    var detModel = LocalFullModels.ChineseV3.DetectionModel;
    var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
    var recModel = LocalFullModels.ChineseV3.RecognitionModel;
    return new PaddleOcrAll(detModel, clsModel, recModel);
}
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;

public PaddleOcrAll CreateOcrEngine(string backendMode)
{
    // Each backend requires a different NuGet runtime package installed
    switch (backendMode)
    {
        case "gpu":
            // Requires: Sdcb.PaddleInference.runtime.win64.cuda
            // Requires: CUDA toolkit + cuDNN installed on host
            var gpuConfig = PaddleConfig.FromModelDir("models/");
            gpuConfig.EnableGpu(500, deviceId: 0); // Simplified
            break;

        case "openvino":
            // Requires: Sdcb.PaddleInference.runtime.win64.mkl
            var oviConfig = PaddleConfig.FromModelDir("models/");
            oviConfig.EnableMkldnn(); // Simplified
            break;

        default:
            // CPU-only — still requires platform-specific runtime package
            var cpuConfig = PaddleConfig.FromModelDir("models/");
            cpuConfig.SetCpuMathLibraryNumThreads(Environment.ProcessorCount);
            break;
    }

    // Backend-specific config passed to model constructors — Simplified
    var detModel = LocalFullModels.ChineseV3.DetectionModel;
    var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
    var recModel = LocalFullModels.ChineseV3.RecognitionModel;
    return new PaddleOcrAll(detModel, clsModel, recModel);
}
Imports Sdcb.PaddleInference
Imports Sdcb.PaddleOCR

Public Function CreateOcrEngine(ByVal backendMode As String) As PaddleOcrAll
    ' Each backend requires a different NuGet runtime package installed
    Select Case backendMode
        Case "gpu"
            ' Requires: Sdcb.PaddleInference.runtime.win64.cuda
            ' Requires: CUDA toolkit + cuDNN installed on host
            Dim gpuConfig As PaddleConfig = PaddleConfig.FromModelDir("models/")
            gpuConfig.EnableGpu(500, deviceId:=0) ' Simplified

        Case "openvino"
            ' Requires: Sdcb.PaddleInference.runtime.win64.mkl
            Dim oviConfig As PaddleConfig = PaddleConfig.FromModelDir("models/")
            oviConfig.EnableMkldnn() ' Simplified

        Case Else
            ' CPU-only — still requires platform-specific runtime package
            Dim cpuConfig As PaddleConfig = PaddleConfig.FromModelDir("models/")
            cpuConfig.SetCpuMathLibraryNumThreads(Environment.ProcessorCount)
    End Select

    ' Backend-specific config passed to model constructors — Simplified
    Dim detModel = LocalFullModels.ChineseV3.DetectionModel
    Dim clsModel = LocalFullModels.ChineseV3.ClassifierModel
    Dim recModel = LocalFullModels.ChineseV3.RecognitionModel
    Return New PaddleOcrAll(detModel, clsModel, recModel)
End Function
$vbLabelText   $csharpLabel

IronOCR 접근 방식:

using IronOcr;

// 아니요 backend selection. 아니요 switch statement. 아니요 environment variable check.
// The same code runs on CPU-only VMs, GPU workstations, and ARM devices.
public IronTesseract CreateOcrEngine()
{
    return new IronTesseract();
}

// Parallel processing across CPU cores — no GPU configuration required
public IEnumerable<string> ReadBatch(IEnumerable<string> imagePaths)
{
    var results = new System.Collections.Concurrent.ConcurrentBag<string>();
    Parallel.ForEach(imagePaths, path =>
    {
        var result = new IronTesseract().Read(path);
        results.Add(result.Text);
    });
    return results;
}
using IronOcr;

// 아니요 backend selection. 아니요 switch statement. 아니요 environment variable check.
// The same code runs on CPU-only VMs, GPU workstations, and ARM devices.
public IronTesseract CreateOcrEngine()
{
    return new IronTesseract();
}

// Parallel processing across CPU cores — no GPU configuration required
public IEnumerable<string> ReadBatch(IEnumerable<string> imagePaths)
{
    var results = new System.Collections.Concurrent.ConcurrentBag<string>();
    Parallel.ForEach(imagePaths, path =>
    {
        var result = new IronTesseract().Read(path);
        results.Add(result.Text);
    });
    return results;
}
Imports IronOcr
Imports System.Collections.Concurrent
Imports System.Threading.Tasks

Public Class OcrProcessor
    ' 아니요 backend selection. 아니요 switch statement. 아니요 environment variable check.
    ' The same code runs on CPU-only VMs, GPU workstations, and ARM devices.
    Public Function CreateOcrEngine() As IronTesseract
        Return New IronTesseract()
    End Function

    ' Parallel processing across CPU cores — no GPU configuration required
    Public Function ReadBatch(imagePaths As IEnumerable(Of String)) As IEnumerable(Of String)
        Dim results As New ConcurrentBag(Of String)()
        Parallel.ForEach(imagePaths, Sub(path)
                                         Dim result = New IronTesseract().Read(path)
                                         results.Add(result.Text)
                                     End Sub)
        Return results
    End Function
End Class
$vbLabelText   $csharpLabel

여기 있는 Parallel.ForEach 패턴은 기본적으로 스레드 안전합니다. 각 IronTesseract 인스턴스는 독립적이며 공유 네이티브 상태가 없습니다. PaddleSharp 배포에서 백엔드 조건 관리에 시간을 소비하는 팀의 경우, 이러한 간소화는 배포 안정성 향상으로도 이어집니다. 동일한 빌드 아티팩트가 하드웨어 감지 코드 없이 모든 곳에서 실행되기 때문입니다. 속도 최적화 가이드에서는 처리량에 민감한 시나리오에 대한 구성 옵션을 다룹니다.

테이블 인식 마이그레이션

PaddleSharp에서 테이블 추출을 하려면 별도의 테이블 인식 모델이 필요합니다. 이는 표준 감지, 분류 및 인식 세트 외에 네 번째 모델 파일입니다. 테이블 모델은 별도의 API 호출을 사용하며 자체적인 결과 구조를 반환합니다. 송장, 양식 또는 스프레드시트 처리 파이프라인을 구축하는 팀은 두 개의 병렬 초기화 경로와 두 개의 결과 구문 분석 전략을 유지합니다.

PaddleSharp OCR 접근 방식:

// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;

public class TableRecognitionService
{
    // Standard OCR engine — 3 models
    private readonly PaddleOcrAll _textOcr;

    // Table engine — 4th model, separate initialization
    // private readonly PaddleOcrTable _tableOcr; // Simplified

    public TableRecognitionService()
    {
        var detModel = LocalFullModels.ChineseV3.DetectionModel;
        var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
        var recModel = LocalFullModels.ChineseV3.RecognitionModel;
        _textOcr = new PaddleOcrAll(detModel, clsModel, recModel);

        // Table model: separate download, separate version tracking
        // var tableModel = LocalFullModels.TableEnV2.Model; // Simplified
        // _tableOcr = new PaddleOcrTable(tableModel); // Simplified
    }

    public void ProcessDocument(string imagePath)
    {
        using var image = Cv2.ImRead(imagePath);

        // Text extraction path
        var textResult = _textOcr.Run(image);
        var text = string.Join(" ", textResult.Regions.Select(r => r.Text));

        // Table extraction path — different API, different result structure
        // var tableResult = _tableOcr.Run(image); // Simplified
        // foreach (var cell in tableResult.Cells) { ... } // Simplified
    }
}
// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;

public class TableRecognitionService
{
    // Standard OCR engine — 3 models
    private readonly PaddleOcrAll _textOcr;

    // Table engine — 4th model, separate initialization
    // private readonly PaddleOcrTable _tableOcr; // Simplified

    public TableRecognitionService()
    {
        var detModel = LocalFullModels.ChineseV3.DetectionModel;
        var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
        var recModel = LocalFullModels.ChineseV3.RecognitionModel;
        _textOcr = new PaddleOcrAll(detModel, clsModel, recModel);

        // Table model: separate download, separate version tracking
        // var tableModel = LocalFullModels.TableEnV2.Model; // Simplified
        // _tableOcr = new PaddleOcrTable(tableModel); // Simplified
    }

    public void ProcessDocument(string imagePath)
    {
        using var image = Cv2.ImRead(imagePath);

        // Text extraction path
        var textResult = _textOcr.Run(image);
        var text = string.Join(" ", textResult.Regions.Select(r => r.Text));

        // Table extraction path — different API, different result structure
        // var tableResult = _tableOcr.Run(image); // Simplified
        // foreach (var cell in tableResult.Cells) { ... } // Simplified
    }
}
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models
Imports OpenCvSharp

Public Class TableRecognitionService
    ' Standard OCR engine — 3 models
    Private ReadOnly _textOcr As PaddleOcrAll

    ' Table engine — 4th model, separate initialization
    ' Private ReadOnly _tableOcr As PaddleOcrTable ' Simplified

    Public Sub New()
        Dim detModel = LocalFullModels.ChineseV3.DetectionModel
        Dim clsModel = LocalFullModels.ChineseV3.ClassifierModel
        Dim recModel = LocalFullModels.ChineseV3.RecognitionModel
        _textOcr = New PaddleOcrAll(detModel, clsModel, recModel)

        ' Table model: separate download, separate version tracking
        ' Dim tableModel = LocalFullModels.TableEnV2.Model ' Simplified
        ' _tableOcr = New PaddleOcrTable(tableModel) ' Simplified
    End Sub

    Public Sub ProcessDocument(imagePath As String)
        Using image = Cv2.ImRead(imagePath)
            ' Text extraction path
            Dim textResult = _textOcr.Run(image)
            Dim text = String.Join(" ", textResult.Regions.Select(Function(r) r.Text))

            ' Table extraction path — different API, different result structure
            ' Dim tableResult = _tableOcr.Run(image) ' Simplified
            ' For Each cell In tableResult.Cells ' Simplified
            ' ... 
            ' Next
        End Using
    End Sub
End Class
$vbLabelText   $csharpLabel

IronOCR 접근 방식:

using IronOcr;

public class TableRecognitionService
{
    // One engine handles both text and table regions
    public void ProcessDocument(string imagePath)
    {
        var ocr = new IronTesseract();
        var result = ocr.Read(imagePath);

        // Structured hierarchy: pages → paragraphs → lines → words
        foreach (var page in result.Pages)
        {
            foreach (var paragraph in page.Paragraphs)
            {
                Console.WriteLine($"Block at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");
            }
        }

        Console.WriteLine($"Full document text: {result.Text}");
    }
}
using IronOcr;

public class TableRecognitionService
{
    // One engine handles both text and table regions
    public void ProcessDocument(string imagePath)
    {
        var ocr = new IronTesseract();
        var result = ocr.Read(imagePath);

        // Structured hierarchy: pages → paragraphs → lines → words
        foreach (var page in result.Pages)
        {
            foreach (var paragraph in page.Paragraphs)
            {
                Console.WriteLine($"Block at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");
            }
        }

        Console.WriteLine($"Full document text: {result.Text}");
    }
}
Imports IronOcr

Public Class TableRecognitionService
    ' One engine handles both text and table regions
    Public Sub ProcessDocument(imagePath As String)
        Dim ocr As New IronTesseract()
        Dim result = ocr.Read(imagePath)

        ' Structured hierarchy: pages → paragraphs → lines → words
        For Each page In result.Pages
            For Each paragraph In page.Paragraphs
                Console.WriteLine($"Block at ({paragraph.X},{paragraph.Y}): {paragraph.Text}")
            Next
        Next

        Console.WriteLine($"Full document text: {result.Text}")
    End Sub
End Class
$vbLabelText   $csharpLabel

테이블 구조 자체를 행과 열로 추출해야 하는 문서의 경우,IronOCR테이블 추출 전용 기능을 제공합니다.

using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice-with-table.jpg");

var result = ocr.Read(input);

// Access structured page layout for table region extraction
foreach (var page in result.Pages)
{
    foreach (var line in page.Lines)
    {
        // Lines within a table region preserve spatial ordering
        Console.WriteLine($"Row text: {line.Text} | Y position: {line.Y}");
        foreach (var word in line.Words)
        {
            Console.WriteLine($"  Cell: '{word.Text}' at X={word.X}");
        }
    }
}
using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice-with-table.jpg");

var result = ocr.Read(input);

// Access structured page layout for table region extraction
foreach (var page in result.Pages)
{
    foreach (var line in page.Lines)
    {
        // Lines within a table region preserve spatial ordering
        Console.WriteLine($"Row text: {line.Text} | Y position: {line.Y}");
        foreach (var word in line.Words)
        {
            Console.WriteLine($"  Cell: '{word.Text}' at X={word.X}");
        }
    }
}
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("invoice-with-table.jpg")

    Dim result = ocr.Read(input)

    ' Access structured page layout for table region extraction
    For Each page In result.Pages
        For Each line In page.Lines
            ' Lines within a table region preserve spatial ordering
            Console.WriteLine($"Row text: {line.Text} | Y position: {line.Y}")
            For Each word In line.Words
                Console.WriteLine($"  Cell: '{word.Text}' at X={word.X}")
            Next
        Next
    Next
End Using
$vbLabelText   $csharpLabel

모델 다운로드 하나가 삭제되었습니다. 초기화 경로 하나가 제거되었습니다.IronOCR의 구조화된 결과 계층 구조는 단어 수준의 X/Y 좌표를 제공하여 별도의 인식 모델 없이도 표의 행과 열을 재구성하는 데 필요한 위치 데이터를 제공합니다. 테이블 읽기 가이드결과 읽기 가이드는 구조화된 출력 API의 전체 내용을 다룹니다.

스캔한 문서에서 검색 가능한 PDF 출력

PaddleSharp는 텍스트 문자열만 출력합니다. 스캔한 PDF 파일에서 텍스트를 검색할 수 있는 문서 아카이브를 구축하려면 별도의 PDF 라이브러리를 통합하고, 텍스트 오버레이 레이어를 작성하고, 두 라이브러리를 동시에 관리해야 합니다. 그러한 제약을 받아들인 팀은 종종 그것이 마이그레이션의 계기가 된다는 것을 알게 됩니다. 두 라이브러리 통합에 드는 노력이 OCR 공급업체를 바꾸는 데 드는 노력보다 크기 때문입니다.

PaddleSharp OCR 접근 방식:

// Simplified — PaddleSharp has no PDF output. Requires a separate PDF library.
// Example of what teams typically build:

// using Sdcb.PaddleOCR;
// using SomePdfLibrary; // Third dependency to produce searchable PDF

public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
    // Step 1: OCR via PaddleSharp — produces text only
    // var text = _ocr.Run(Cv2.ImRead(imagePath));

    // Step 2: Build a PDF with text overlay using a separate PDF library
    // Requires: text positions mapped to PDF coordinate space
    // Requires: image embedded as background
    // Requires: invisible text layer positioned over image
    // ~50–100 lines of PDF construction code
    throw new NotImplementedException("Requires a separate PDF library");
}
// Simplified — PaddleSharp has no PDF output. Requires a separate PDF library.
// Example of what teams typically build:

// using Sdcb.PaddleOCR;
// using SomePdfLibrary; // Third dependency to produce searchable PDF

public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
    // Step 1: OCR via PaddleSharp — produces text only
    // var text = _ocr.Run(Cv2.ImRead(imagePath));

    // Step 2: Build a PDF with text overlay using a separate PDF library
    // Requires: text positions mapped to PDF coordinate space
    // Requires: image embedded as background
    // Requires: invisible text layer positioned over image
    // ~50–100 lines of PDF construction code
    throw new NotImplementedException("Requires a separate PDF library");
}
Public Sub ArchiveScannedDocument(imagePath As String, outputPdfPath As String)
    ' Step 1: OCR via PaddleSharp — produces text only
    ' Dim text = _ocr.Run(Cv2.ImRead(imagePath))

    ' Step 2: Build a PDF with text overlay using a separate PDF library
    ' Requires: text positions mapped to PDF coordinate space
    ' Requires: image embedded as background
    ' Requires: invisible text layer positioned over image
    ' ~50–100 lines of PDF construction code
    Throw New NotImplementedException("Requires a separate PDF library")
End Sub
$vbLabelText   $csharpLabel

IronOCR 접근 방식:

using IronOcr;

public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    input.Deskew();   // Straighten scan before archiving
    input.DeNoise();  // Clean up scan artifacts

    var ocr = new IronTesseract();
    var result = ocr.Read(input);

    // One call: OCR + searchable PDF with text layer + image background
    result.SaveAsSearchablePdf(outputPdfPath);
}

// Multi-page document — same pattern
public void ArchiveMultiPageDocument(string[] imageFiles, string outputPdfPath)
{
    using var input = new OcrInput();
    foreach (var file in imageFiles)
        input.LoadImage(file);

    var result = new IronTesseract().Read(input);
    result.SaveAsSearchablePdf(outputPdfPath);
}
using IronOcr;

public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    input.Deskew();   // Straighten scan before archiving
    input.DeNoise();  // Clean up scan artifacts

    var ocr = new IronTesseract();
    var result = ocr.Read(input);

    // One call: OCR + searchable PDF with text layer + image background
    result.SaveAsSearchablePdf(outputPdfPath);
}

// Multi-page document — same pattern
public void ArchiveMultiPageDocument(string[] imageFiles, string outputPdfPath)
{
    using var input = new OcrInput();
    foreach (var file in imageFiles)
        input.LoadImage(file);

    var result = new IronTesseract().Read(input);
    result.SaveAsSearchablePdf(outputPdfPath);
}
Imports IronOcr

Public Sub ArchiveScannedDocument(imagePath As String, outputPdfPath As String)
    Using input As New OcrInput()
        input.LoadImage(imagePath)
        input.Deskew()   ' Straighten scan before archiving
        input.DeNoise()  ' Clean up scan artifacts

        Dim ocr As New IronTesseract()
        Dim result = ocr.Read(input)

        ' One call: OCR + searchable PDF with text layer + image background
        result.SaveAsSearchablePdf(outputPdfPath)
    End Using
End Sub

' Multi-page document — same pattern
Public Sub ArchiveMultiPageDocument(imageFiles As String(), outputPdfPath As String)
    Using input As New OcrInput()
        For Each file In imageFiles
            input.LoadImage(file)
        Next

        Dim result = New IronTesseract().Read(input)
        result.SaveAsSearchablePdf(outputPdfPath)
    End Using
End Sub
$vbLabelText   $csharpLabel

PDF 라이브러리가 없습니다. 좌표 매핑 없음. 텍스트 레이어 위치 지정 없음.IronOCR의 검색 가능한 PDF 출력 형식은 원본 이미지 위에 보이지 않는 텍스트 레이어를 삽입하여 스캔한 문서의 시각적 형태를 그대로 유지하면서도 텍스트 검색이 완벽하게 가능한 파일을 생성합니다. 검색 가능한 PDF 사용 설명서에는 페이지 선택, 품질 옵션 및 메타데이터 제어에 대한 내용이 포함되어 있습니다.

패들샤프 OCR API와IronOCR매핑 참조

패들샤프 OCR IronOCR
Sdcb.PaddleOCR (namespace) IronOcr (namespace)
Sdcb.PaddleInference (namespace) 필요 없음 — 자동 구성됨
PaddleOcrAll IronTesseract
new PaddleOcrAll(det, cls, rec) new IronTesseract()
LocalFullModels.ChineseV3.DetectionModel 동등한 모델 없음 - 모델 선택 불가
LocalFullModels.ChineseV3.ClassifierModel 동등한 모델 없음 - 모델 선택 불가
LocalFullModels.ChineseV3.RecognitionModel 동등한 모델 없음 - 모델 선택 불가
PaddleConfig.FromModelDir() 동등한 객체 없음 — 구성 객체 없음
config.EnableGpu(memMB, deviceId) 동등한 개념이 없습니다. 백엔드는 자동화되어 있습니다.
config.EnableMkldnn() 동등한 개념이 없습니다. 백엔드는 자동화되어 있습니다.
config.SetCpuMathLibraryNumThreads(n) 동등한 기능 없음 - 내부적으로 관리됨
Cv2.ImRead(path) (OpenCV load) input.LoadImage(path)
ocr.Run(mat) ocr.Read(input) 또는 ocr.Read("file.jpg")
result.Regions result.Pages[0].Words 또는 result.Pages[0].Lines
region.Text word.Text, line.Text, paragraph.Text
region.Rect.Center.X/.Y word.X, word.Y
region.Score (confidence) word.Confidence, result.Confidence
모델 수준 언어 교환 ocr.Language = OcrLanguage.French
표 형식 모델 (별도 다운로드) 내장된 구조화된 결과 계층 구조
Cv2.CvtColor(..., GRAY) input.Binarize() 또는 input.Contrast()
Cv2.GaussianBlur(...) input.DeNoise()
검색 가능한 PDF 출력 없음 result.SaveAsSearchablePdf("output.pdf")

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

문제 1: OpenCV 종속성 언로드 실패

PaddleSharp OCR: OpenCvSharp4.runtime.win 및 유사한 플랫폼별 런타임 패키지는 네이티브 DLL을 설치합니다. 이러한 DLL은 일부 호스팅 환경, 특히 IIS 앱 풀 재활용 시 적절한 정리 작업을 방해할 수 있으며, 빌드 시 잘못된 플랫폼 런타임 패키지가 참조될 경우 어셈블리 로드 오류를 발생시킬 수 있습니다. 이러한 DLL을 제거하려면 NuGet 패키지를 제거하고 출력 디렉터리에 캐시된 네이티브 바이너리를 모두 삭제해야 합니다.

해결책: OpenCvSharp4OpenCvSharp4.runtime.* 패키지를 제거한 후, 재구축 전에 빌드 출력 디렉터리를 정리하십시오:

dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet clean
dotnet build
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet clean
dotnet build
SHELL

IronOCR 자체적인 종속성을 내부적으로 번들링하고 관리되지 않는 수명 주기를 처리합니다. 플랫폼별 런타임 패키지를 선택할 필요가 없습니다. IronTesseract 설정 가이드에는IronOCR자동으로 처리하는 플랫폼 요구 사항이 설명되어 있습니다.

문제 2: 마이그레이션 후 디스크에 남아 있는 모델 파일

PaddleSharp OCR: PaddleSharp가 다운로드한 모델 파일(탐지, 분류, 인식 및 테이블 모델)은 일반적으로 애플리케이션과 상대적인 models/ 디렉터리에 저장됩니다. 이 파일들은 NuGet 패키지를 제거해도 삭제되지 않습니다. Docker 이미지에서 불필요한 레이어 크기를 추가합니다. 배포 파이프라인에서 이전 경로에 있는 오래된 모델 파일은 남아 있는 초기화 코드가 이를 참조하는 경우 시작 오류를 일으킬 수 있습니다.

해결 방법: 마이그레이션 과정에서 모델 디렉터리를 명시적으로 제거합니다. 시작 구성에서 경로 참조가 있는지 검토하십시오.

# Locate model directory references in application code
grep -r "LocalFullModels\|ModelPath\|models/" --include="*.cs" .
grep -r "DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
# Locate model directory references in application code
grep -r "LocalFullModels\|ModelPath\|models/" --include="*.cs" .
grep -r "DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
SHELL

모델 참조를 제거하고IronOCR초기화한 후에는 저장소와 Docker 빌드 컨텍스트에서 모델 디렉터리를 삭제하십시오.

문제 3: 마이그레이션 후 단일 개체 수명 가정이 깨짐

PaddleSharp OCR: PaddleOcrAll는 그 생성 비용으로 인해 요청당 인스턴스화가 비현실적이어서 싱글톤으로 등록되었습니다.IronOCR동일한 싱글턴 등록으로 마이그레이션하는 코드는 요청 간에 불필요한 상태 공유를 도입합니다. IronTesseract은(는) 동시에 사용될 때 스레드 안전하지만, 단일 인스턴스를 공유할 필요는 없습니다 — 각 인스턴스는 독립적입니다.

해결책: 싱글턴 등록이 성능 향상 외에 다른 목적을 가지고 있는지 평가합니다. 대부분의 ASP.NET Core 애플리케이션의 경우IronOCR사용할 때 임시 등록이 더 깔끔한 선택입니다.

// PaddleSharp — forced singleton due to construction cost
services.AddSingleton<PaddleOcrAll>(sp =>
{
    var det = LocalFullModels.ChineseV3.DetectionModel;  // Simplified
    var cls = LocalFullModels.ChineseV3.ClassifierModel; // Simplified
    var rec = LocalFullModels.ChineseV3.RecognitionModel; // Simplified
    return new PaddleOcrAll(det, cls, rec);
});

//IronOCR— transient works; no expensive construction
services.AddTransient<IronTesseract>();
// PaddleSharp — forced singleton due to construction cost
services.AddSingleton<PaddleOcrAll>(sp =>
{
    var det = LocalFullModels.ChineseV3.DetectionModel;  // Simplified
    var cls = LocalFullModels.ChineseV3.ClassifierModel; // Simplified
    var rec = LocalFullModels.ChineseV3.RecognitionModel; // Simplified
    return new PaddleOcrAll(det, cls, rec);
});

//IronOCR— transient works; no expensive construction
services.AddTransient<IronTesseract>();
Imports Microsoft.Extensions.DependencyInjection

' PaddleSharp — forced singleton due to construction cost
services.AddSingleton(Of PaddleOcrAll)(Function(sp)
    Dim det = LocalFullModels.ChineseV3.DetectionModel ' Simplified
    Dim cls = LocalFullModels.ChineseV3.ClassifierModel ' Simplified
    Dim rec = LocalFullModels.ChineseV3.RecognitionModel ' Simplified
    Return New PaddleOcrAll(det, cls, rec)
End Function)

' IronOCR— transient works; no expensive construction
services.AddTransient(Of IronTesseract)()
$vbLabelText   $csharpLabel

명시적인 인스턴스 재사용이 필요한 고처리량 배치 시나리오에서는 싱글톤 또는 풀링 패턴이 여전히 효과적이지만, 이는 성능상의 선택이지 정확성 요구 사항은 아닙니다.

문제 4: 결과 영역 순서 지정이 더 이상 필요하지 않음

PaddleSharp OCR: result.Regions는 탐지 순서대로 감지된 텍스트 영역을 반환하며, 이는 좌에서 우, 상에서 하로의 독해 순서와 반드시 일치하지는 않습니다. 팀은 일반적으로 .Rect.Center.Y 뒤에 .Rect.Center.X으로 정렬한 후 영역 텍스트를 결합하는 데 사용합니다 — 이는 거의 모든 PaddleSharp 텍스트 추출 구현에 나타나는 패턴입니다. 이 패턴을IronOCR에 그대로 옮기면 중복 코드가 생성됩니다.

해결 방법:IronOCR기본적으로 읽기 순서대로 결과를 반환합니다. 정렬을 제거하세요:

// PaddleSharp — manual reading-order sort required
var text = string.Join("\n", result.Regions
    .OrderBy(r => r.Rect.Center.Y)
    .ThenBy(r => r.Rect.Center.X)
    .Select(r => r.Text));

//IronOCR— result.Text is already in reading order; no sort needed
var text = result.Text;

// For word-level access with position, use the structured hierarchy directly
foreach (var word in result.Pages[0].Words)
{
    Console.WriteLine($"{word.Text} at ({word.X},{word.Y})");
}
// PaddleSharp — manual reading-order sort required
var text = string.Join("\n", result.Regions
    .OrderBy(r => r.Rect.Center.Y)
    .ThenBy(r => r.Rect.Center.X)
    .Select(r => r.Text));

//IronOCR— result.Text is already in reading order; no sort needed
var text = result.Text;

// For word-level access with position, use the structured hierarchy directly
foreach (var word in result.Pages[0].Words)
{
    Console.WriteLine($"{word.Text} at ({word.X},{word.Y})");
}
Imports System
Imports System.Linq

' PaddleSharp — manual reading-order sort required
Dim text = String.Join(vbLf, result.Regions _
    .OrderBy(Function(r) r.Rect.Center.Y) _
    .ThenBy(Function(r) r.Rect.Center.X) _
    .Select(Function(r) r.Text))

' IronOCR— result.Text is already in reading order; no sort needed
text = result.Text

' For word-level access with position, use the structured hierarchy directly
For Each word In result.Pages(0).Words
    Console.WriteLine($"{word.Text} at ({word.X},{word.Y})")
Next
$vbLabelText   $csharpLabel

문제 5: 백엔드 조건부 패키지로 인해 복원 기능이 작동하지 않음

PaddleSharp OCR: 일부 PaddleSharp 설정은 대상 환경(CUDA는 GPU, MKL은 OpenVINO, CPU 전용)에 따라 다른 Sdcb.PaddleInference.runtime.* 패키지를 조건부로 참조합니다. 이는 때로 .csproj 조건으로 나타나거나 배포 대상별 개별 프로젝트 파일로 나타납니다. 결과적으로 생성되는 빌드 매트릭스는 잘못된 패키지 세트가 복원될 때 CI 파이프라인을 중단시킵니다.

해결책: PaddleSharp 패키지를 제거한 후, .csproj 파일을 감사하여 PackageReference 블록에서 Sdcb.* 또는 OpenCvSharp* 패키지를 참조하는 조건부 블록을 완전히 제거합니다:

grep -n "Sdcb\|OpenCvSharp\|PaddleInference" *.csproj
grep -n "Sdcb\|OpenCvSharp\|PaddleInference" *.csproj
SHELL

IronOCR은 플랫폼 조건이 없는 단일 IronOcr 패키지 참조를 사용합니다. 동일한 패키지가 Windows, Linux 및 macOS에서 올바르게 복원됩니다.

문제 6: 테이블 결과 구조에는 직접적인 대응물이 없습니다.

PaddleSharp OCR: PaddleOcrTable는 인식된 각 셀에 대한 행 및 열 인덱스를 가진 셀 기반 구조를 반환합니다. 이 구조를 사용하는 코드는 일반적으로 (row, column)로 인덱스된 2차원 배열을 만듭니다.IronOCR동일한 셀 인덱스 구조를 제공하지 않습니다. 대신 단어 및 줄 좌표를 제공하며, 이를 공간적으로 그룹화하여 셀 그리드를 재구성해야 합니다.

해결 방법:IronOCR단어 좌표를 사용하여 행은 Y축 위치를 기준으로 그룹화하고 열은 X축 위치를 기준으로 정렬하여 테이블 구조를 재구성합니다. 일반적인 표 형식의 경우, 표 읽기 방법 안내에서는 공간적 그룹화 방식을 제공합니다. 알려진 필드 위치가 있는 구조화된 송장용으로는 지역 기반 OCRCropRectangle와 함께 전체 페이지 테이블 추출보다 깔끔한 패턴입니다.

using IronOcr;

// Target specific table cells by region instead of full-page table detection
var totalAmountRegion = new CropRectangle(400, 600, 200, 30); // x, y, width, height
using var input = new OcrInput();
input.LoadImage("invoice.jpg", totalAmountRegion);

var result = new IronTesseract().Read(input);
Console.WriteLine($"Total: {result.Text}");
using IronOcr;

// Target specific table cells by region instead of full-page table detection
var totalAmountRegion = new CropRectangle(400, 600, 200, 30); // x, y, width, height
using var input = new OcrInput();
input.LoadImage("invoice.jpg", totalAmountRegion);

var result = new IronTesseract().Read(input);
Console.WriteLine($"Total: {result.Text}");
Imports IronOcr

' Target specific table cells by region instead of full-page table detection
Dim totalAmountRegion As New CropRectangle(400, 600, 200, 30) ' x, y, width, height
Using input As New OcrInput()
    input.LoadImage("invoice.jpg", totalAmountRegion)

    Dim result = New IronTesseract().Read(input)
    Console.WriteLine($"Total: {result.Text}")
End Using
$vbLabelText   $csharpLabel

패들샤프 OCR 마이그레이션 체크리스트

사전 마이그레이션

패키지를 제거하기 전에 코드베이스에 있는 모든 PaddleSharp 참조를 검토하십시오.

# Find all PaddleSharp and PaddleInference usages
grep -rn "Sdcb\.PaddleOCR\|Sdcb\.PaddleInference" --include="*.cs" .

# Find OpenCV usages that will need replacement
grep -rn "OpenCvSharp\|Cv2\.\|using var.*Mat\b" --include="*.cs" .

# Find model path references and configuration
grep -rn "LocalFullModels\|ModelDir\|DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .

# Find backend selection logic
grep -rn "EnableGpu\|EnableMkldnn\|PaddleConfig\|SetCpuMath" --include="*.cs" .

# Find table recognition usages
grep -rn "PaddleOcrTable\|TableModel\|table.*ocr\|ocr.*table" --include="*.cs" .

# Find result region access patterns that need updating
grep -rn "\.Regions\b\|Rect\.Center\|region\.Text" --include="*.cs" .
# Find all PaddleSharp and PaddleInference usages
grep -rn "Sdcb\.PaddleOCR\|Sdcb\.PaddleInference" --include="*.cs" .

# Find OpenCV usages that will need replacement
grep -rn "OpenCvSharp\|Cv2\.\|using var.*Mat\b" --include="*.cs" .

# Find model path references and configuration
grep -rn "LocalFullModels\|ModelDir\|DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .

# Find backend selection logic
grep -rn "EnableGpu\|EnableMkldnn\|PaddleConfig\|SetCpuMath" --include="*.cs" .

# Find table recognition usages
grep -rn "PaddleOcrTable\|TableModel\|table.*ocr\|ocr.*table" --include="*.cs" .

# Find result region access patterns that need updating
grep -rn "\.Regions\b\|Rect\.Center\|region\.Text" --include="*.cs" .
SHELL

디스크에 있는 모델 파일들을 목록화하고 경로를 기록해 두세요. 모든 배포 대상을 나열하고 .csproj에서 GPU 또는 OpenVINO 특정 NuGet 조건부가 있는지 확인하십시오. PaddleSharp 구축 비용으로 인해 서비스가 싱글턴으로 등록될 수 있음을 유의하십시오.

코드 마이그레이션

  1. 모든 Sdcb.PaddleOCR, Sdcb.PaddleInference, OpenCvSharp4OpenCvSharp4.runtime.* NuGet 패키지를 모든 프로젝트 파일에서 제거합니다.
  2. IronOcr NuGet 패키지를 설치합니다.
  3. 필요한 언어에 대한 언어 NuGet 패키지를 설치합니다 (예: IronOcr.Languages.ChineseSimplified).
  4. 애플리케이션 시작에 IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";을 추가합니다.
  5. 모든 using Sdcb.PaddleOCR, using Sdcb.PaddleInference, 및 using OpenCvSharp 문을 using IronOcr으로 교체합니다.
  6. PaddleOcrAll 인스턴스화 및 모델 로딩을 new IronTesseract()으로 교체합니다.
  7. 모든 PaddleConfig 백엔드 선택 블록을 삭제합니다 (CPU, GPU, OpenVINO 조건부).
  8. Cv2.ImRead(path) 호출을 input.LoadImage(path)으로 교체하고 OcrInput을 사용합니다.
  9. OpenCV 전처리 작업 (CvtColor, GaussianBlur, Threshold 등)을 OcrInput 필터 방법 (Deskew(), DeNoise(), Contrast(), Binarize())으로 교체합니다.
  10. 모든 ocr.Run(mat) 호출을 ocr.Read(input)으로 교체합니다.
  11. result.Regions 열거를 result.Pages, result.Pages[n].Lines, 또는 result.Pages[n].Words으로 교체합니다.
  12. .OrderBy(r => r.Rect.Center.Y).ThenBy(r => r.Rect.Center.X) 정렬 체인을 제거합니다 — 독해 순서는 자동입니다.
  13. PaddleOcrTable 초기화 및 결과 파싱을 OcrInput 지역 기반 타겟팅 또는 좌표 기반 단어 그룹화로 교체합니다.
  14. 검색 가능한 PDF 아카이브가 필요한 어디든지 result.SaveAsSearchablePdf(path)를 추가합니다.
  15. 서비스 수명 등록을 재평가하십시오. PaddleSharp 구축 비용으로 인해 발생하는 단일 등록은 일반적으로 일시적이거나 범위가 제한될 수 있습니다.
  16. 디스크에서 모델 파일을 삭제하고 Docker 빌드 컨텍스트에서 모델 디렉터리를 제거합니다.
  17. 플랫폼 특정 Paddle 또는 OpenCV 런타임 패키지에 대한 모든 .csproj 조건부 PackageReference 블록을 제거합니다.

마이그레이션 이후

  • 파이프라인에 있는 각 문서 유형별로 20~30개의 대표 샘플을 사용하여 텍스트 추출 결과가 PaddleSharp의 출력과 일치하거나 그 이상인지 확인합니다.
  • 애플리케이션 시작 로그에 OpenCvSharp관련 어셈블리 로드 예외가 없음을 확인합니다.
  • 동일한 빌드 아티팩트를 사용하여 각 대상 플랫폼(Windows, Linux, Docker)에서 배포 테스트를 수행합니다. 플랫폼별 패키지 선택은 필요하지 않아야 합니다.
  • 수동 결과 정렬이 필요했던 문서가 result.Text로 올바른 순서의 텍스트를 생성하는지 검증합니다.
  • 검색 가능한 PDF 출력 파일이 Adobe Acrobat Reader 또는 사용자가 선택한 PDF 뷰어에서 텍스트 검색이 가능한지 확인하십시오.
  • 애플리케이션을 부하 상태로 실행하여 IronTesseract 인스턴스가 요청당 생성되지 않아 요청당 PaddleOcrAll 생성과 관련된 메모리 압박을 유발하지 않는지 확인합니다.
  • NuGet 패키지로 설치된 언어 팩이 추가 파일 배포 단계 없이 CI에서 올바르게 복원되는지 확인합니다.
  • 영역 기반 또는 좌표 그룹화 방식을 사용하여 예상되는 행/열 구조에 대해 모든 테이블 추출 시나리오를 테스트합니다.
  • 시작 경로에서 PaddleOcrAll 싱글톤 생성을 제거한 후 애플리케이션 시작 시간이 감소했는지 확인합니다.

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

하나의 패키지가 네 개의 패키지 스택을 대체합니다. 마이그레이션 후, OCR 의존성 영역은 단일 IronOcr NuGet 참조입니다. 네 개의 패키지 스택 — Sdcb.PaddleOCR, Sdcb.PaddleInference, OpenCvSharp4 및 플랫폼 특정 런타임 —은 프로젝트 파일에 한 항목으로 변합니다. 의존성 감사, 라이선스 스캔 및 취약성 모니터링은 이제 네 개 대신 한 표면을 덮고 있습니다.

배포 아티팩트는 모든 환경에서 동일합니다. CPU, GPU 또는 OpenVINO와 같은 백엔드 선택 조건은 더 이상 필요하지 않습니다. 동일한 빌드 아티팩트가 환경별 패키지 선택이나 초기화 분기 없이 개발자 노트북, CI 실행기, Linux 컨테이너 및 클라우드 VM에 배포됩니다. Docker 이미지는 모델 파일을 COPY할 필요가 없고 플랫폼 런타임 패키지를 설치할 필요가 없어 축소됩니다.

문서 아카이브 파이프라인은 더 이상 두 번째 라이브러리를 필요로 하지 않습니다. result.SaveAsSearchablePdf()는 대부분의 PaddleSharp 팀이 검색 가능한 아카이브를 만들기 위해 추가했던 PDF 라이브러리 의존성을 제거합니다. OCR 처리와 검색 가능한 PDF 생성은 단일 API 호출로 이루어집니다. 하루에 수천 건의 스캔 문서를 처리하는 팀의 경우, 이러한 간소화로 인해 라이브러리 간 버전 충돌 문제가 완전히 해결됩니다. 검색 가능한 PDF 관련 블로그 게시물은 대규모 생산 시 고려 사항을 다룹니다.

서비스 수명 결정은 라이브러리 제약이 아닌 애플리케이션 요구사항을 반영합니다. IronTesseract은(는) 경량의 생성 방식을 가지고 있습니다. PaddleSharp의 고비용 모델 로딩으로 인해 발생하는 강제 단일 패턴은 더 이상 필요하지 않습니다. ASP.NET Core 에서는 서비스 범위를 요청별로 지정할 수 있으므로 동시 사용자 간의 격리가 더욱 명확해지고 공유 상태 스레딩 관련 문제가 해결됩니다. 배포 옵션에 대한 자세한 내용은 ASP.NET OCR 사용 사례 페이지를 참조하세요.

언어 확장은 Install-Package일 뿐, 연구 프로젝트가 아닙니다. 125개 이상의 언어 카탈로그는 유럽, 아시아, 중동 및 특수 문자를 NuGet 패키지로 제공합니다. 중국어로만 시작된 파이프라인에 프랑스어, 독일어, 아랍어 또는 일본어를 추가하는 것은 dotnet add package IronOcr.Languages.French이며 한 줄의 구성으로 가능합니다. 모델 파일 소싱, 업스트림 가용성 조사, 수동 파일 배포 등의 과정이 필요하지 않습니다.

전처리는 OCR API의 일부입니다. PaddleSharp 전처리가 요구했던 OpenCV 지식 — 필터 커널 이해, Mat 처리, 적응형 임계값 매개변수 선택 —은 이제 OCR 작업에 대한 전제조건이 아닙니다. OcrInput은 합리적인 기본값으로 명명된 작업을 제공합니다. OpenCV 전문가가 아니었지만 OpenCV 전처리 코드를 유지 관리하던 팀은 해당 코드를 교체하지 않고 삭제할 수 있습니다. 전처리 기능 페이지 에는 사용 가능한 모든 필터 목록과 각 필터를 적용해야 하는 시점에 대한 설명이 나와 있습니다.

참고해 주세요Adobe Acrobat, PaddleOCR, Tesseract는 해당 소유자의 등록 상표입니다. 이 사이트는 Adobe Inc., Baidu, Google, PaddlePaddle의 승인을 받거나 후원받는 것이 아닙니다. 모든 제품명, 로고 및 브랜드는 해당 소유자의 자산입니다. 비교는 정보 제공 목적으로만 사용되며, 작성 시점에 공개적으로 이용 가능한 정보를 반영합니다.

자주 묻는 질문

PaddleSharp OCR에서 IronOCR로 마이그레이션해야 하는 이유는 무엇인가요?

일반적인 동인으로는 COM 상호 운용의 복잡성 제거, 파일 기반 라이선스 관리 대체, 페이지당 과금 방지, Docker/컨테이너 배포 활성화, 표준 .NET 툴링과 통합되는 NuGet 네이티브 워크플로 채택 등이 있습니다.

PaddleSharp OCR에서 IronOCR로 마이그레이션할 때 주요 코드 변경 사항은 무엇인가요?

PaddleSharp 초기화 시퀀스를 IronTesseract 인스턴스화로 대체하고, COM 수명 주기 관리(명시적 생성/로드/폐쇄 패턴)를 제거하고, 결과 속성 이름을 업데이트합니다. 그 결과 상용구 줄이 현저히 줄어듭니다.

마이그레이션을 시작하려면 IronOCR을 어떻게 설치하나요?

패키지 관리자 콘솔에서 '설치-패키지 IronOcr'을 실행하거나 CLI에서 '닷넷 추가 패키지 IronOcr'을 실행하세요. 언어 팩은 별도의 패키지입니다: 예를 들어 프랑스어의 경우 '닷넷 추가 패키지 IronOcr.Languages.French'를 실행합니다.

IronOCR은 표준 비즈니스 문서에 대해 PaddleSharp OCR의 OCR 정확도와 일치하나요?

IronOCR은 송장, 계약서, 영수증, 타이핑된 양식 등 표준 비즈니스 콘텐츠에 대해 높은 정확도를 달성합니다. 이미지 전처리 필터(데스큐, 노이즈 제거, 대비 향상)는 품질이 저하된 입력에 대한 인식률을 더욱 향상시킵니다.

IronOCR은 별도로 설치하는 언어 데이터를 어떻게 처리하나요?

IronOCR의 언어 데이터는 NuGet 패키지로 배포됩니다. '닷넷 추가 패키지 IronOcr.Languages.German'은 독일어 지원을 설치합니다. 수동 파일 배치나 디렉터리 경로는 필요하지 않습니다.

PaddleSharp OCR에서 IronOCR로 마이그레이션하려면 배포 인프라를 변경해야 하나요?

IronOCR은 패들샤프 OCR보다 인프라 변경이 더 적게 필요합니다. SDK 바이너리 경로, 라이선스 파일 배치 또는 라이선스 서버 구성이 필요하지 않습니다. NuGet 패키지에는 완전한 OCR 엔진이 포함되어 있으며 라이선스 키는 애플리케이션 코드에 설정된 문자열입니다.

마이그레이션 후 IronOCR 라이선싱은 어떻게 구성하나요?

애플리케이션 시작 코드에 IronOcr.License.LicenseKey = "YOUR-KEY"를 할당하세요. Docker 또는 Kubernetes에서 키를 환경 변수로 저장하고 시작 시 키를 읽습니다. 트래픽을 수락하기 전에 License.IsValidLicense를 사용하여 유효성을 검사하세요.

IronOCR은 PaddleSharp와 동일한 방식으로 PDF를 처리할 수 있나요?

예. IronOCR은 원본 및 스캔한 PDF를 모두 읽습니다. IronTesseract를 인스턴스화하고, 입력이 PDF 경로 또는 OcrPdfInput인 경우 ocr.Read(input)를 호출하고, OcrResult 페이지를 반복하면 됩니다. 별도의 PDF 렌더링 파이프라인이 필요하지 않습니다.

IronOCR은 대량 처리에서 스레딩을 어떻게 처리하나요?

IronTesseract는 스레드별로 인스턴스화해도 안전합니다. Parallel.ForEach 또는 Task 풀에서 스레드당 하나의 인스턴스를 스핀업하고, OCR을 동시에 실행하고, 완료되면 각 인스턴스를 폐기하면 됩니다. 전역 상태나 잠금이 필요하지 않습니다.

IronOCR은 텍스트 추출 후 어떤 출력 형식을 지원하나요?

IronOCR은 텍스트, 단어 좌표, 신뢰도 점수, 페이지 구조를 포함한 구조화된 결과를 반환합니다. 내보내기 옵션에는 일반 텍스트, 검색 가능한 PDF, 다운스트림 처리를 위한 구조화된 결과 개체가 포함됩니다.

워크로드 확장을 위해 IronOCR 가격이 PaddleSharp OCR보다 더 예측 가능한가요?

IronOCR은 페이지당 또는 볼륨당 요금이 없는 정액제 영구 라이선스를 사용합니다. 10,000페이지를 처리하든 1,000만 페이지를 처리하든 라이선스 비용은 일정하게 유지됩니다. 볼륨 및 팀 라이선스 옵션은 IronOCR 가격 페이지에서 확인할 수 있습니다.

PaddleSharp OCR에서 IronOCR로 마이그레이션한 후 기존 테스트는 어떻게 되나요?

추출된 텍스트 콘텐츠에 대해 어설트하는 테스트는 마이그레이션 후에도 계속 통과해야 합니다. API 호출 패턴 또는 COM 개체 수명 주기의 유효성을 검사하는 테스트는 IronOCR의 더 간단한 초기화 및 결과 모델을 반영하도록 업데이트해야 합니다.

칸나오팟 우돈판트
소프트웨어 엔지니어
카나팟은 소프트웨어 엔지니어가 되기 전 일본 홋카이도 대학교에서 환경 자원학 박사 학위를 취득했습니다. 학위 과정 중에는 생물생산공학과 소속 차량 로봇 연구실에서 활동하기도 했습니다. 2022년에는 C# 기술을 활용하여 Iron Software의 엔지니어링 팀에 합류했고, 현재 IronPDF 개발에 집중하고 있습니다. 카나팟은 IronPDF에 사용되는 대부분의 코드를 직접 작성하는 개발자로부터 배울 수 있다는 점에 만족하며, 동료들과의 소통을 통해 배우는 것 외에도 Iron Software에서 일하는 즐거움을 누리고 있습니다. 코딩이나 문서 작업을 하지 않을 때는 주로 PS5로 게임을 하거나 The Last of Us를 다시 시청하는 것을 즐깁니다.

아이언 서포트 팀

저희는 주 5일, 24시간 온라인으로 운영합니다.
채팅
이메일
전화해