IRONSOFTWAREHOME
동영상

OCR 도구를 사용하여 이미지에서 아랍어 텍스트를 추출하는 방법

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

이 가이드는 .NET 개발자가 GdPicture .NET OCR에서 IronOCR 로 완전히 마이그레이션하는 과정을 안내합니다. 이 문서에서는 모든 주요 OCR 워크플로에 대한 패키지 교체, 네임스페이스 변경 및 실질적인 전후 코드 패턴을 다루며, 특히 GdPicture의 리소스 관리 모델을 정의하는 정수 이미지 ID 수명 주기를 제거하는 데 중점을 둡니다. 비교 기사를 미리 읽을 필요는 없습니다.

GdPicture .NET 에서 마이그레이션해야 하는 이유는 무엇일까요?

GdPicture .NET 은 스캐너 통합, DICOM 지원, PDF 편집, 주석 달기 및 OCR 기능을 단일 공급업체에서 제공받아야 하는 팀을 위해 구축된 문서 이미지 처리 플랫폼입니다. OCR이 유일한 요구 사항일 경우, 플랫폼의 가격 책정 방식과 API 아키텍처는 시간이 지남에 따라 누적되는 마찰을 야기합니다.

기본 OCR 워크플로우용 플러그인 비용. 스캔한 PDF에서 텍스트를 추출하고 검색 가능한 결과물을 생성하려면 세 가지 라이선스 구성 요소가 필요합니다. 코어 SDK는 약 4,000달러, OCR 플러그인은 약 2,000달러, PDF 플러그인은 약 2,000달러입니다. 따라서 초기 비용은 8,000달러이며, 여기에 연간 유지 보수 비용 20%가 Plus . OCR 기능만 필요한 팀은 문서 이미지 처리 플랫폼의 전체 가격 구조를 그대로 감수해야 합니다. IronOCR는 이미지 OCR, PDF OCR, 전처리, 검색 가능한 PDF 출력과 같은 동일한 작업 흐름을 가격에 상관없이 전체 패키지에서 지원하며, $2,399 영구 라이선스로, 기능별 라이선스 결정이 필요 없습니다. 자세한 등급별 내용은 IronOCR 라이선스 페이지를 참조하십시오.

정수 이미지 ID 수명 주기. GdPicture을 통해 로드된 모든 이미지는 int을 반환합니다. 해당 정수를 OCR 작업에 전달하고 완료되면 ReleaseGdPictureImage을 호출합니다. 이 패턴은 IDisposable 이전에 존재했습니다. 제대로 따르면 효과가 있습니다. 누락될 경우 메모리 누수가 발생합니다. 매일 수백 건의 문서를 처리하는 운영 서비스에서 오류 분기에 대한 릴리스 호출이 한 번이라도 누락되면 진단하기 매우 어려운 메모리 사용량 증가가 발생합니다. IronOCR의 OcrInputIDisposable을 구현합니다. 따라서 using 문은 전체 정리 작업을 없애줍니다.

버전 특정 네임스페이스. GdPicture는 네임스페이스에 주요 버전 번호를 포함합니다: using GdPicture14. 다음 주요 릴리스로 업그레이드하기 위해서는 GdPicture 클래스를 참조하는 모든 소스 파일에서 해당 using 지침을 업데이트해야 합니다. 수십 개의 서비스에 걸쳐 OCR 기능이 분산된 대규모 애플리케이션의 경우, 찾기 및 바꾸기 작업은 몇 시간씩 소요되며 기능적인 개선도 가져오지 못합니다. IronOCR의 네임스페이스는 모든 주요 버전에서 IronOcr되었습니다.

외부 리소스 폴더 요구 사항. GdPicture OCR은 런타임에 ResourceFolder 언어 파일이 들어 있는 디렉터리를 가리키는 속성이 필요합니다. 이 경로는 개발 머신에서 작동하지만 디렉터리 구조가 존재하지 않는 Linux 서버, Docker 컨테이너, Azure App Service 배포 환경에서는 작동하지 않습니다. IronOCR은 NuGet 패키지에 영어 언어 지원을 번들 포함합니다; 추가 언어는 빌드 출력과 함께 제공되는 NuGet 패키지로 설치됩니다.

3-컴포넌트 초기화. GdPicture의 PDF OCR 워크플로는 GdPictureImaging, GdPictureOCR, GdPicturePDF - 개별적인 정리 요구 사항을 가진 세 가지 컴포넌트의 인스턴스 화가 필요하며 라이선스 매니저 등록 및 리소스 폴더 할당을 포함해야 합니다.IronOCR시작 시 한 줄의 코드와 호출 시 하나의 클래스가 필요합니다.

GdPicture OCR 인스턴스는 스레드 안전성을 기본적으로 지원하지 않습니다. 병렬 문서 처리를 위해서는 상태 손상을 방지하기 위해 신중한 인스턴스 관리 및 동기화가 필요합니다. IronOCR는 동시 사용을 위해 설계되었습니다: 스레드 당 하나의 IronTesseract을 생성하거나 로드 상태에서 단일 인스턴스를 공유 - 어떤 패턴이든 추가 동기화 코드 없이 작동합니다.

근본적인 문제

