IronOCR 과 AWS Textract 비교: 스타트업을 위한 OCR 솔루션
GdPicture.NET은 OCR 플러그인에 대한 단일 달러를 지불하기 전에 기본 라이선스가 필요하며, PDF를 읽거나 검색 가능한 출력을 생성하려면 추가 PDF 플러그인도 필요합니다. 현재 가격 문의는 GdPicture에 문의하십시오. 이미지와 PDF에서 텍스트를 추출해야 하는 팀의 경우, 여러 플러그인과 연간 유지 보수 비용이 합한 총 비용이 상당히 증가할 수 있습니다. 요금 청구 방식은 GdPicture의 아키텍처에서 직접적으로 비롯됩니다. GdPicture는 스캔, DICOM, 주석, 바코드 처리 및 PDF 편집을 포함하는 완벽한 문서 이미지 처리 플랫폼이며, OCR은 여러 플러그인 중 하나일 뿐입니다. OCR 기능만 필요한 팀은 실제로는 전혀 사용하지 않을 문서 이미지 처리 SDK 전체 비용을 부담하게 됩니다.
API 또한 동일한 철학을 반영합니다. GdPicture는 정수 이미지 ID를 사용하여 메모리의 리소스를 추적합니다 — 로드하는 모든 이미지는 int을 반환합니다. 해당 정수 핸들에 대해 메소드를 호출한 다음 명시적으로 해제하거나 메모리 누수를 수용해야 합니다. 이 패턴은 IDisposable 및 using 문보다 앞서 있습니다. 이 방식은 효과적이지만, 모든 정리 작업에 대한 결정 책임을 매번 개발자에게 전가합니다. 이 비교 분석에서는 플러그인 기반 가격 책정과 이미지 ID 수명 주기라는 두 가지 문제점을 API 복잡성, 전처리, PDF 처리와 함께 IronOCR 대조 대상으로 살펴봅니다.
GdPicture .NET 이해하기
GdPicture .NET 은 ORPALIS에서 개발한 상용 문서 이미지 처리 SDK입니다. 이 플랫폼은 수년에 걸쳐 이미지 처리, PDF 생성 및 편집, 바코드 판독 및 생성, TWAIN/WIA 스캐너 통합, DICOM 의료 영상, 주석 및 검토 워크플로, PDF/A 규격 준수 문서 보관 등 광범위한 기능을 포괄하도록 구축되었습니다. OCR은 이 생태계 내의 기능 중 하나이며, 전용 플러그인을 통해 제공됩니다.
SDK는 기능을 각각 고유의 기본 클래스를 가진 여러 모듈로 구성합니다.
- GdPictureImaging — 이미지 로딩, 처리, 형식 변환 및 모든 정수 이미지 ID의 출처
- GdPicturePDF — PDF 생성, 편집, 렌더링 및 페이지 수준 OCR 작업 (별도 플러그인 라이선스 필요)
- GdPictureOCR — 텍스트 인식 및 추출; GdPictureImaging에서 생성된 이미지 ID를 사용합니다.
- GdPicture1DBarcode / GdPicture2DBarcode — 선형 및 2D 바코드 읽기 및 쓰기 (별도 플러그인 라이선스 필요)
- GdPictureDocumentImaging — 기울기 보정, 얼룩 제거, 테두리 제거, 구멍 제거 등을 포함한 고급 문서 정리 필터 (별도 플러그인)
- GdPictureAnnotations — 문서 마크업, 검토 및 수정
기본 OCR도 두 구성 요소 GdPictureImaging 및 GdPictureOCR의 인스턴스를 생성하고 라이프사이클을 관리해야 합니다. PDF에서 OCR을 추출하려면 GdPicturePDF이 필요합니다. 네임스페이스 자체에 버전 번호 (GdPicture14)가 포함되어 있어, 주요 SDK 업그레이드 시 전체 코드베이스에 대해 찾기 및 바꾸기를 강제합니다.
일반적인 OCR 시나리오에 대한 플러그인 종속성 트리는 다음과 같습니다.
| 필요하시면 | 라이선스를 취득해야 합니다. |
|---|---|
| 이미지에서 OCR 추출 | 기본 라이선스 + OCR 플러그인 |
| PDF에서 OCR 추출 | 기본 구성 + OCR 플러그인 + PDF 플러그인 |
| 검색 가능한 PDF 출력 | 기본 구성 + OCR 플러그인 + PDF 플러그인 |
| OCR 전 문서 정리 | 기본 패키지 + OCR 플러그인 + 문서 이미지 처리 플러그인 |
이미지 ID 수명 주기
GdPicture의 핵심적인 아키텍처적 특징은 정수 이미지 ID 관리입니다. 이미지를 로드하면 GdPicture 런타임 내의 메모리를 할당하고 int 핸들을 반환합니다. 해당 정수 값을 사용하여 이후의 모든 호출에서 이미지를 참조합니다. 작업이 끝나면 해당 정수로 ReleaseGdPictureImage을 호출합니다. 그렇게 하지 않으면 프로세스가 끝날 때까지 메모리가 해제되지 않습니다.
using GdPicture14;
// Every image load returns an integer handle
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
{
throw new Exception($"Failed to load image: {_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
{
// CRITICAL: omitting this line causes a memory leak
_imaging.ReleaseGdPictureImage(imageId);
}
using GdPicture14;
// Every image load returns an integer handle
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
{
throw new Exception($"Failed to load image: {_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
{
// CRITICAL: omitting this line causes a memory leak
_imaging.ReleaseGdPictureImage(imageId);
}
Imports GdPicture14
' Every image load returns an integer handle
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(imagePath)
If imageId = 0 Then
Throw New Exception($"Failed to load image: {_imaging.GetStat()}")
End If
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then
Throw New Exception($"OCR failed: {_ocr.GetStat()}")
End If
Return _ocr.GetOCRResultText(resultId)
Finally
' CRITICAL: omitting this line causes a memory leak
_imaging.ReleaseGdPictureImage(imageId)
End Try
여러 페이지로 구성된 PDF를 처리할 때, 렌더링된 각 페이지는 별도의 이미지 ID를 생성합니다. 200 DPI 해상도의 100페이지 분량 문서에서 정리 작업이 누락될 경우 1~5GB의 메모리가 할당될 수 있습니다. 올바른 패턴은 모든 ID를 수집하고 finally 블록에서 해제하는 것을 요구합니다. 그러나 이러한 규율은 전적으로 개발자의 책임입니다.
IronOCR이해하기
IronOCR 은 .NET 용 상용 OCR 라이브러리로, 단일 NuGet 패키지로 제공됩니다. 해당 디자인 목표는 설정 오버헤드 없이 정확성을 제공하는 것입니다: 패키지를 설치하고, 라이센스 키를 설정하고, Read을 호출합니다. 이 라이브러리는 최적화된 Tesseract 5 엔진을 래핑하며, 자동 전처리, 네이티브 PDF 처리 및 구조화된 결과 접근 기능을 모두 표준 .NET 패턴을 통해 제공합니다.
주요 특징:
- 단일 NuGet 패키지 —
dotnet add package IronOcr가 설치됩니다. 외부 리소스 폴더 없음, 네이티브 바이너리 관리 기능 없음 - 표준 .NET 리소스 관리 —
OcrInput가IDisposable을 구현합니다. 모든 정리 작업은 예외 여부에 관계없이using문이 처리합니다. - 자동 전처리 — Deskew, DeNoise, Contrast, Binarize, 및 EnhanceResolution은
OcrInput의 한 줄 메소드 호출입니다. 엔진은 명시적인 지시 없이도 자동 교정을 적용합니다 - 네이티브 PDF 입력 — 스캔된 PDF와 네이티브 PDF가 모두 별도의 렌더링 단계 없이
IronTesseract.Read로 직접 전달됩니다. - 설계 상 스레드 안전 — 단일
IronTesseract인스턴스가 동시 요청을 처리합니다.Parallel.ForEach은 추가적인 동기화 없이 작동합니다. - 125개 이상의 언어 — 별도의 NuGet 패키지로 배포됨 (
IronOcr.Languages.French등), 관리할 tessdata 폴더가 필요 없습니다. - 구조화된 결과 접근 —
OcrResult은.Pages,.Lines,.Words,.Characters, 및.Barcodes을 좌표 데이터와 함께 타입화된 컬렉션으로 노출합니다.
가격은 영구적입니다: $999 Lite, $1,499 Plus, $2,999 Professional, $5,999 Unlimited. 모든 기능은 모든 등급에서 이용 가능합니다. 차이점은 개발자 수와 포함된 프로젝트 수입니다.
기능 비교
| 기능 | GdPicture.NET | IronOCR |
|---|---|---|
| 가격 모델 | 플러그인 기반 영구 라이선스 + 연간 20% 유지보수 비용 | 고정형 영구채, 연간 업데이트는 선택 사항입니다. |
| 진입 비용(PDF에서 OCR 처리) | 다수의 플러그인 필요 (가격 문의는 GdPicture에 문의하십시오) | $2,999 (하나의 패키지, 모든 기능) |
| 자원 관리 | 수동 정수 ID 추적 및 릴리스 | IDisposable / using 성명 |
| 네임스페이스 안정성 | 네임스페이스의 버전 번호 (GdPicture14) |
버전 독립적 (IronOcr) |
| PDF OCR | 별도의 PDF 플러그인이 필요합니다. | 내장형, 추가 라이선스 필요 없음 |
| 설치 | 여러 개의 NuGet 패키지 + 외부 리소스 폴더 | 단일 NuGet, 외부 파일 필요 없음 |
| 크로스 플랫폼 | 윈도우, 리눅스, macOS | 윈도우, 리눅스, macOS, Docker, AWS, Azure |
상세 기능 비교
| 기능 | GdPicture.NET | IronOCR |
|---|---|---|
| 설정 및 설치 | ||
| NuGet 설치 | 여러 패키지가 필요합니다 | dotnet add package IronOcr |
| 외부 리소스 폴더 | 필수 (tessdata 스타일 언어 파일) | 필수 아님 (묶음 상품) |
| 라이선스 활성화 | LicenseManager.RegisterKEY() |
IronOcr.License.LicenseKey = "..." |
| 컴포넌트 초기화 | PDF OCR워크플로우를 위한 3~4개 클래스 | new IronTesseract() |
| 주요 업그레이드 시 네임스페이스 | 모든 소스 파일을 업데이트해야 합니다. | 변경 사항 없음 |
| OCR 기능 | ||
| 이미지 OCR | 예 | 예 |
| PDF OCR | 예 (PDF 플러그인 필요) | 예 (내장형) |
| 비밀번호로 보호된 PDF | 예 | 예 |
| 다중 페이지 PDF | 수동 페이지 루프 + ID 정리 | 자동 |
| 검색 가능한 PDF 출력 | OcrPage + SaveToFile |
result.SaveAsSearchablePdf() |
| hOCR 내보내기 | 아니요 | 예 |
| 전처리 | ||
| 디스큐 | GdPictureDocumentImaging 플러그인을 통해 | input.Deskew() |
| 노이즈 제거 | GdPictureDocumentImaging 플러그인을 통해 | input.DeNoise() |
| 명암 대비 강화 | GdPictureImaging을 통해 | input.Contrast() |
| 이진화 | GdPictureImaging을 통해 | input.Binarize() |
| DPI 향상 | GdPictureImaging을 통해 | input.EnhanceResolution(300) |
| 자동 수정(코드 없음) | 아니요 | 예 (Read에 내장됨) |
| 리소스 관리 | ||
| 메모리 관리 모델 | 수동 정수 ID 추적 | IDisposable / GC |
| 메모리 누수 위험 | 높음(ReleaseGdPictureImage 누락) | 없음(using 문) |
| 나사 안전 | 수동 인스턴스 관리 | 설계상 스레드 안전 |
| 결과 및 데이터 | ||
| 일반 텍스트 | GetOCRResultText(resultId) |
result.Text |
| 신뢰도 점수 | GetOCRResultConfidence(resultId) |
result.Confidence |
| 단어 단위 데이터 | 중첩된 블록/줄/단어 반복 | result.Words 컬렉션 |
| 좌표 접근 | 블록/줄/단어 인덱스 호출을 통해 | 직접 .X, .Y, .Width, .Height |
| OCR 중 바코드 판독 | 별도의 바코드 플러그인을 통해 | ocr.Configuration.ReadBarCodes = true |
| 언어 | ||
| 언어 개수 | 테서랙트 기반, 유사한 적용 범위 | NuGet 패키지를 통해 125개 이상 |
| 언어 분포 | 리소스 폴더 파일 | NuGet 패키지 |
| 한 번에 여러 언어 지원 | 예 | 예 (AddSecondaryLanguage) |
| 배포 | ||
| Docker | 지원됨 | 지원됨(문서화됨) |
| Linux | 지원됨 | 지원됨 |
| AWS 람다 | 가능한 | 문서화된 가이드 |
| Azure 앱 서비스 | 가능한 | 문서화된 가이드 |
이미지 ID 수명 주기 vs. 일회용 OcrInput
GdPicture와IronOCR간의 가장 중요한 아키텍처적 차이점은 기능상의 차이가 아니라, 각 라이브러리가 처리하는 이미지에 대한 메모리 관리 방식입니다.
GdPicture 접근법
GdPicture의 모든 이미지는 런타임에 관리되는 풀에 정수 핸들로 존재합니다. 이미지를 불러와 핸들을 획득하고, 해당 정수 값을 OCR 및 기타 작업에 전달한 다음 작업이 완료되면 해제합니다. 이 패턴은 명확하고, 그대로 따르면 정확합니다. 문제는 이를 잘못 이해하기 쉽고, 그 결과 메모리 용량이 무한정 증가한다는 것입니다.
PDF OCR 워크플로는 이러한 위험성을 가장 명확하게 보여줍니다. pdf.RenderPageToGdPictureImage()의 각 호출은 메모리에 새로운 래스터 이미지를 할당하고 새 정수 ID를 반환합니다. 100페이지짜리 문서는 100개의 개별 할당을 생성합니다. 단 하나의 ReleaseGdPictureImage 호출을 누락하면 프로세스는 유출된 메모리를 축적합니다:
using GdPicture14;
public string ExtractTextFromPdf(string pdfPath)
{
var text = new StringBuilder();
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(pdfPath, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Failed to load PDF: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// Each page render = new memory allocation + new integer ID
int imageId = pdf.RenderPageToGdPictureImage(200, false);
if (imageId == 0) continue;
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (!string.IsNullOrEmpty(resultId))
text.AppendLine(_ocr.GetOCRResultText(resultId));
}
finally
{
// Without this: ~10–50MB leaked per page
_imaging.ReleaseGdPictureImage(imageId);
}
}
return text.ToString();
}
using GdPicture14;
public string ExtractTextFromPdf(string pdfPath)
{
var text = new StringBuilder();
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(pdfPath, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Failed to load PDF: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// Each page render = new memory allocation + new integer ID
int imageId = pdf.RenderPageToGdPictureImage(200, false);
if (imageId == 0) continue;
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (!string.IsNullOrEmpty(resultId))
text.AppendLine(_ocr.GetOCRResultText(resultId));
}
finally
{
// Without this: ~10–50MB leaked per page
_imaging.ReleaseGdPictureImage(imageId);
}
}
return text.ToString();
}
Imports GdPicture14
Imports System.Text
Public Function ExtractTextFromPdf(ByVal pdfPath As String) As String
Dim text As New StringBuilder()
Using pdf As New GdPicturePDF()
Dim status As GdPictureStatus = pdf.LoadFromFile(pdfPath, False)
If status <> GdPictureStatus.OK Then
Throw New Exception($"Failed to load PDF: {status}")
End If
Dim pageCount As Integer = pdf.GetPageCount()
For i As Integer = 1 To pageCount
pdf.SelectPage(i)
' Each page render = new memory allocation + new integer ID
Dim imageId As Integer = pdf.RenderPageToGdPictureImage(200, False)
If imageId = 0 Then Continue For
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If Not String.IsNullOrEmpty(resultId) Then
text.AppendLine(_ocr.GetOCRResultText(resultId))
End If
Finally
' Without this: ~10–50MB leaked per page
_imaging.ReleaseGdPictureImage(imageId)
End Try
Next
End Using
Return text.ToString()
End Function
여러 PDF 파일을 일괄 처리하는 것은 이러한 문제를 더욱 악화시킵니다. 각 for 루프의 문서는 List<int>에서 ID를 수집하고 모두 finally에서 해제해야 한다고 유지 관리자에게 상기시키는 메모리를 가지고 있어야 합니다. 그건 인프라 구축 작업이지, OCR 작업이 아닙니다.
IronOCR접근법
OcrInput는 표준 IDisposable입니다. 메소드가 정상적으로 반환되거나 예외를 던지는지 여부에 관계없이 using 문이 정리를 보장합니다. 추적해야 할 정수 ID도 없고, 초기화해야 할 별도의 이미지 구성 요소도 없으며, PDF 페이지에 대한 외부 DPI 렌더링 단계도 없습니다.
using IronOcr;
public string ExtractTextFromPdf(string pdfPath)
{
// LoadPdf handles page rendering internally
using var input = new OcrInput();
input.LoadPdf(pdfPath);
var result = new IronTesseract().Read(input);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
return result.Text;
// using block exits — all internal resources released automatically
}
using IronOcr;
public string ExtractTextFromPdf(string pdfPath)
{
// LoadPdf handles page rendering internally
using var input = new OcrInput();
input.LoadPdf(pdfPath);
var result = new IronTesseract().Read(input);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
return result.Text;
// using block exits — all internal resources released automatically
}
Imports IronOcr
Public Function ExtractTextFromPdf(pdfPath As String) As String
' LoadPdf handles page rendering internally
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Dim result = New IronTesseract().Read(input)
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
Next
Return result.Text
' using block exits — all internal resources released automatically
End Using
End Function
암호로 보호된 PDF의 경우, 해당 매개변수는 추가적인 상태 확인이 필요한 별도의 오버로드 방식이 아니라 명명된 인수입니다.
using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf("searchable-output.pdf");
using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf("searchable-output.pdf");
Imports IronOcr
Using input As New OcrInput()
input.LoadPdf("encrypted.pdf", Password:="secret")
Dim result = New IronTesseract().Read(input)
result.SaveAsSearchablePdf("searchable-output.pdf")
End Using
IronOCR PDF 입력 가이드에는 페이지 범위 선택을 포함한 추가 옵션이 설명되어 있습니다. Entity Framework, HttpClient, 스트림 처리 전반에서 이미 익숙한 IDisposable 패턴을 가진 팀에게는 OcrInput이 새로운 정신 모델을 요구하지 않습니다.
플러그인 번들링 비용
이미지와 PDF에서 텍스트를 추출하고 검색 가능한 출력을 생성해야 하는 서버 응용 프로그램의 경우, GdPicture 라이선스 스택은 여러 플러그인을 요구합니다. Professional 기본 라이선스, OCR 플러그인, PDF 플러그인에 대한 현재 가격 조회는 GdPicture에 문의하십시오. 연간 유지 보수 비용 (일반적으로 전체 라이선스 비용의 일정 비율)은 시간이 흐르며 증가합니다.
IronOCR Professional 동일한 워크플로우를 하나의 패키지에 담았습니다.
IronOCR Professional: $professionalLicense (one-time)
옵션 연간 업데이트: $plusLicense/연도
3년 총액 (영구, 업데이트 없음): $professionalLicense
다년간의 비용 차이는 업데이트 선호도에 따라 상당히 달라질 수 있습니다. 그러한 가격 차이가 발생하는 이유는 GdPicture의 플러그인 모델이 OCR에 특화된 워크로드가 아닌 전체 문서 이미지 처리 플랫폼을 기준으로 가격이 책정되었기 때문입니다. OCR 플러그인은 가장 일반적인 OCR 입력 형식을 사용할 수 있게 하는 PDF 플러그인 전에 필수입니다.
OCR을 위해 GdPicture를 평가하는 팀은 OCR 관련 백로그에서 거의 찾아볼 수 없는 기능, 즉 TWAIN/WIA 스캐너 통합, DICOM 의료 영상, 주석 및 수정 워크플로, 텍스트 추출을 넘어선 고급 PDF 편집 기능에 비용을 지불합니다. IronOCR 라이선스 페이지에서 플러그인이나 기능별 라이선스 결정 없이 모든 기능이 모든 계층에서 제공되는 가격 모델을 확인하세요.
API 복잡성 및 전처리
GdPicture는 GdPictureImaging을 통해 전처리를 제공합니다 (대비, 이진화, 해상도 스케일링) 및 별도의 GdPictureDocumentImaging 플러그인을 통해 (정렬, 제거, 테두리 제거). OCR 전에 기울기 보정을 적용하려면 문서 이미지 처리 플러그인 라이선스가 필요하므로, 품질이 다양한 스캔 문서를 처리하는 모든 워크플로에 세 번째 비용이 추가됩니다.
GdPicture 접근법
저품질 스캔 PDF 파일의 전체 워크플로(로드, 전처리, 페이지별 OCR 처리, 릴리스)는 세 가지 구성 요소 클래스에 걸쳐 있으며 각 단계에서 세심한 상태 확인이 필요합니다.
using GdPicture14;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(inputPdf, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Load failed: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// OcrPage adds text layer to each page
// Requires: OCR plugin + PDF plugin + resource folder path
GdPictureStatus ocrStatus = pdf.OcrPage(
"eng",
@"C:\GdPicture\Resources\OCR", // 외부 리소스 폴더 required
"",
200
);
if (ocrStatus != GdPictureStatus.OK)
Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}");
}
pdf.SaveToFile(outputPdf, true);
}
using GdPicture14;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(inputPdf, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Load failed: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// OcrPage adds text layer to each page
// Requires: OCR plugin + PDF plugin + resource folder path
GdPictureStatus ocrStatus = pdf.OcrPage(
"eng",
@"C:\GdPicture\Resources\OCR", // 외부 리소스 폴더 required
"",
200
);
if (ocrStatus != GdPictureStatus.OK)
Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}");
}
pdf.SaveToFile(outputPdf, true);
}
Imports GdPicture14
Public Sub CreateSearchablePdf(inputPdf As String, outputPdf As String)
Using pdf As New GdPicturePDF()
Dim status As GdPictureStatus = pdf.LoadFromFile(inputPdf, False)
If status <> GdPictureStatus.OK Then
Throw New Exception($"Load failed: {status}")
End If
Dim pageCount As Integer = pdf.GetPageCount()
For i As Integer = 1 To pageCount
pdf.SelectPage(i)
' OcrPage adds text layer to each page
' Requires: OCR plugin + PDF plugin + resource folder path
Dim ocrStatus As GdPictureStatus = pdf.OcrPage(
"eng",
"C:\GdPicture\Resources\OCR", ' 외부 리소스 폴더 required
"",
200
)
If ocrStatus <> GdPictureStatus.OK Then
Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}")
End If
Next
pdf.SaveToFile(outputPdf, True)
End Using
End Sub
ResourceFolder 경로는 선택 사항이 아닙니다. 실행 시에 .traineddata 언어 파일이 포함된 디렉토리로 확인되어야 합니다. 이 경로는 개발 머신에서는 작동하지만, 서비스 계정이 C:\GdPicture\Resources\OCR을 볼 수 없거나, 애플리케이션이 Linux로 배포되거나, Docker이미지에 해당 디렉토리 구조가 포함되어 있지 않을 때 프로덕션에서 실패합니다. 이러한 실패를 디버깅하는 것은 종종 루트 원인에 대해 거의 설명하지 않는 일반적인 GdPictureStatus 오류 코드를 추적하는 것을 의미합니다.
IronOCR접근법
IronOCR 에서 이와 동등한 워크플로는 (경사 보정 및 노이즈 제거를 위한 전처리를 포함하여) 단 다섯 줄입니다.
using IronOcr;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(inputPdf);
input.Deskew(); // 아니요 separate plugin required
input.DeNoise();
var result = ocr.Read(input);
result.SaveAsSearchablePdf(outputPdf);
}
using IronOcr;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(inputPdf);
input.Deskew(); // 아니요 separate plugin required
input.DeNoise();
var result = ocr.Read(input);
result.SaveAsSearchablePdf(outputPdf);
}
Imports IronOcr
Public Sub CreateSearchablePdf(inputPdf As String, outputPdf As String)
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadPdf(inputPdf)
input.Deskew() ' 아니요 separate plugin required
input.DeNoise()
Dim result = ocr.Read(input)
result.SaveAsSearchablePdf(outputPdf)
End Using
End Sub
NuGet 패키지에는 영어 지원 기능이 내장되어 있습니다. 추가 언어는 IronOcr.Languages.French가 아닌 파일 시스템 경로의 .traineddata 파일 대신 NuGet 패키지로 설치됩니다. 이미지 품질 수정 가이드 및 이미지 방향 수정 가이드는 OcrInput에서 사용할 수 있는 전처리 옵션의 전체 세트를 다룹니다.
신뢰도 기반 처리(예: 데이터베이스에 기록하기 전에 임계값 미만의 결과를 필터링)의 경우 결과 객체는 신뢰도를 직접 노출합니다.
var result = new IronTesseract().Read("scanned.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");
// Per-word confidence for fine-grained filtering
var highConfidenceWords = result.Words
.Where(w => w.Confidence > 85)
.Select(w => w.Text);
var result = new IronTesseract().Read("scanned.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");
// Per-word confidence for fine-grained filtering
var highConfidenceWords = result.Words
.Where(w => w.Confidence > 85)
.Select(w => w.Text);
Imports System
Imports System.Linq
Dim result = (New IronTesseract()).Read("scanned.jpg")
Console.WriteLine($"Confidence: {result.Confidence}%")
' Per-word confidence for fine-grained filtering
Dim highConfidenceWords = result.Words _
.Where(Function(w) w.Confidence > 85) _
.Select(Function(w) w.Text)
GdPicture는 같은 데이터를 얻기 위해 세 개의 중첩 루프 — 블록, 라인, 단어 — 가 필요하며, 각 레벨에서 인덱스 기반 메소드 호출 (GetOCRResultBlockLineWordConfidence(resultId, b, l, w))이 필요합니다. 신뢰도 점수 활용 방법은 일반적인 사용 사례에 대한 구조화된 접근 모델을 보여줍니다.
구조화된 데이터 및 결과 접근
단어별 좌표와 신뢰도 값을 추출하는 것은 문서 이해 워크플로에서 흔히 요구되는 사항입니다. 송장 필드 추출, 양식 처리 및 레이아웃 분석 모두 이러한 기능을 필요로 합니다.
GdPicture 접근법
GdPicture는 RunOCR()에서 resultId 문자열을 반환하며, 모든 결과 데이터는 GdPictureOCR 인스턴스에서 메소드 호출을 통해 해당 ID로 쿼리됩니다. 단어 단위의 정확도를 높이려면 세 가지 계층적 단계를 반복적으로 거쳐야 합니다.
using GdPicture14;
public List<(string word, float confidence)> GetWordConfidences(int imageId)
{
var words = new List<(string, float)>();
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
int blockCount = _ocr.GetOCRResultBlockCount(resultId);
for (int b = 0; b < blockCount; b++)
{
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++)
{
string word = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w);
float conf = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w);
words.Add((word, conf));
}
}
}
return words;
}
using GdPicture14;
public List<(string word, float confidence)> GetWordConfidences(int imageId)
{
var words = new List<(string, float)>();
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
int blockCount = _ocr.GetOCRResultBlockCount(resultId);
for (int b = 0; b < blockCount; b++)
{
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++)
{
string word = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w);
float conf = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w);
words.Add((word, conf));
}
}
}
return words;
}
Imports GdPicture14
Public Function GetWordConfidences(imageId As Integer) As List(Of (word As String, confidence As Single))
Dim words As New List(Of (String, Single))()
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
Dim blockCount As Integer = _ocr.GetOCRResultBlockCount(resultId)
For b As Integer = 0 To blockCount - 1
Dim lineCount As Integer = _ocr.GetOCRResultBlockLineCount(resultId, b)
For l As Integer = 0 To lineCount - 1
Dim wordCount As Integer = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l)
For w As Integer = 0 To wordCount - 1
Dim word As String = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w)
Dim conf As Single = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w)
words.Add((word, conf))
Next
Next
Next
Return words
End Function
이것은 틀린 말이 아닙니다. 데이터에 접근할 수 있습니다. 하지만 이를 위해서는 단어 수준 데이터가 필요한 모든 프로젝트에 대해 결과 구조에 대한 3차원 색인을 이해하고 유지해야 합니다.
IronOCR접근법
OcrResult은 .Words을 타입화된 컬렉션으로 노출합니다. LINQ는 이를 직접적으로 공격합니다.
using IronOcr;
var result = new IronTesseract().Read("invoice.jpg");
// All words with position and confidence
foreach (var word in result.Words)
{
Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}");
}
// Lines, paragraphs, and pages follow the same pattern
foreach (var line in result.Lines)
Console.WriteLine(line.Text);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters");
using IronOcr;
var result = new IronTesseract().Read("invoice.jpg");
// All words with position and confidence
foreach (var word in result.Words)
{
Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}");
}
// Lines, paragraphs, and pages follow the same pattern
foreach (var line in result.Lines)
Console.WriteLine(line.Text);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters");
Imports IronOcr
Dim result = New IronTesseract().Read("invoice.jpg")
' All words with position and confidence
For Each word In result.Words
Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}")
Next
' Lines, paragraphs, and pages follow the same pattern
For Each line In result.Lines
Console.WriteLine(line.Text)
Next
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters")
Next
문서의 특정 사각형 영역에서 텍스트를 추출하는 영역 기반 OCR 방식 역시 마찬가지로 직접적입니다.
var region = new CropRectangle(0, 0, 600, 100); // header area
using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);
var headerText = new IronTesseract().Read(input).Text;
var region = new CropRectangle(0, 0, 600, 100); // header area
using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);
var headerText = new IronTesseract().Read(input).Text;
Imports IronOcr
Dim region As New CropRectangle(0, 0, 600, 100) ' header area
Using input As New OcrInput()
input.LoadImage("invoice.jpg", region)
Dim headerText As String = New IronTesseract().Read(input).Text
End Using
읽기 결과 가이드 와 영역 기반 OCR 가이드는 이러한 패턴이 여러 페이지로 구성된 문서와 구조화된 필드 추출 워크플로에 어떻게 적용되는지 보여줍니다.
API 매핑 참조
| GdPicture.NET | IronOCR에 상응하는 |
|---|---|
LicenseManager.RegisterKEY("key") |
IronOcr.License.LicenseKey = "key" |
new GdPictureImaging() |
필수 사항이 아닙니다. 내부적으로 처리됩니다. |
new GdPictureOCR() |
new IronTesseract() |
new GdPicturePDF() |
필요하지 않음 — OcrInput.LoadPdf()가 이를 처리합니다 |
ocr.ResourceFolder = path |
필수 사항이 아닙니다. 리소스는 NuGet 에 포함되어 있습니다. |
imaging.CreateGdPictureImageFromFile(path) |
input.LoadImage(path)가 OcrInput 위에 있습니다. |
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.GetOCRResultBlockLineWordText(resultId, b, l, w) |
result.Words[i].Text |
ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w) |
result.Words[i].Confidence |
pdf.LoadFromFile(path, false) → GdPictureStatus |
input.LoadPdf(path) — 실패 시 던지기 |
pdf.LoadFromFile(path, password) |
input.LoadPdf(path, Password: password) |
pdf.RenderPageToGdPictureImage(200, false) |
필수 사항이 아닙니다.IronOCR자체적으로 렌더링합니다. |
pdf.SelectPage(i) |
필수 사항이 아닙니다. 기본적으로 모든 페이지가 처리됩니다. |
pdf.GetPageCount() |
필요하지 않음 — 또는 result.Pages.Count |
pdf.OcrPage("eng", resourcePath, "", 200) |
result.SaveAsSearchablePdf(outputPath) |
pdf.SaveToFile(outputPath, true) |
result.SaveAsSearchablePdf(outputPath) |
imaging.GetStat() / ocr.GetStat() |
표준 .NET 예외 |
GdPictureStatus.OK 호출 후 확인 |
필수 사항이 아닙니다. 예외는 정상적으로 전파됩니다. |
using GdPicture14; |
using IronOcr; |
팀이 GdPicture .NET 에서IronOCR로 전환을 고려할 때
OCR이 유일한 필수 요건입니다.
스캔한 송장 입력, 의료 양식 처리, 계약서 텍스트 추출 등 문서 수집 파이프라인을 구현하는 팀은 GdPicture가 LEADTOOLS 및 Kofax와 함께 Enterprise 소프트웨어 목록에 포함되어 있기 때문에 GdPicture를 자주 평가합니다. 플러그인 종속성 표가 명확해지면 상황이 달라집니다. PDF 입력이 필요한 경우 PDF 플러그인은 필수입니다. 문서 이미지 처리 플러그인은 전처리 작업이 필요한 경우 필수적입니다. 디스큐 교정을 사용한 스캔된 PDF에서 OCR이 필요한 팀은 상당한 Professional 초기 비용을 가진 세 가지 플러그인 라이선스를 갖게 됩니다. 요구 사항이 텍스트 추출이고 GdPicture 기능 목록의 다른 것이 필요하지 않다면, 이러한 가격은 순수한 간접 비용을 의미합니다. IronOCR는 $2,999 Professional이 단일 패키지에서 플러그인 결정을 필요로 하지 않고 동일한 워크플로우 — 이미지 입력, PDF 입력, 전처리, 검색 가능한 PDF 출력 — 을 적용합니다.
운영 환경에서의 메모리 누수 사고
정수 ID의 수명 주기는 고처리량 문서 처리 서비스에서 언제든 발생할 수 있는 운영상의 문제로 이어질 수 있습니다. 부하가 걸린 상태에서 업로드된 PDF를 처리하는 웹 API 엔드포인트는 결국 이미지 해제 호출에 도달하지 못하는 코드 경로를 갖게 될 것입니다. 오류 분기에서 조기에 반환되거나, 정리 블록 이전에 처리되지 않은 예외가 발생하거나, 또는 해당 패턴에 익숙하지 않은 개발자가 정수 이미지 핸들을 매개변수로 받는 헬퍼 메서드를 추가하고 이를 해제하는 것을 잊어버리는 경우 등이 그 예입니다. 메모리 사용량이 증가하고 서비스 속도가 느려지지만, 힙 덤프에서 근본 원인을 찾기는 어렵습니다. 이러한 문제를 디버깅해 본 팀들은 일반적으로 런타임이 정리를 처리하는 모델을 선호합니다.IronOCR의 표준 해제 패턴은 바로 그러한 모델입니다. 즉, 개발자가 모든 호출 지점에서 정리를 수행하는 대신 컴파일러가 구조화된 정리를 강제하는 방식입니다.
버전 업그레이드 마찰
GdPicture는 네임스페이스에 주요 버전 번호를 포함합니다. 버전 14에서 버전 15로 업그레이드하려면 GdPicture 클래스를 참조하는 모든 소스 파일에서 해당 네임스페이스 지시문을 업데이트해야 합니다. OCR, PDF 처리, 이미지 처리 기능이 수십 개의 서비스와 유틸리티 클래스에 걸쳐 분산되어 있는 대규모 애플리케이션의 경우, 이는 간단한 마이그레이션 작업이 아니며 기능적인 이점도 없습니다. Microsoft.EntityFrameworkCore부터 Newtonsoft.Json에 이르기까지 모든 최신 .NET 라이브러리는 버전과 무관한 네임스페이스를 사용하며, NuGet 패키지 버전 번호를 통해 버전을 관리합니다.IronOCR해당 규칙을 따릅니다. 즉, 버전 1부터 현재 릴리스까지 동일한 네임스페이스 가져오기가 적용됩니다.
마이크로서비스 및 컨테이너 배포
GdPicture OCR은 런타임 시 특정 경로에 언어 데이터 파일이 포함된 외부 리소스 폴더가 있어야 합니다. 컨테이너 환경에서는 해당 파일을 Docker이미지에 포함시키거나, 볼륨을 마운트하거나, 시작 스크립트를 구성하여 파일을 다운로드하도록 해야 합니다. 일반적으로 그 결과는 필요 이상으로 수백 메가바이트 더 큰 Docker이미지, 배포 체크리스트 항목 누락, 그리고 볼륨이 마운트되지 않아 컨테이너를 정상적으로 재시작할 때 발생하는 프로덕션 오류입니다.IronOCR패키지 자체에 영어 지원 기능을 포함하고 있습니다. 추가 언어는 빌드 출력의 일부로 NuGet 패키지로 설치됩니다. 컨테이너는 복원 단계에서 필요한 것을 가져오므로 구성할 경로가 없습니다. Docker 배포 가이드 와 Linux 배포 가이드는 각 대상 환경에 대한 구체적인 구성 방법을 설명합니다.
문서 이미지 처리 전문 지식이 없는 개발팀
GdPicture의 적용 범위가 넓은 것은 필연적입니다. 문서 이미지 처리 플랫폼 전체를 포괄하기 때문입니다. OCR 마이크로서비스를 유지 관리하는 팀에 합류하는 개발자에게는 이미지 처리 구성 요소, OCR 구성 요소, PDF 구성 요소, 정수 ID 수명 주기, 상태 반환 코드 처리 및 리소스 폴더 구성을 이해하는 것이 상당한 초기 투자입니다. IronOCR의 OCR 처리 영역은 엔진, 입력 컨테이너, 결과 객체의 세 가지 클래스로 구성됩니다. 그것이 사용 사례의 90%에 대한 전체적인 사고방식입니다. 새로운 개발자를 온보딩한다는 것은 멀티 모듈 SDK 가이드보다는 IronTesseract 설정 방법 을 알려주는 것을 의미합니다.
일반적인 마이그레이션 고려사항
컴포넌트 초기화 교체
GdPicture는 4단계 초기화 시퀀스를 요구합니다: LicenseManager을 통해 라이센스 키 등록, GdPictureImaging 초기화, GdPictureOCR 초기화 및 리소스 폴더 경로 설정. IronOCR는 이것을 Program.cs 또는 Startup.cs에 속하는 단일 속성 할당으로 줄입니다.
// Remove
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR";
// Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY";
// IronTesseract instances are instantiated per-use or as a singleton
// Remove
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR";
// Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY";
// IronTesseract instances are instantiated per-use or as a singleton
' Remove
Dim lm As New LicenseManager()
lm.RegisterKEY("GDPICTURE-LICENSE-KEY")
_imaging = New GdPictureImaging()
_ocr = New GdPictureOCR()
_ocr.ResourceFolder = "C:\GdPicture\Resources\OCR"
' Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY"
' IronTesseract instances are instantiated per-use or as a singleton
이미지 ID 추적 제거
모든 CreateGdPictureImageFromFile 호출 및 모든 RenderPageToGdPictureImage 호출에는 기존 코드베이스 어딘가에 해당하는 ReleaseGdPictureImage 호출이 있습니다. 이러한 정리 호출은 IronOCR에서 완전히 제거되었습니다 — OcrInput가 처분을 처리합니다. 이동은 기계적입니다: 각 int imageId = ...을 찾고, 짝을 이루는 ReleaseGdPictureImage(imageId)를 찾아 로딩 코드를 using var input = new OcrInput()로 감싸고, GdPicture 메소드 호출을 IronOCR의 해당 호출로 대체합니다.
// Remove
int imageId = _imaging.CreateGdPictureImageFromFile(path);
if (imageId == 0) throw new Exception(_imaging.GetStat().ToString());
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId)) throw new Exception(_ocr.GetStat().ToString());
string text = _ocr.GetOCRResultText(resultId);
_imaging.ReleaseGdPictureImage(imageId);
// Replace with
using var input = new OcrInput();
input.LoadImage(path);
var result = new IronTesseract().Read(input);
string text = result.Text;
// Remove
int imageId = _imaging.CreateGdPictureImageFromFile(path);
if (imageId == 0) throw new Exception(_imaging.GetStat().ToString());
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId)) throw new Exception(_ocr.GetStat().ToString());
string text = _ocr.GetOCRResultText(resultId);
_imaging.ReleaseGdPictureImage(imageId);
// Replace with
using var input = new OcrInput();
input.LoadImage(path);
var result = new IronTesseract().Read(input);
string text = result.Text;
Imports System
' Remove
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(path)
If imageId = 0 Then Throw New Exception(_imaging.GetStat().ToString())
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then Throw New Exception(_ocr.GetStat().ToString())
Dim text As String = _ocr.GetOCRResultText(resultId)
_imaging.ReleaseGdPictureImage(imageId)
' Replace with
Using input As New OcrInput()
input.LoadImage(path)
Dim result = New IronTesseract().Read(input)
Dim text As String = result.Text
End Using
오류 처리 적응
GdPicture는 각 중요한 운영 후 GdPictureStatus 반환 코드를 사용합니다.IronOCR일반적인 .NET 예외를 발생시킵니다. 이동은 if (status != GdPictureStatus.OK) 가드를 try/catch 블록으로 대체하여 OCR 특정 실패와 입력 실패에 대해 표준 IOException 및 FileNotFoundException을 처리합니다. 이미지에서 텍스트를 읽는 방법에 대한 튜토리얼 에서는 일반적인 시나리오에 대한 오류 처리 패턴을 다룹니다.
언어 팩 배포
GdPicture 언어 파일은 파일 시스템 폴더의 .traineddata 파일입니다.IronOCR언어 팩은 NuGet 패키지입니다. 이번 마이그레이션은 배포 매니페스트에서 리소스 폴더를 제거하고 필요한 각 언어에 대한 NuGet 패키지 참조를 추가합니다.
# Remove filesystem dependency for each language
# Add NuGet package instead
dotnet add package IronOcr.Languages.French
dotnet add package IronOcr.Languages.German
dotnet add package IronOcr.Languages.ChineseSimplified
# Remove filesystem dependency for each language
# Add NuGet package instead
dotnet add package IronOcr.Languages.French
dotnet add package IronOcr.Languages.German
dotnet add package IronOcr.Languages.ChineseSimplified
다중 언어 가이드는 주 및 보조 언어가 IronTesseract 인스턴스에 지정된 다중 언어 문서의 구성을 다룹니다.
IronOCR의 추가 기능
이 비교에서 다룬 영역 외에도IronOCR순수 OCR 컨텍스트에서 GdPicture에 직접적으로 상응하는 기능이 없는 기능들이 포함되어 있습니다.
- 비동기 OCR — ASP.NET Core 요청 처리기 및 백그라운드 서비스에서의 논블로킹 작동을 위한
ReadAsync - 페이지 회전 감지 — 수동 전처리 없이 회전된 페이지를 자동으로 감지하고 수정합니다.
- 진행 상황 추적 — 장시간 실행되는 배치 작업에 대한 콜백 기반 진행 이벤트를 UI 진행률 표시줄에 표시합니다.
- 스트림 입력 —
input.LoadImage(stream)이System.IO.Stream을 직접 수락하며, 파이프라인 아키텍처에서 임시 파일 작성 회피 - 특수 문서 읽기 — 여권, 번호판, MICR 수표 및 같은
IronTesseract인터페이스를 통해 작성된 핸드링
.NET 호환성 및 미래 준비
IronOCR .NET 8, .NET 9, .NET Standard 2.0 및 .NET Framework 4.6.2 이상을 대상으로 합니다. 이 단일 NuGet 패키지는 Windows x64, Windows x86, Linuxx64 및 macOS에 동일하게 배포됩니다. GdPicture .NET 은 크로스 플랫폼 대상을 지원하지만, 플러그인 아키텍처로 인해 Linux및 컨테이너 배포 시에는 각 플러그인의 네이티브 종속성을 개별적으로 고려해야 합니다. IronOCR의 네임스페이스는 모든 주요 버전 변경에서 IronOcr를 유지하여 업그레이드 경로가 코드베이스 전체 찾기 대체를 요구하지 않습니다. .NET 10이 2026년 말에 출시됨에 따라, IronOCR은 API 변경 없이 연속적인 .NET 릴리스 전반에 걸쳐 호환성을 유지해 온 실적을 바탕으로 유지 관리 주기가 긴 애플리케이션에 안정적인 기반을 제공합니다.
결론
GdPicture .NET 은 스캐너 통합, PDF 편집, 주석 달기, DICOM 지원 및 OCR 기능을 하나의 SDK에서 한 공급업체로부터 제공받는 통합 문서 이미지 처리 플랫폼이 필요한 팀에게 적합한 선택입니다. 그러한 사용 사례는 존재합니다. 플러그인 모델은 그러한 기능 대부분이 실제로 적용 가능한 범위 내에 있을 때 유용합니다.
요구 사항이 OCR인데 응답이 GdPicture일 때 불일치가 발생합니다. PDF 플러그인은 OCR을 이용한 PDF 데이터 추출 사용 사례와 분리할 수 없습니다. 문서 이미지 처리 플러그인은 전처리 과정과 분리할 수 없습니다. 정수 ID 수명 주기는 선택 사항이 아닙니다. 이는 전체 SDK의 기본 리소스 관리 모델입니다. 스캔한 PDF에서 텍스트를 추출해야 하는 팀은 이러한 모든 복잡성과 비용을 감수해야 하며, 추가 기능 중 어느 것도 그들의 업무량에 비해 그만한 가치가 없습니다.
다년간에 걸친 가격 차이는 단일 개발자 Professional 워크플로에 상당할 수 있습니다. 코드 복잡성 차이는 측정 가능합니다. 기본 OCR에 정리 작업을 포함하면 25줄 이상이 필요한 반면, 이 경우에는 단 한 줄만 필요합니다. 운영상의 격차, 즉 외부 리소스 폴더, 버전별 네임스페이스, 다중 구성 요소 초기화는 코드 줄 수보다는 배포 마찰과 온보딩 시간으로 나타나지만, 실제로 존재하는 문제입니다.
IronOCR를 $2,999 영구적으로 통해 동일한 핵심 OCR 결과 — 이미지 텍스트 추출, 스캔된 PDF 처리, 검색 가능한 PDF 출력, 125개 이상의 언어, 신뢰도 스코어링, 구조화된 데이터 접근 — 원칙으로 보장합니다. 표준 .NET 패턴으로서 유지 관리에 전문적인 SDK 지식이 필요하지 않습니다. OCR이 목적이지, 더 광범위한 문서 관리 플랫폼의 구성 요소가 아닌 팀의 경우, 이 방식이 더 적합합니다.
자주 묻는 질문
GdPicture.NET OCR이란 무엇인가요?
GdPicture.NET OCR은 개발자와 기업에서 이미지와 문서에서 텍스트를 추출하는 데 사용하는 OCR 솔루션입니다. 이 솔루션은 .NET 애플리케이션 개발을 위해 IronOCR과 함께 평가된 여러 OCR 옵션 중 하나입니다.
IronOCR은 .NET 개발자를 위한 GdPicture.NET OCR과 어떻게 비교되나요?
IronOCR은 IronTesseract를 핵심 엔진으로 사용하는 NuGet 네이티브 .NET OCR 라이브러리입니다. GdPicture.NET OCR에 비해 배포가 간편하고(SDK 설치 프로그램 없음), 정액제 요금이 적용되며, COM 인터롭이나 클라우드 종속성이 없는 깔끔한 C# API를 제공합니다.
IronOCR이 GdPicture.NET OCR보다 설정이 더 쉬운가요?
IronOCR은 단일 NuGet 패키지를 통해 설치됩니다. SDK 설치 프로그램, 복사할 라이선스 파일, 등록할 COM 구성 요소 또는 관리해야 할 별도의 런타임 바이너리가 없습니다. 전체 OCR 엔진이 패키지에 번들로 제공됩니다.
GdPicture.NET OCR과 IronOCR 사이에는 어떤 정확도 차이가 있나요?
IronOCR은 표준 비즈니스 문서, 송장, 영수증, 스캔 양식에 대해 높은 인식 정확도를 달성합니다. 품질이 많이 저하된 문서나 일반적이지 않은 스크립트의 경우 정확도는 소스 품질에 따라 달라집니다. IronOCR에는 이미지 전처리 필터가 포함되어 있어 저품질 입력에 대한 인식률을 향상시킵니다.
IronOCR은 PDF 텍스트 추출을 지원하나요?
예. IronOCR은 한 번의 호출로 원본 PDF와 스캔한 PDF 이미지 모두에서 텍스트를 추출합니다. 또한 여러 페이지의 TIFF 파일, 이미지, 스트림도 지원합니다. 스캔한 PDF의 경우 OCR은 페이지별 결과 개체를 사용하여 페이지별로 적용됩니다.
GdPicture.NET OCR 라이선싱은 IronOCR과 어떻게 비교되나요?
IronOCR은 페이지당 또는 스캔당 요금이 없는 정액제 영구 라이선스를 사용합니다. 대량의 문서를 처리하는 조직은 문서 양에 관계없이 동일한 라이선스 비용을 지불합니다. 자세한 내용과 볼륨 가격은 IronOCR 라이선스 페이지에서 확인할 수 있습니다.
IronOCR 어떤 언어를 지원하나요?
IronOCR은 별도의 NuGet 언어 팩을 통해 127개 언어를 지원합니다. 언어를 추가하려면 '닷넷 추가 패키지 IronOcr.Languages.{Language}' 명령 하나만 있으면 됩니다. 수동으로 파일을 배치하거나 경로를 구성할 필요가 없습니다.
.NET 프로젝트에 IronOCR 설치하는 방법은 무엇인가요?
NuGet을 통해 설치합니다: 패키지 관리자 콘솔에서 '설치-패키지 IronOcr' 또는 CLI에서 '닷넷 추가 패키지 IronOcr'을 실행합니다. 추가 언어 팩도 같은 방법으로 설치됩니다. 기본 SDK 인스톨러가 필요하지 않습니다.
IronOCR은 GdPicture.NET과 달리 Docker 및 컨테이너화된 배포에 적합한가요?
예. IronOCR은 NuGet 패키지를 통해 Docker 컨테이너에서 작동합니다. 라이선스 키는 환경 변수를 통해 설정됩니다. OCR 엔진 자체에는 라이선스 파일, SDK 경로 또는 볼륨 마운트가 필요하지 않습니다.
GdPicture.NET과 비교하여 구매하기 전에 IronOCR을 사용해 볼 수 있나요?
예. IronOCR 평가판 모드는 문서를 처리하고 출력물에 워터마크 오버레이가 포함된 OCR 결과를 반환합니다. 라이선스를 구매하기 전에 자신의 문서에서 정확성을 확인할 수 있습니다.
IronOCR은 텍스트 추출과 함께 바코드 판독을 지원하나요?
IronOCR은 텍스트 추출과 OCR에 중점을 둡니다. 바코드 판독을 위해 Iron Software는 동반 라이브러리로 IronBarcode를 제공합니다. 두 가지 모두 개별적으로 또는 Iron Suite 번들의 일부로 사용할 수 있습니다.
GdPicture.NET OCR에서 IronOCR로 쉽게 마이그레이션할 수 있나요?
GdPicture.NET OCR에서 IronOCR로의 마이그레이션에는 일반적으로 초기화 시퀀스를 IronTesseract 인스턴스화로 대체하고, COM 수명 주기 관리를 제거하고, API 호출을 업데이트하는 작업이 포함됩니다. 대부분의 마이그레이션은 코드 복잡성을 크게 줄여줍니다.