GdPicture는 각 이미지에 대해 런타임 관리 정수 핸들로 메모리를 할당합니다. TIFF 처리 루프의 모든 RenderPageToGdPictureImage 호출은 수동으로 해제해야 하는 새 할당을 생성합니다:

// GdPicture: every frame = new integer ID = manual release required
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("multi-page.tiff", false);

var frameIds = new List<int>();
try
{
    for (int i = 1; i <= pdf.GetPageCount(); i++)
    {
        pdf.SelectPage(i);
        int frameId = pdf.RenderPageToGdPictureImage(200, false); // new allocation
        if (frameId != 0) frameIds.Add(frameId);
        // ... OCR call here ...
    }
}
finally
{
    foreach (var id in frameIds) _imaging.ReleaseGdPictureImage(id); // manual per-frame release
}
C#

IronOCR 생명주기를 완전히 제거합니다. OcrInput는 프레임 열거 및 정리를 처리합니다:

// IronOCR: the using statement handles everything
using var input = new OcrInput();
input.LoadImageFrames("multi-page.tiff");
var result = new IronTesseract().Read(input);
C#

##IronOCR과 GdPicture .NET: 기능 비교

아래 표는 OCR 중심 워크플로우를 위한 두 라이브러리 간의 기능 적용 범위를 보여줍니다.

기능GdPicture.NETIronOCR
설치여러 개의 NuGet 패키지dotnet add package IronOcr
라이선스 활성화LicenseManager.RegisterKEY()IronOcr.License.LicenseKey = "..."
주요 업그레이드 시 네임스페이스찾기 및 대체 필요 (GdPicture14 → 다음)변경되지 않음 (IronOcr)
컴포넌트 초기화GdPictureImaging + GdPictureOCR + GdPicturePDFnew IronTesseract()
리소스 메모리 모델수동 정수 ID 추적 및 릴리스IDisposable / using 명령문
메모리 누수 위험높음 (누락된 ReleaseGdPictureImage)없음 (컴파일러 강제 사항 using)
외부 리소스 폴더필수 (_ocr.ResourceFolder = path)필수 사항이 아닙니다. 패키지에 포함되어 있습니다.
이미지 OCR
PDF OCR예 (PDF 플러그인 필요)내장형, 추가 라이선스 필요 없음
여러 페이지로 구성된 TIFF 파일수동 프레임 루프 + 프레임별 ID 정리input.LoadImageFrames()
스트림 입력GdPictureImaging 스트림 오버로드를 통해input.LoadImage(stream)
검색 가능한 PDF 출력pdf.OcrPage() + pdf.SaveToFile()result.SaveAsSearchablePdf()
디스큐 전처리문서 이미지 플러그인이 필요합니다.input.Deskew() – 내장
소음 제거문서 이미지 플러그인이 필요합니다.input.DeNoise() – 내장
언어폴더에 있는 Tesseract 기반 학습 데이터 파일NuGet 패키지를 통해 125개 이상
다국어 OCROcrLanguage.French + OcrLanguage.German
스레드 안전성수동 인스턴스 관리설계상 스레드 안전
비동기 OCR내장되어 있지 않음ReadAsync()
바코드 판독별도의 바코드 플러그인ocr.Configuration.ReadBarCodes = true
구조화된 출력인덱스 기반 블록/줄/단어 접근타입 .Pages, .Words, .Characters
자신감 점수GetOCRResultConfidence(resultId)result.Confidence
크로스 플랫폼윈도우, 리눅스, macOS윈도우, 리눅스, macOS, Docker, AWS, Azure
진입 비용(PDF에서 OCR 처리)약 8,000달러 (코어 + OCR + PDF 플러그인 포함)$999–$2,399
가격 모델플러그인 기반 영구 라이선스 + 연간 20% 유지보수 비용고정형 영구채, 연간 업데이트는 선택 사항입니다.
상업적 지원

빠른 시작: GdPicture .NET 에서IronOCR로 마이그레이션

1단계: NuGet 패키지 교체

GdPicture 패키지를 제거하세요:

dotnet remove package GdPicture.NET
dotnet remove package GdPicture.NET.OCR
dotnet remove package GdPicture.NET.PDF
SHELL

NuGet 패키지 페이지 에서IronOCR설치하세요.

dotnet add package IronOcr

영어 이외의 언어를 사용하려면 해당 언어 팩을 설치하세요.

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

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

GdPicture 네임스페이스를IronOCR네임스페이스로 바꾸십시오.

// Before (GdPicture)
using GdPicture14;

// After (IronOCR)
using IronOcr;
C#

단계 3: 라이선스 초기화

이 줄을 Program.cs 또는 Startup.cs의 OCR 호출 전에 배치하십시오:

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

GdPicture 라이선스 등록 차단을 완전히 제거하십시오.

// Remove this
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
C#

구매 전 평가를 위해 IronOCR 제품 페이지 에서 무료 평가판 키를 다운로드할 수 있습니다.

코드 마이그레이션 예제

다중 페이지 TIFF 프레임 처리

GdPicture에서 여러 페이지로 구성된 TIFF 파일을 처리하려면 PDF/이미징 API를 통해 각 프레임을 선택하고, 새 이미지 ID로 렌더링하고, OCR을 실행한 다음 해당 ID를 해제해야 합니다. finally 블록에서 해제되지 않은 단일 프레임은 DPI에 따라 10-50MB를 누출합니다.

GdPicture .NET 접근 방식:

using GdPicture14;

public class GdPictureTiffProcessor
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;

    public string ExtractTextFromTiff(string tiffPath)
    {
        var text = new StringBuilder();

        // Load TIFF through the imaging component
        int tiffId = _imaging.CreateGdPictureImageFromFile(tiffPath);

        if (tiffId == 0)
            throw new Exception($"TIFF load failed: {_imaging.GetStat()}");

        // Outer try: release the original TIFF handle
        try
        {
            int frameCount = _imaging.GetPageCount(tiffId);

            for (int i = 1; i <= frameCount; i++)
            {
                // Switch to frame — modifies the existing ID in place
                _imaging.SelectPage(tiffId, i);

                // Clone frame to a new image ID for OCR
                int frameId = _imaging.CloneImage(tiffId);

                if (frameId == 0) continue;

                // Inner try: release each cloned frame ID
                try
                {
                    _ocr.SetImage(frameId);
                    _ocr.Language = "eng";

                    string resultId = _ocr.RunOCR();

                    if (!string.IsNullOrEmpty(resultId))
                    {
                        text.AppendLine($"[Frame {i}] {_ocr.GetOCRResultText(resultId)}");
                    }
                }
                finally
                {
                    // Release cloned frame — critical for each iteration
                    _imaging.ReleaseGdPictureImage(frameId);
                }
            }
        }
        finally
        {
            // Release original TIFF handle
            _imaging.ReleaseGdPictureImage(tiffId);
        }

        return text.ToString();
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class IronOcrTiffProcessor
{
    public string ExtractTextFromTiff(string tiffPath)
    {
        using var input = new OcrInput();
        input.LoadImageFrames(tiffPath);  // all frames loaded, all cleanup automatic

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

        // Per-frame text is available on result.Pages
        foreach (var page in result.Pages)
            Console.WriteLine($"[Frame {page.PageNumber}] {page.Text}");

        return result.Text;
    }
}
C#

LoadImageFrames는 멀티 페이지 TIFF의 모든 프레임을 OcrInput 파이프라인에 로드합니다. using 블록은 범위 끝에 있는 모든 프레임과 관련된 메모리를 처리합니다. 유지 해야 할 List<int>이 없으며, 중첩된 try/finally 블록이 필요하지 않습니다. TIFF 및 GIF 입력 가이드 에서는 프레임 선택 및 다중 형식 처리에 대해 자세히 설명합니다.

스트림 기반 입력으로 플러그인 초기화를 대체합니다.

서버 애플리케이션은 HTTP 업로드, 메시지 큐 또는 데이터베이스 블롭 등으로부터 파일 경로가 아닌 스트림 형태로 문서를 수신하는 경우가 많습니다. GdPicture은 GdPictureImaging을 통해 스트림을 로드해야 하며, 해당 과정 자체가 모든 작업 전에 구성 요소 초기화 시퀀스 및 리소스 폴더 구성을 요구합니다.

GdPicture .NET 접근 방식:

using GdPicture14;

public class GdPictureStreamOcr : IDisposable
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;

    public GdPictureStreamOcr()
    {
        // Plugin initialization required before stream loading is possible
        var lm = new LicenseManager();
        lm.RegisterKEY("GDPICTURE-LICENSE-KEY");

        _imaging = new GdPictureImaging();
        _ocr = new GdPictureOCR();
        _ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR"; // path must exist at runtime
    }

    public string ExtractTextFromStream(Stream documentStream)
    {
        // Load stream into imaging component to get an image ID
        int imageId = _imaging.CreateGdPictureImageFromStream(documentStream);

        if (imageId == 0)
            throw new Exception($"Stream load failed: {_imaging.GetStat()}");

        try
        {
            _ocr.SetImage(imageId);
            _ocr.Language = "eng";

            string resultId = _ocr.RunOCR();

            if (string.IsNullOrEmpty(resultId))
                throw new Exception($"OCR failed: {_ocr.GetStat()}");

            return _ocr.GetOCRResultText(resultId);
        }
        finally
        {
            _imaging.ReleaseGdPictureImage(imageId);
        }
    }

    public void Dispose()
    {
        _ocr?.Dispose();
        _imaging?.Dispose();
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class IronOcrStreamOcr
{
    public string ExtractTextFromStream(Stream documentStream)
    {
        using var input = new OcrInput();
        input.LoadImage(documentStream);  // stream accepted directly — no imaging component

        return new IronTesseract().Read(input).Text;
    }
}
C#

GdPicture 방식을 사용하려면 첫 번째 스트림을 소비하기 전에 세 개의 객체를 생성하고 파일 시스템 경로를 구성해야 합니다. IronOCR는 사전 설정 없이 OcrInput에서 스트림을 직접 수락합니다. 스트림 입력 가이드는 임시 파일 작성을 피하고자 하는 파이프라인 아키텍처를 위한 바이트 배열, MemoryStream, FileStream 패턴을 다룹니다.

비동기 OCR이 상태 코드 폴링을 대체합니다.

GdPicture OCR은 동기식입니다. ASP.NET Core 엔드포인트 또는 백그라운드 서비스에서 문서를 처리하는 애플리케이션은 Task.Run 내에서 RunOCR을 감싸서 요청 스레드를 차단하지 않도록 해야 하며, 스레드 경계를 넘어 이미지 ID 수명 주기를 관리해야 합니다. IronOCR는 ReadAsync를 통해 일류 비동기 지원을 제공합니다.

GdPicture .NET 접근 방식:

using GdPicture14;
using System.Threading.Tasks;

public class GdPictureAsyncWrapper
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;
    private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

    public async Task<string> ExtractTextAsync(string imagePath)
    {
        // Must acquire lock: GdPictureOCR is not thread-safe
        await _lock.WaitAsync();

        try
        {
            return await Task.Run(() =>
            {
                int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);

                if (imageId == 0)
                    throw new Exception($"Load failed: {_imaging.GetStat()}");

                try
                {
                    _ocr.SetImage(imageId);
                    _ocr.Language = "eng";

                    string resultId = _ocr.RunOCR();

                    if (string.IsNullOrEmpty(resultId))
                        throw new Exception($"OCR failed: {_ocr.GetStat()}");

                    return _ocr.GetOCRResultText(resultId);
                }
                finally
                {
                    _imaging.ReleaseGdPictureImage(imageId);
                }
            });
        }
        finally
        {
            _lock.Release();
        }
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class IronOcrAsyncService
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public async Task<string> ExtractTextAsync(string imagePath)
    {
        // ReadAsync is natively async — no Task.Run wrapper, no lock required
        var result = await _ocr.ReadAsync(imagePath);
        return result.Text;
    }

    public async Task<string> ExtractFromStreamAsync(Stream stream)
    {
        using var input = new OcrInput();
        input.LoadImage(stream);

        var result = await _ocr.ReadAsync(input);
        return result.Text;
    }
}
C#

GdPicture 방법은 공유 GdPictureOCR 인스턴스에 대한 접근을 직렬화하기 위해 SemaphoreSlim이 필요하며, 호출 스레드에서 동기화 차단 작업을 이동시키기 위해 Task.Run이 필요하며, 해당 람다 내에서 전체 이미지 ID 수명 주기를 포함해야 합니다. IronOCR의 ReadAsync은 진정한 비차단 및 스레드 안전성을 제공합니다. 비동기 OCR 가이드에서는 ASP.NET Core 미들웨어 및 호스팅된 백그라운드 서비스와의 통합에 대해 다룹니다.

스레드 안전성을 고려한 병렬 배치 처리

스캔한 문서가 담긴 폴더를 최대한 빠르게 처리하려면 병렬 실행이 필요합니다. GdPicture은 스레드 당 하나의 GdPictureOCR 인스턴스가 필요합니다 - 단일 인스턴스를 공유하면 비결정적 실패를 초래합니다. 각 스레드별 인스턴스는 또한 자체 GdPictureImaging 구성 요소와 리소스 폴더 구성이 필요하기 때문에, 공장 패턴 없이는 스레드 풀 접근이 실현 불가능합니다.

GdPicture .NET 접근 방식:

using GdPicture14;
using System.Collections.Concurrent;
using System.Threading.Tasks;

public class GdPictureParallelBatch
{
    private readonly string _resourceFolder = @"C:\GdPicture\Resources\OCR";

    public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
    {
        var results = new ConcurrentDictionary<string, string>();

        // Each thread must have its own component instances
        Parallel.ForEach(imagePaths, imagePath =>
        {
            // Create per-thread instances — shared instances cause failures
            using var threadImaging = new GdPictureImaging();
            using var threadOcr = new GdPictureOCR();
            threadOcr.ResourceFolder = _resourceFolder;

            // Re-register license per thread (may be required depending on SDK version)
            var lm = new LicenseManager();
            lm.RegisterKEY("GDPICTURE-LICENSE-KEY");

            int imageId = threadImaging.CreateGdPictureImageFromFile(imagePath);

            if (imageId == 0)
            {
                results[imagePath] = $"ERROR: {threadImaging.GetStat()}";
                return;
            }

            try
            {
                threadOcr.SetImage(imageId);
                threadOcr.Language = "eng";

                string resultId = threadOcr.RunOCR();
                results[imagePath] = string.IsNullOrEmpty(resultId)
                    ? $"ERROR: {threadOcr.GetStat()}"
                    : threadOcr.GetOCRResultText(resultId);
            }
            finally
            {
                threadImaging.ReleaseGdPictureImage(imageId);
            }
        });

        return results;
    }
}
C#

IronOCR 접근 방식:

using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;

public class IronOcrParallelBatch
{
    public ConcurrentDictionary<string, string> ProcessBatch(string[] imagePaths)
    {
        var results = new ConcurrentDictionary<string, string>();

        // IronTesseract is thread-safe — one instance handles all threads
        var ocr = new IronTesseract();

        Parallel.ForEach(imagePaths, imagePath =>
        {
            try
            {
                results[imagePath] = ocr.Read(imagePath).Text;
            }
            catch (Exception ex)
            {
                results[imagePath] = $"ERROR: {ex.Message}";
            }
        });

        return results;
    }
}
C#

GdPicture의 병렬 구현은 스레드당 세 개의 객체를 생성하며, 스레드별 라이선스 등록이 필요합니다. IronOCR는 동기화 오버헤드 없이 단일 IronTesseract 인스턴스에서 동시 읽기를 처리합니다. 멀티스레딩 예제는 문서 처리 작업 부하에서 고용량 처리량 벤치마크 및 Parallel.ForEach 패턴을 보여줍니다.

바이트 배열 입력 및 구조화된 단락 추출

데이터베이스나 객체 저장소에서 문서를 검색하는 애플리케이션은 파일 경로 대신 바이트 배열을 사용하는 경우가 많습니다. GdPicture은 바이트 배열을 스트림으로 변환하고 GdPictureImaging을 통해 로드해야 합니다. 결과에서 단락 수준의 구조화된 데이터를 추출하려면 블록/행 색인 계층 구조를 탐색해야 합니다.

GdPicture .NET 접근 방식:

using GdPicture14;

public class GdPictureByteArrayOcr
{
    private readonly GdPictureImaging _imaging;
    private readonly GdPictureOCR _ocr;

    public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
    {
        var paragraphs = new List<string>();

        // Byte array must go through MemoryStream to reach CreateGdPictureImageFromStream
        using var ms = new MemoryStream(imageBytes);
        int imageId = _imaging.CreateGdPictureImageFromStream(ms);

        if (imageId == 0)
            throw new Exception($"Byte array load failed: {_imaging.GetStat()}");

        try
        {
            _ocr.SetImage(imageId);
            _ocr.Language = "eng";

            string resultId = _ocr.RunOCR();

            if (string.IsNullOrEmpty(resultId))
                throw new Exception($"OCR failed: {_ocr.GetStat()}");

            // Paragraph-level data requires iterating block structure
            int blockCount = _ocr.GetOCRResultBlockCount(resultId);

            for (int b = 0; b < blockCount; b++)
            {
                var blockText = new StringBuilder();
                int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);

                for (int l = 0; l < lineCount; l++)
                {
                    int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);

                    for (int w = 0; w < wordCount; w++)
                    {
                        blockText.Append(_ocr.GetOCRResultBlockLineWordText(resultId, b, l, w));
                        blockText.Append(" ");
                    }
                }

                string text = blockText.ToString().Trim();
                if (!string.IsNullOrEmpty(text))
                    paragraphs.Add(text);
            }
        }
        finally
        {
            _imaging.ReleaseGdPictureImage(imageId);
        }

        return paragraphs;
    }
}
C#

IronOCR 접근 방식:

using IronOcr;

public class IronOcrByteArrayOcr
{
    public List<string> ExtractParagraphsFromBytes(byte[] imageBytes)
    {
        using var input = new OcrInput();
        input.LoadImage(imageBytes);  // byte array accepted directly

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

        // Paragraphs are a first-class typed collection
        return result.Paragraphs
            .Select(p => p.Text)
            .Where(t => !string.IsNullOrWhiteSpace(t))
            .ToList();
    }
}
C#

IronOCR는 중간 MemoryStream 없이 byte[]LoadImage에 직접 수락합니다. 결과는 블록/라인/단어 삼중 루프가 필요 없는 형식화된 LINQ-쿼리 가능한 컬렉션으로 .Paragraphs을 노출합니다. 결과 읽기 가이드에서는 송장 및 양식 처리 워크플로에 대한 좌표 액세스, 신뢰도 필터링 및 구조화된 출력 패턴을 다룹니다. 문서의 특정 영역을 스캔하려면 영역 기반 OCR을 참조하십시오.

GdPicture .NET API와IronOCR매핑 참조

GdPicture.NETIronOCR에 상응하는
using GdPicture14;using IronOcr;
LicenseManager.RegisterKEY("key")IronOcr.License.LicenseKey = "key"
new GdPictureImaging()필요 없음 – OcrInput 내부
new GdPictureOCR()new IronTesseract()
new GdPicturePDF()필요 없음 – OcrInput.LoadPdf()이 처리함
_ocr.ResourceFolder = path필수 사항이 아닙니다. 리소스는 NuGet 에 포함되어 있습니다.
imaging.CreateGdPictureImageFromFile(path)input.LoadImage(path)
imaging.CreateGdPictureImageFromStream(stream)input.LoadImage(stream)
imaging.CreateGdPictureImageFromBytes(bytes)input.LoadImage(bytes)
imaging.CloneImage(tiffId)은 프레임 당input.LoadImageFrames(tiffPath)
imaging.ReleaseGdPictureImage(imageId)using var input = new OcrInput() – 자동
ocr.SetImage(imageId)필요 없음 – OcrInput이 이미지를 보유
ocr.Language = "eng"ocr.Language = OcrLanguage.English
ocr.RunOCR()resultId 문자열ocr.Read(input) → 형식화된 OcrResult
ocr.GetOCRResultText(resultId)result.Text
ocr.GetOCRResultConfidence(resultId)result.Confidence
ocr.GetOCRResultBlockCount(resultId)result.Pages[i].Paragraphs.Count
ocr.GetOCRResultBlockLineWordText(resultId, b, l, w)result.Words[i].Text
imaging.GetStat() / ocr.GetStat()표준 .NET 예외
각 호출 후 GdPictureStatus.OK 확인필수 사항이 아닙니다. 예외 사항은 자동으로 전파됩니다.
pdf.OcrPage("eng", resourcePath, "", 200)result.SaveAsSearchablePdf(outputPath)
pdf.RenderPageToGdPictureImage(200, false)필수 사항이 아닙니다.IronOCR자체적으로 렌더링합니다.
pdf.SelectPage(i)필수 사항이 아닙니다. 기본적으로 모든 페이지가 처리됩니다.
pdf.GetPageCount()result.Pages.Count
Task.Run(() => ocr.RunOCR()) + SemaphoreSlimawait ocr.ReadAsync(input)

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

문제 1: 리팩토링 후 코드에 이미지 ID 변수가 남아 있음

GdPicture.NET: 기존 코드는 메서드 상단에 int imageId을 선언하고, try/finally를 통해 추적하며, 여러 GdPicture 호출로 전달합니다. GdPicture 호출을 교체한 후, 해당 변수와 ReleaseGdPictureImage 호출은 고아가 된 죽은 코드가 됩니다.

해결 방법: 이미지 ID 패턴 전체를 삭제합니다. 선언, try, finally, 해제 호출을 제거하고 using var input = new OcrInput() 블록으로 교체합니다. 제거해야 할 모든 정리 호출을 찾기 위해 ReleaseGdPictureImage을 검색하십시오:

grep -rn "ReleaseGdPictureImage\|imageId\|resultId" --include="*.cs" .
SHELL
// Remove all of this
int imageId = _imaging.CreateGdPictureImageFromFile(path);
try
{
    _ocr.SetImage(imageId);
    string resultId = _ocr.RunOCR();
    return _ocr.GetOCRResultText(resultId);
}
finally
{
    _imaging.ReleaseGdPictureImage(imageId);
}

// Replace with
using var input = new OcrInput();
input.LoadImage(path);
return new IronTesseract().Read(input).Text;
C#

문제 2: 배포 환경에서 리소스 폴더 경로를 찾을 수 없음

GdPicture.NET: 개발 머신에서 설정된 경로는 해결되지만, 운영 환경에서는 실패합니다. 공통 증상은 빈 결과를 반환하는 무음의 OCR 실패 또는 누락된 파일을 지칭하지 않는 일반적인 GdPictureStatus 오류입니다.

솔루션: ResourceFolder 할당을 완전히 제거합니다.IronOCR NuGet 패키지에는 영어 지원 기능이 포함되어 있습니다. 추가 언어는 NuGet 패키지로 설치됩니다. 구성하거나 배포할 파일 시스템 경로가 없습니다.

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

문제 3: GdPictureStatus 오류 처리 방식이 예외 처리 방식으로 대체됨

GdPicture.NET: 모든 작업은 즉시 확인해야 하는 GdPictureStatus 열거형 값을 반환하거나 설정합니다. 코드는 if (status != GdPictureStatus.OK) 보호 코드로 밀집되어 있습니다. 일부 상태 코드는 일반적입니다 (예: Error, InvalidParameter) 루트 원인을 확인하기 위해 문서를 참조해야 합니다.

**해결책:**IronOCR형식화된 .NET 예외를 발생시킵니다. 상태 확인 코드를 try/catch 블록으로 대체하세요. 표준 IOExceptionFileNotFoundException은 입력 실패를 포함합니다; IronOcr.Exceptions.OcrException은 OCR 전용 오류를 다룹니다. IronTesseract 설정 가이드 에서 권장 오류 처리 패턴을 참조하십시오.

try
{
    var result = new IronTesseract().Read(imagePath);
    return result.Text;
}
catch (FileNotFoundException ex)
{
    _logger.LogError("Input file missing: {Path}", ex.FileName);
    throw;
}
catch (IronOcr.Exceptions.OcrException ex)
{
    _logger.LogError("OCR processing failed: {Message}", ex.Message);
    throw;
}
C#

이슈 4: GdPicture14 네임스페이스의 여러 파일

GdPicture.NET: 네임스페이스의 버전 번호는 프로젝트 전역 using GdPicture14; 지시문이 수십 개의 파일에 존재함을 의미합니다. 마이그레이션 후, 이들은 모두 using IronOcr;로 교체되어야 합니다.

솔루션: 모든 .cs 파일에 대해 전역 찾기 및 교체를 사용한 다음, GdPicture 참조가 남아있지 않은지 확인하십시오:

# Find all files with GdPicture namespace
grep -rln "using GdPicture" --include="*.cs" .

# After replacing, verify nothing remains
grep -rn "GdPicture14\|GdPictureOCR\|GdPictureImaging\|GdPicturePDF" --include="*.cs" .
SHELL

문제 5: TIFF 프레임 카운트 로직

GdPicture.NET: TIFF 프레임을 반복하는 코드는 종종 파일이 로드된 방법에 따라 GdPictureImaging.GetPageCount(imageId)GdPicturePDF.GetPageCount()를 오가며 혼합 호출합니다. 프레임 인덱스는 1부터 시작합니다.

솔루션: 모든 프레임을 자동으로 처리하는 input.LoadImageFrames(path)을 사용하십시오. 기존 코드가 특정 프레임만 처리하는 경우, 0부터 시작하는 인덱스 배열과 함께 input.LoadImageFrames(path, frameNumbers)을 사용하십시오. 각 프레임 결과는 역시 0부터 시작하는 result.Pages를 통해 접근합니다. TIFF 입력 가이드 에는 인덱스 동작 방식이 명시적으로 설명되어 있습니다.

문제 6: 전처리에는 문서 이미지 처리 플러그인이 필요합니다.

GdPicture.NET: Deskew 및 despeckle 작업은 별도의 라이선스 구매가 필요한 GdPictureDocumentImaging 플러그인에 속합니다. 플러그인 설치를 건너뛴 팀은 페이지가 기울어져 있거나 노이즈가 많은 스캔 문서에서 OCR 정확도 문제가 발생하는 경우가 많습니다.

**해결책:**IronOCR전처리 방법은 기본 패키지에 포함되어 있습니다. Deskew()DeNoise()OcrInput에 직접 추가합니다. 이미지 품질 보정 가이드Contrast(), Sharpen(), Binarize(), 및 심하게 열화된 스캔을 위한 DeepCleanBackgroundNoise()을 포함한 모든 사용 가능한 필터를 다룹니다:

using var input = new OcrInput();
input.LoadImage("scanned-document.tiff");
input.Deskew();        // no separate plugin license
input.DeNoise();
input.Contrast();

var result = new IronTesseract().Read(input);
C#

GdPicture .NET 마이그레이션 체크리스트

사전 마이그레이션

변경 작업을 수행하기 전에 코드베이스를 감사하여 모든 GdPicture 종속성을 찾아내십시오.

# Find all GdPicture namespace imports
grep -rn "using GdPicture" --include="*.cs" .

# Find all image ID creation points
grep -rn "CreateGdPictureImageFromFile\|CreateGdPictureImageFromStream\|RenderPageToGdPictureImage\|CloneImage" --include="*.cs" .

# Find all release calls — these map to using block boundaries
grep -rn "ReleaseGdPictureImage" --include="*.cs" .

# Find all resource folder assignments
grep -rn "ResourceFolder" --include="*.cs" .

# Find all OCR result ID accesses
grep -rn "RunOCR\|GetOCRResult\|resultId" --include="*.cs" .

# Find all GdPictureStatus checks
grep -rn "GdPictureStatus\|GetStat()" --include="*.cs" .

# Count GdPicture-dependent files
grep -rln "GdPicture14" --include="*.cs" . | wc -l
SHELL

코드 수정 전에 다음 사항을 기록해 두십시오.

  • GdPictureImaging, GdPictureOCR, 및 GdPicturePDF 참조가 포함된 파일
  • 서로 다른 이미지 ID 생성/릴리스 쌍은 총 몇 개입니까?
  • 문서 이미지 플러그인(기울임 보정, 노이즈 제거) 사용 여부
  • 리소스 폴더에 있는 언어 traineddata 파일
  • 어떤 배포 스크립트 또는 Docker 파일이 리소스 폴더 경로를 참조합니까?

코드 마이그레이션

  1. 프로젝트 파일에서 모든 GdPicture NuGet 패키지를 제거합니다.
  2. NuGet을 통해 IronOcr 설치
  3. 리소스 폴더에 이전에 있던 각 언어에 대한 IronOcr.Languages.* Install-Package
  4. IronOcr.License.LicenseKey = "..."Program.cs 또는 Startup.cs에 추가
  5. LicenseManager.RegisterKEY() 호출 및 라이선스 매니저 객체 제거
  6. 모든 GdPictureImaging 필드 선언 및 생성자 초기화 제거
  7. 모든 GdPictureOCR 필드 선언 및 ResourceFolder 할당 제거
  8. OCR 워크플로를 위해 사용된 모든 GdPicturePDF 필드 선언 제거
  9. int imageId = _imaging.CreateGdPictureImage*(...) 블록을 using var input = new OcrInput();로 교체하십시오. 입력.Load*(...)`
  10. _ocr.SetImage(imageId);를 교체합니다. _ocr.Language = "..."; string resultId = _ocr.RunOCR();withvar result = new IronTesseract().Read(input);`
  11. _ocr.GetOCRResultText(resultId)result.Text으로 교체
  12. 모든 _imaging.ReleaseGdPictureImage(imageId) 호출 제거
  13. GdPictureStatus 검사를 try/catch 블록으로 교체
  14. TIFF 프레임 루프를 input.LoadImageFrames(path)으로 교체
  15. pdf.OcrPage(...) + pdf.SaveToFile(...)result.SaveAsSearchablePdf(outputPath)으로 교체
  16. 배포 스크립트 및 Docker 이미지에서 리소스 폴더 경로를 제거합니다.
  17. 모든 영향을 받은 파일에서 using GdPicture14;using IronOcr;으로 업데이트

마이그레이션 이후

모든 코드 변경을 완료한 후, 프로덕션 환경에 배포하기 전에 다음 사항을 확인하십시오.

  • 단일 이미지 OCR이 제거된 컴포넌트에서 NullReferenceException 없이 예상 문자 반환
  • 다중 페이지 TIFF 처리는 모든 프레임을 포함하고, result.Pages을 통해 페이지별 텍스트를 생성합니다.
  • PDF OCR은 50개 이상의 문서를 일괄 처리해도 메모리 사용량 증가 없이 모든 페이지를 처리합니다.
  • 스트림 입력은 중간 파일 작성 없이 MemoryStreamFileStream을 허용합니다.
  • 비동기 OCR은 스레드 풀을 차단하지 않고 ASP.NET Core 요청 처리기와 통합됩니다.
  • Parallel.ForEach으로 병렬 일괄 처리 시 모든 스레드에 대해 정확한 결과를 생성합니다.
  • 모든 언어 팩(프랑스어, 독일어 등) NuGet 패키지를 통해 올바르게 활성화됩니다.
  • 전처리 필터(기울기 보정, 노이즈 제거)는 스캔 문서의 정확도를 향상시킵니다.
  • 검색 가능한 PDF 출력물은 PDF 뷰어 및 텍스트 검색 애플리케이션에서 읽을 수 있습니다.
  • 마이그레이션을 거친 후, 어떠한 .cs 파일에도 GdPicture 네임스페이스 참조가 남아있지 않음
  • 메모리 프로파일은 지속적인 부하 상태에서도 안정적인 사용량을 보여줍니다 (이미지 할당 누수 없음).
  • 파일 시스템 경로 오류 없이 Linux 및 Docker 대상 환경에 배포가 성공적으로 완료됩니다.

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

컴파일러가 메모리 안전성을 보장합니다. GdPicture에서 개발자가 수동으로 관리해야 했던 이미지 ID 수명 주기가 완전히 사라집니다. OcrInputIDisposable을 구현하며, using 블록은 범위 끝에서의 정리를 강제합니다 - 예외 경로를 포함하여. 유지해야 할 List<int>이 없으며, 기억해야 할 finally 블록도 없고, 누락된 해제 호출로 인한 프로덕션 메모리 인시던트도 없습니다.

모든 OCR 상황을 위한 단일 패키지. 이미지 OCR, PDF OCR, 다중 페이지 TIFF 처리, 검색 가능한 PDF 생성, 전처리 필터, 바코드 읽기 및 125+ 언어 팩은 모두 IronOcr NuGet 패키지 및 해당 언어 동반자로 제공됩니다. 일반적인 워크플로우를 구현하기 위해 두 번째 또는 세 번째 라이선스를 구매해야 하는 기능 제한은 없습니다. 전체 기능 목록은 IronOCR 기능 개요를 참조하십시오.

네이티브 비동기 및 스레드 안전성. ReadAsync은 진정한 비동기 메서드로, Task.Run 래퍼가 아닙니다. IronTesseract는 동기화 없이 스레드 간에 안전하게 사용할 수 있습니다. 과거에 스레드 별 구성 요소 초기화 및 세마포어 직렬화가 필요했던 문서 처리 서비스가 Parallel.ForEach을 통해 단일 공유 인스턴스로 축소됩니다. 비동기 OCR 가이드는 ASP.NET Core 와 호스팅 서비스 패턴을 모두 다룹니다.

**배포 구성이 전혀 필요 없습니다.**IronOCR파일 시스템 경로, 외부 언어 파일, 네이티브 바이너리 배치, 배포 스크립트가 필요하지 않습니다. NuGet 복원 단계에서 애플리케이션에 필요한 모든 것을 제공합니다. Docker 이미지, Azure App Service 배포 및 Linux 서버는 모두 개발 환경과 동일하게 작동합니다. Docker 배포 가이드Azure 배포 가이드는 실제 운영 환경에 적합한 구성을 보여줍니다.

버전 안정 네임스페이스. using IronOcr는 주요 버전 릴리스 간에 변경되지 않았습니다. NuGet 버전 번호는 표준 패키지 관리 모델을 통해 버전 관리를 처리합니다. 향후 주요 업그레이드 시 코드베이스 전체에서 네임스페이스 가져오기를 찾아 바꾸는 작업이 필요하지 않습니다.

예측 가능한 영구 라이선스. IronOCR는 $999 (Lite), $1,499 (Plus), $2,399 (Professional), 및 $4,799 (Unlimited) - 1년 업데이트를 포함하는 일회성 영구 구매로 가격이 책정되며, 연간 갱신 옵션이 제공됩니다. 모든 기능은 모든 등급에서 이용 가능합니다. 기능별 플러그인 비용이나 페이지당 비용이 없으며, 첫 해 이후에는 유지보수 의무도 없습니다. 이전에 OCR 전용 워크플로우를 위해 GdPicture 플러그인 라이선스에 8,000달러 이상을 지출했던 팀은 첫 번째 라이선스 주기 내에 그 비용을 회수할 수 있습니다. 자세한 가격 정보는 IronOCR 라이선스 페이지 에서 확인할 수 있습니다.

참고해 주세요: GdPicture.NET 및 Tesseract는 각각의 소유자에 의해 등록된 상표입니다. 본 사이트는 Google, Nutrient 또는 ORPALIS와 관련이 없고, 보증이나 후원을 받지 않았습니다. 모든 제품명, 로고 및 브랜드는 해당 소유자의 자산입니다. 비교는 정보 제공 목적으로만 사용되며, 작성 시점에 공개적으로 이용 가능한 정보를 반영합니다.

관련 기사

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