Dynamsoft OCR에서 IronOCR로 마이그레이션하기
이 가이드는 Dynamsoft Label Recognizer에서 IronOCR 로 마이그레이션하는 .NET 개발자를 위한 완벽한 마이그레이션 경로를 제공합니다. 이 문서에서는 NuGet 패키지 교체, 네임스페이스 업데이트, 라이선스 초기화, 그리고 일반적인 기능 비교와는 다른 시나리오에 대한 실용적인 코드 마이그레이션 예제를 다룹니다. 여기에는 템플릿 구성 제거, 런타임 설정 JSON 제거, 지역 정의 마이그레이션, 결과 구문 분석 간소화 등이 포함됩니다.
Dynamsoft OCR에서 마이그레이션해야 하는 이유는 무엇일까요?
Dynamsoft 라벨 인식기는 특정 목적에 특화된 소프트웨어입니다. 이러한 정밀도는 제한적인 환경에서는 효과적이지만, 애플리케이션 범위가 원래의 MRZ 또는 VIN 사용 사례를 넘어 확장되는 순간 문제가 발생합니다.
런타임 설정 JSON은 유지보수 표면입니다. 모든 Dynamsoft 인식 워크플로우는 매개변수 배열, 문자 모델 및 지역 참조를 선언하는 JSON 문서를 로딩하는 AppendSettingsFromString으로 시작합니다. 해당 JSON 템플릿은 별도의 배포 아티팩트이며, 바이너리에 컴파일되지 않습니다. Dynamsoft가 SDK 버전 간에 템플릿 스키마를 변경할 때 버전 관리, 배포 파이프라인 관리 및 수동 업데이트가 필요합니다. IronOCR는 설정 파일이 필요 없습니다: IronTesseract를 인스턴스화하고 .Read()를 호출하면 엔진이 자동으로 적절한 설정을 선택합니다.
연간 구독료가 누적됩니다. Dynamsoft 라벨 인식기 라이선스는 기기당 연간 599달러 이상입니다. 영구적인 선택권은 없습니다. 5개 장치로 구성된 처리 클러스터는 연간 2,995달러 이상이며, 이 예산에는 MRZ 및 구조화된 라벨 인식 기능만 포함됩니다. 바코드용 Dynamsoft Barcode Reader 또는 문서 가장자리 보정용 Dynamsoft Document Normalizer를 추가하면 연간 청구 금액이 제품 수량만큼 증가합니다. IronOCR의 Lite 라이선스는 $999 한 번으로 일반 OCR, 구조화된 레이블, 바코드, 네이티브 PDF, 검색 가능한 PDF 출력 및 125개 이상의 언어를 단일 패키지로 커버합니다.
지역 정의에는 JSON 템플릿이 필요합니다. Dynamsoft에서 인식 지역을 정의하려면 ReferenceRegionArray JSON 블록을 작성하고 LabelRecognizerParameterArray에서 참조하며 이미지 처리 시작 전 전체 문서를 로딩해야 합니다. IronOCR는 CropRectangle(x, y, width, height) 생성자 하나만 사용하여 OcrInput.LoadImage에 직접 전달합니다. 지역 변경은 JSON 문서 재분석이 아닌 숫자 하나만 수정하면 됩니다.
결과 파싱은 전적으로 당신의 책임입니다. RecognizeFile 및 RecognizeByFile은 원시 텍스트 문자열이 포함된 LineResult 배열을 반환합니다. 필드 오프셋, 날짜 변환, 검사 숫자 유효성 검사, 이름 구분 기호 처리 등 필요한 모든 구조를 생성하려면 원시 출력 위에 사용자 지정 구문 분석 코드를 추가해야 합니다. IronOCR는 OcrResult를 반환하며, 이는 바운딩 박스 좌표, 신뢰도 점수, 폰트 메타데이터가 이미 채워진 상태의 .Pages, .Lines, .Words, .Characters을 포함한 타이핑된 컬렉션입니다.
PDF를 기본적으로 지원하지 않아 숨겨진 종속성이 발생합니다. Dynamsoft Label Recognizer는 PDF 입력 기능을 제공하지 않습니다. 처리 파이프라인에 들어오는 모든 PDF 파일은 첫 번째 Dynamsoft 호출 전에 각 페이지를 비트맵으로 렌더링하는 외부 라이브러리, 페이지 반복 루프 및 결과 집계 단계를 거쳐야 합니다. IronOCR는 PDF를 네이티브로 읽습니다: new IronTesseract().Read("document.pdf")는 보조 의존성, 렌더링 루프, 임시 이미지 폴더 없이 모든 페이지를 처리합니다.
다중 제품 초기화 블록은 범위에 따라 성장합니다. 구조화된 라벨, 바코드, 문서 표준화를 처리하는 Dynamsoft 응용 프로그램은 시작 시 세 개의 고정 InitLicense 호출을 하며, 세 개의 폐기 체인과 독립적인 SDK 버전 종속성을 가집니다. SDK를 업그레이드한다는 것은 모든 제품에 걸쳐 조정이 필요하다는 것을 의미합니다.IronOCR애플리케이션이 어떤 기능을 사용하든 관계없이 초기화 라인 하나와 패키지 버전 하나만 가지고 있습니다.
근본적인 문제
Dynamsoft는 인식 작업을 시작하기 전에 런타임에 로드되는 JSON 구성 파일이 필요합니다.
// Dynamsoft: JSON template required before any image processing
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
string settings = @"{
""LabelRecognizerParameterArray"": [{
""Name"": ""VIN_Label"",
""ReferenceRegionNameArray"": [""VinRegion""],
""CharacterModelName"": ""VIN""
}],
""ReferenceRegionArray"": [{
""Name"": ""VinRegion"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [5, 40],
""SecondPoint"": [95, 40],
""ThirdPoint"": [95, 60],
""FourthPoint"": [5, 60]
}
}]
}";
recognizer.AppendSettingsFromString(settings); // fails silently if JSON is malformed
var results = recognizer.RecognizeFile(imagePath);
// Dynamsoft: JSON template required before any image processing
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
string settings = @"{
""LabelRecognizerParameterArray"": [{
""Name"": ""VIN_Label"",
""ReferenceRegionNameArray"": [""VinRegion""],
""CharacterModelName"": ""VIN""
}],
""ReferenceRegionArray"": [{
""Name"": ""VinRegion"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [5, 40],
""SecondPoint"": [95, 40],
""ThirdPoint"": [95, 60],
""FourthPoint"": [5, 60]
}
}]
}";
recognizer.AppendSettingsFromString(settings); // fails silently if JSON is malformed
var results = recognizer.RecognizeFile(imagePath);
' Dynamsoft: JSON template required before any image processing
LabelRecognizer.InitLicense(licenseKey)
Dim recognizer As New LabelRecognizer()
Dim settings As String = "{
""LabelRecognizerParameterArray"": [{
""Name"": ""VIN_Label"",
""ReferenceRegionNameArray"": [""VinRegion""],
""CharacterModelName"": ""VIN""
}],
""ReferenceRegionArray"": [{
""Name"": ""VinRegion"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [5, 40],
""SecondPoint"": [95, 40],
""ThirdPoint"": [95, 60],
""FourthPoint"": [5, 60]
}
}]
}"
recognizer.AppendSettingsFromString(settings) ' fails silently if JSON is malformed
Dim results = recognizer.RecognizeFile(imagePath)
// IronOCR: no JSON, no template files — region is a constructor argument
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var region = new CropRectangle(x: 50, y: 400, width: 900, height: 200);
using var input = new OcrInput();
input.LoadImage(imagePath, region);
var result = new IronTesseract().Read(input);
Console.WriteLine(result.Text);
// IronOCR: no JSON, no template files — region is a constructor argument
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var region = new CropRectangle(x: 50, y: 400, width: 900, height: 200);
using var input = new OcrInput();
input.LoadImage(imagePath, region);
var result = new IronTesseract().Read(input);
Console.WriteLine(result.Text);
Imports IronOcr
' IronOCR: no JSON, no template files — region is a constructor argument
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim region As New CropRectangle(x:=50, y:=400, width:=900, height:=200)
Using input As New OcrInput()
input.LoadImage(imagePath, region)
Dim result = New IronTesseract().Read(input)
Console.WriteLine(result.Text)
End Using
IronOCR과 Dynamsoft OCR: 기능 비교
아래 표는 두 라이브러리 간의 전체 기능 차이를 보여줍니다.
| 기능 | Dynamsoft 라벨 인식기 | IronOCR |
|---|---|---|
| 일반 문서 OCR | 지원되지 않음 | 전체 지원 |
| MRZ 인식 | 특수화된 (원시 텍스트 출력) | 구조화된 필드가 내장되어 있습니다. |
| VIN 인식 | 특수형 (템플릿 필요) | 영역 타겟팅을 사용한 표준 OCR |
| 산업 라벨 판독 | 특수형 (템플릿 필요) | 예, CropRectangle 통해 |
| 런타임 설정 구성 | 필수 (JSON AppendSettingsFromString 통해) |
필요하지 않음 |
| 템플릿 배포 아티팩트 | 필수 (JSON 파일) | None |
| 네이티브 PDF 입력 | 지원되지 않음 | 예 |
| 비밀번호로 보호된 PDF | 지원되지 않음 | 예 |
| 여러 페이지로 구성된 TIFF 입력 | 수동 페이지 반복 | 네이티브 (LoadImageFrames 통해) |
| 검색 가능한 PDF 출력 | 지원되지 않음 | 예 (SaveAsSearchablePdf 통해) |
| 바코드 판독 | 별도 제품 (다이나소프트 바코드 리더기) | 내장 (ReadBarCodes = true 통해) |
| 자동 전처리 | 제한적 | 예 (왜곡 제거, 노이즈 제거, 대비 제거, 이진화, 선명도 향상, 팽창, 침식) |
| 구조화된 출력 (단어, 줄, 단락) | 원시 LineResult 텍스트 문자열 |
좌표 및 신뢰도를 포함하여 완벽하게 입력되었습니다. |
| 언어 지원 | 리미티드(라틴어 MRZ) | 125개 이상의 언어를 NuGet 패키지로 제공합니다. |
| 다국어 동시 | 지원되지 않음 | 예 (OcrLanguage.French + OcrLanguage.German 통해) |
| 신뢰도 점수 | 줄 단위로만 | 단어당, 줄당, 페이지당 |
| hOCR 내보내기 | 지원되지 않음 | 예 |
| 라이센싱 모델 | 연간 구독료(기기당 연간 $599 이상) | 영구 ($999 한 번, Lite tier) |
| 여러 제품이 필요합니다 | 예 (완벽한 보장을 위해서는 3개 이상 필요) | 아니요 (1개 패키지) |
| .NET Framework 지원 | .NET Framework 4.x 이상 | .NET Framework 4.6.2 이상, .NET 5/6/7/8/9 |
| 크로스 플랫폼 배포 | 예 | 예 (Windows, Linux, macOS, Docker, Azure, AWS) |
| NuGet 패키지 | Dynamsoft.LabelRecognizer |
IronOcr |
빠른 시작: Dynamsoft OCR에서IronOCR로 마이그레이션
1단계: NuGet 패키지 교체
Dynamsoft 패키지를 제거하세요.
dotnet remove package Dynamsoft.LabelRecognizer
dotnet remove package Dynamsoft.LabelRecognizer
NuGet 갤러리 에서IronOCR설치하세요.
dotnet add package IronOcr
단계 2: 네임스페이스 업데이트
// Before (Dynamsoft)
using Dynamsoft.LabelRecognizer;
using Dynamsoft.Core;
// After (IronOCR)
using IronOcr;
// Before (Dynamsoft)
using Dynamsoft.LabelRecognizer;
using Dynamsoft.Core;
// After (IronOCR)
using IronOcr;
Imports IronOcr
단계 3: 라이선스 초기화
각 Dynamsoft 고정 InitLicense 호출을 응용 프로그램 시작 시IronOCR라이선스 할당으로 대체하십시오:
// Before (Dynamsoft — one call per product)
LabelRecognizer.InitLicense("DYNAMSOFT-LICENSE-KEY");
// After (IronOCR — one line, all features)
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Before (Dynamsoft — one call per product)
LabelRecognizer.InitLicense("DYNAMSOFT-LICENSE-KEY");
// After (IronOCR — one line, all features)
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
' Before (Dynamsoft — one call per product)
LabelRecognizer.InitLicense("DYNAMSOFT-LICENSE-KEY")
' After (IronOCR — one line, all features)
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
코드 마이그레이션 예제
템플릿 기반 인식에서 제로 구성 엔진으로
Dynamsoft의 JSON 템플릿 시스템은 이미지를 처리하기 전에 SDK에 문자 모델, 영역 사양 및 인식 매개변수에 대한 자세한 지침을 제공합니다. 대부분의 실제 OCR 작업 부하에서 해당 구성은 인식 이점 없이 설정 복잡성만 증가시킵니다. 기본 Tesseract 엔진이 레이아웃 감지를 자동으로 처리하기 때문입니다.
Dynamsoft 접근 방식:
using Dynamsoft.LabelRecognizer;
using Dynamsoft.Core;
// JSON template required before recognition
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
string invoiceTemplate = @"{
""LabelRecognizerParameterArray"": [{
""Name"": ""Invoice_Header"",
""ReferenceRegionNameArray"": [""HeaderRegion""],
""CharacterModelName"": ""NumberLetter""
}],
""ReferenceRegionArray"": [{
""Name"": ""HeaderRegion"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [0, 0],
""SecondPoint"": [100, 0],
""ThirdPoint"": [100, 20],
""FourthPoint"": [0, 20]
}
}]
}";
recognizer.AppendSettingsFromString(invoiceTemplate);
var results = recognizer.RecognizeFile("invoice.jpg");
var headerText = new StringBuilder();
foreach (var result in results)
foreach (var line in result.LineResults)
headerText.AppendLine(line.Text);
Console.WriteLine(headerText.ToString());
recognizer.Dispose();
using Dynamsoft.LabelRecognizer;
using Dynamsoft.Core;
// JSON template required before recognition
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
string invoiceTemplate = @"{
""LabelRecognizerParameterArray"": [{
""Name"": ""Invoice_Header"",
""ReferenceRegionNameArray"": [""HeaderRegion""],
""CharacterModelName"": ""NumberLetter""
}],
""ReferenceRegionArray"": [{
""Name"": ""HeaderRegion"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [0, 0],
""SecondPoint"": [100, 0],
""ThirdPoint"": [100, 20],
""FourthPoint"": [0, 20]
}
}]
}";
recognizer.AppendSettingsFromString(invoiceTemplate);
var results = recognizer.RecognizeFile("invoice.jpg");
var headerText = new StringBuilder();
foreach (var result in results)
foreach (var line in result.LineResults)
headerText.AppendLine(line.Text);
Console.WriteLine(headerText.ToString());
recognizer.Dispose();
Imports Dynamsoft.LabelRecognizer
Imports Dynamsoft.Core
Imports System.Text
' JSON template required before recognition
LabelRecognizer.InitLicense(licenseKey)
Dim recognizer As New LabelRecognizer()
Dim invoiceTemplate As String = "{
""LabelRecognizerParameterArray"": [{
""Name"": ""Invoice_Header"",
""ReferenceRegionNameArray"": [""HeaderRegion""],
""CharacterModelName"": ""NumberLetter""
}],
""ReferenceRegionArray"": [{
""Name"": ""HeaderRegion"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [0, 0],
""SecondPoint"": [100, 0],
""ThirdPoint"": [100, 20],
""FourthPoint"": [0, 20]
}
}]
}"
recognizer.AppendSettingsFromString(invoiceTemplate)
Dim results = recognizer.RecognizeFile("invoice.jpg")
Dim headerText As New StringBuilder()
For Each result In results
For Each line In result.LineResults
headerText.AppendLine(line.Text)
Next
Next
Console.WriteLine(headerText.ToString())
recognizer.Dispose()
IronOCR 접근 방식:
using IronOcr;
// No template file — region specified inline, engine auto-configures
var region = new CropRectangle(x: 0, y: 0, width: 1200, height: 200);
using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);
input.Deskew();
var result = new IronTesseract().Read(input);
Console.WriteLine(result.Text);
Console.WriteLine($"Confidence: {result.Confidence}%");
using IronOcr;
// No template file — region specified inline, engine auto-configures
var region = new CropRectangle(x: 0, y: 0, width: 1200, height: 200);
using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);
input.Deskew();
var result = new IronTesseract().Read(input);
Console.WriteLine(result.Text);
Console.WriteLine($"Confidence: {result.Confidence}%");
Imports IronOcr
' No template file — region specified inline, engine auto-configures
Dim region As New CropRectangle(x:=0, y:=0, width:=1200, height:=200)
Using input As New OcrInput()
input.LoadImage("invoice.jpg", region)
input.Deskew()
Dim result = New IronTesseract().Read(input)
Console.WriteLine(result.Text)
Console.WriteLine($"Confidence: {result.Confidence}%")
End Using
Dynamsoft 방식은 이미지를 처리하기 전에 JSON 템플릿을 작성, 검증 및 배포해야 합니다. AppendSettingsFromString의 오타는 런타임에 빈 결과를 반환합니다 — 컴파일 시간 유효성 검사가 없습니다. IronOCR의 CropRectangle는 평범한 생성자입니다: 컴파일 시간 타입 체크, 외부 파일 없음, 배포 아티팩트 없음. 모든 타겟팅 패턴에 대한 자세한 내용은 지역 기반 OCR 가이드를 참조하십시오.
지역 마이그레이션을 포함한 VIN 코드 스캔
차량 식별 번호 추출은 Dynamsoft Label Recognizer의 특기입니다. 해당 VIN 템플릿 모델은 특정 17자리 영숫자 형식에 최적화되어 있습니다.IronOCR로 마이그레이션하면 템플릿 모델이 전처리 파이프라인 및 영역 타겟팅으로 대체되어 문자 모델 구성 없이도 동일한 VIN 플레이트 조건을 처리할 수 있습니다.
Dynamsoft 접근 방식:
using Dynamsoft.LabelRecognizer;
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
// VIN requires a specific character model and region configuration
string vinTemplate = @"{
""LabelRecognizerParameterArray"": [{
""Name"": ""VIN_Scan"",
""ReferenceRegionNameArray"": [""VIN_Zone""],
""CharacterModelName"": ""VIN""
}],
""ReferenceRegionArray"": [{
""Name"": ""VIN_Zone"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [10, 35],
""SecondPoint"": [90, 35],
""ThirdPoint"": [90, 65],
""FourthPoint"": [10, 65]
}
}]
}";
recognizer.AppendSettingsFromString(vinTemplate);
var results = recognizer.RecognizeFile("vehicle-vin.jpg");
string rawVin = results
.SelectMany(r => r.LineResults)
.Select(l => l.Text)
.FirstOrDefault() ?? string.Empty;
Console.WriteLine($"Raw VIN text: {rawVin}"); // still requires validation
recognizer.Dispose();
using Dynamsoft.LabelRecognizer;
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
// VIN requires a specific character model and region configuration
string vinTemplate = @"{
""LabelRecognizerParameterArray"": [{
""Name"": ""VIN_Scan"",
""ReferenceRegionNameArray"": [""VIN_Zone""],
""CharacterModelName"": ""VIN""
}],
""ReferenceRegionArray"": [{
""Name"": ""VIN_Zone"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [10, 35],
""SecondPoint"": [90, 35],
""ThirdPoint"": [90, 65],
""FourthPoint"": [10, 65]
}
}]
}";
recognizer.AppendSettingsFromString(vinTemplate);
var results = recognizer.RecognizeFile("vehicle-vin.jpg");
string rawVin = results
.SelectMany(r => r.LineResults)
.Select(l => l.Text)
.FirstOrDefault() ?? string.Empty;
Console.WriteLine($"Raw VIN text: {rawVin}"); // still requires validation
recognizer.Dispose();
Imports Dynamsoft.LabelRecognizer
LabelRecognizer.InitLicense(licenseKey)
Dim recognizer As New LabelRecognizer()
' VIN requires a specific character model and region configuration
Dim vinTemplate As String = "{
""LabelRecognizerParameterArray"": [{
""Name"": ""VIN_Scan"",
""ReferenceRegionNameArray"": [""VIN_Zone""],
""CharacterModelName"": ""VIN""
}],
""ReferenceRegionArray"": [{
""Name"": ""VIN_Zone"",
""Localization"": {
""SourceType"": ""LST_MANUAL_SPECIFICATION"",
""FirstPoint"": [10, 35],
""SecondPoint"": [90, 35],
""ThirdPoint"": [90, 65],
""FourthPoint"": [10, 65]
}
}]
}"
recognizer.AppendSettingsFromString(vinTemplate)
Dim results = recognizer.RecognizeFile("vehicle-vin.jpg")
Dim rawVin As String = results _
.SelectMany(Function(r) r.LineResults) _
.Select(Function(l) l.Text) _
.FirstOrDefault() OrElse String.Empty
Console.WriteLine($"Raw VIN text: {rawVin}") ' still requires validation
recognizer.Dispose()
IronOCR 접근 방식:
using IronOcr;
using System.Text.RegularExpressions;
// Target the VIN plate region directly — no template file
var vinRegion = new CropRectangle(x: 100, y: 350, width: 800, height: 300);
using var input = new OcrInput();
input.LoadImage("vehicle-vin.jpg", vinRegion);
input.Contrast(); // recover faded stamped digits
input.Sharpen(); // clarify character boundaries on embossed plates
var result = new IronTesseract().Read(input);
// VIN: 17 chars, no I/O/Q
var vinMatch = Regex.Match(result.Text, @"\b[A-HJ-NPR-Z0-9]{17}\b");
string vin = vinMatch.Success ? vinMatch.Value : result.Text.Trim();
Console.WriteLine($"VIN: {vin}");
Console.WriteLine($"Confidence: {result.Confidence}%");
using IronOcr;
using System.Text.RegularExpressions;
// Target the VIN plate region directly — no template file
var vinRegion = new CropRectangle(x: 100, y: 350, width: 800, height: 300);
using var input = new OcrInput();
input.LoadImage("vehicle-vin.jpg", vinRegion);
input.Contrast(); // recover faded stamped digits
input.Sharpen(); // clarify character boundaries on embossed plates
var result = new IronTesseract().Read(input);
// VIN: 17 chars, no I/O/Q
var vinMatch = Regex.Match(result.Text, @"\b[A-HJ-NPR-Z0-9]{17}\b");
string vin = vinMatch.Success ? vinMatch.Value : result.Text.Trim();
Console.WriteLine($"VIN: {vin}");
Console.WriteLine($"Confidence: {result.Confidence}%");
Imports IronOcr
Imports System.Text.RegularExpressions
' Target the VIN plate region directly — no template file
Dim vinRegion As New CropRectangle(x:=100, y:=350, width:=800, height:=300)
Using input As New OcrInput()
input.LoadImage("vehicle-vin.jpg", vinRegion)
input.Contrast() ' recover faded stamped digits
input.Sharpen() ' clarify character boundaries on embossed plates
Dim result = New IronTesseract().Read(input)
' VIN: 17 chars, no I/O/Q
Dim vinMatch = Regex.Match(result.Text, "\b[A-HJ-NPR-Z0-9]{17}\b")
Dim vin As String = If(vinMatch.Success, vinMatch.Value, result.Text.Trim())
Console.WriteLine($"VIN: {vin}")
Console.WriteLine($"Confidence: {result.Confidence}%")
End Using
CropRectangle 좌표는 Dynamsoft의 백분율 기반 SecondPoint 사양과 동일한 픽셀 참조 프레임을 사용합니다 — Dynamsoft의 백분율 값을 이미지 크기에 곱하여 변환하십시오. 전처리 파이프라인 (Contrast, Sharpen)은 Dynamsoft가 VIN 템플릿에 내장한 문자 모델 최적화를 대체합니다. 이미지 품질 보정 가이드는 양각 표면 및 저대비 표면에 적합한 필터 선택에 대해 다룹니다.
다중 페이지 TIFF 일괄 처리
Dynamsoft Label Recognizer는 단일 이미지를 처리합니다. 문서 관리 시스템, 의료 영상 아카이브 및 팩스 파이프라인에서 흔히 사용되는 여러 페이지로 구성된 TIFF 문서는 외부 반복 처리가 필요합니다. 즉, 각 프레임을 로드하고, 개별적으로 인식기를 통과시키고, 결과를 취합해야 합니다. IronOCR는 LoadImageFrames를 통해 다중 프레임 TIFF를 네이티브로 처리합니다.
Dynamsoft 접근 방식:
using Dynamsoft.LabelRecognizer;
// Requires an external TIFF library to extract frames
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(genericTemplate);
// External library needed to iterate TIFF frames
var tiffImage = System.Drawing.Image.FromFile("scanned-batch.tiff");
int frameCount = tiffImage.GetFrameCount(
System.Drawing.Imaging.FrameDimension.Page);
var allText = new StringBuilder();
for (int i = 0; i < frameCount; i++)
{
tiffImage.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
string tempPath = $"frame_{i}.jpg";
tiffImage.Save(tempPath, System.Drawing.Imaging.ImageFormat.Jpeg);
var results = recognizer.RecognizeFile(tempPath);
foreach (var r in results)
foreach (var line in r.LineResults)
allText.AppendLine(line.Text);
System.IO.File.Delete(tempPath); // clean up temp files
}
Console.WriteLine(allText.ToString());
recognizer.Dispose();
using Dynamsoft.LabelRecognizer;
// Requires an external TIFF library to extract frames
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(genericTemplate);
// External library needed to iterate TIFF frames
var tiffImage = System.Drawing.Image.FromFile("scanned-batch.tiff");
int frameCount = tiffImage.GetFrameCount(
System.Drawing.Imaging.FrameDimension.Page);
var allText = new StringBuilder();
for (int i = 0; i < frameCount; i++)
{
tiffImage.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
string tempPath = $"frame_{i}.jpg";
tiffImage.Save(tempPath, System.Drawing.Imaging.ImageFormat.Jpeg);
var results = recognizer.RecognizeFile(tempPath);
foreach (var r in results)
foreach (var line in r.LineResults)
allText.AppendLine(line.Text);
System.IO.File.Delete(tempPath); // clean up temp files
}
Console.WriteLine(allText.ToString());
recognizer.Dispose();
Imports Dynamsoft.LabelRecognizer
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Imports System.Text
' Requires an external TIFF library to extract frames
LabelRecognizer.InitLicense(licenseKey)
Dim recognizer As New LabelRecognizer()
recognizer.AppendSettingsFromString(genericTemplate)
' External library needed to iterate TIFF frames
Dim tiffImage As Image = Image.FromFile("scanned-batch.tiff")
Dim frameCount As Integer = tiffImage.GetFrameCount(FrameDimension.Page)
Dim allText As New StringBuilder()
For i As Integer = 0 To frameCount - 1
tiffImage.SelectActiveFrame(FrameDimension.Page, i)
Dim tempPath As String = $"frame_{i}.jpg"
tiffImage.Save(tempPath, Imaging.ImageFormat.Jpeg)
Dim results = recognizer.RecognizeFile(tempPath)
For Each r In results
For Each line In r.LineResults
allText.AppendLine(line.Text)
Next
Next
File.Delete(tempPath) ' clean up temp files
Next
Console.WriteLine(allText.ToString())
recognizer.Dispose()
IronOCR 접근 방식:
using IronOcr;
// No frame iteration, no temp files, no external TIFF library
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff"); // loads all frames natively
input.Deskew();
input.DeNoise();
var ocr = new IronTesseract();
var result = ocr.Read(input);
// Results organized per page
foreach (var page in result.Pages)
{
Console.WriteLine($"Frame {page.PageNumber}: {page.Lines.Count} lines");
Console.WriteLine(page.Text);
}
// Save entire batch as a single searchable PDF
result.SaveAsSearchablePdf("batch-searchable.pdf");
using IronOcr;
// No frame iteration, no temp files, no external TIFF library
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff"); // loads all frames natively
input.Deskew();
input.DeNoise();
var ocr = new IronTesseract();
var result = ocr.Read(input);
// Results organized per page
foreach (var page in result.Pages)
{
Console.WriteLine($"Frame {page.PageNumber}: {page.Lines.Count} lines");
Console.WriteLine(page.Text);
}
// Save entire batch as a single searchable PDF
result.SaveAsSearchablePdf("batch-searchable.pdf");
Imports IronOcr
' No frame iteration, no temp files, no external TIFF library
Using input As New OcrInput()
input.LoadImageFrames("scanned-batch.tiff") ' loads all frames natively
input.Deskew()
input.DeNoise()
Dim ocr As New IronTesseract()
Dim result = ocr.Read(input)
' Results organized per page
For Each page In result.Pages
Console.WriteLine($"Frame {page.PageNumber}: {page.Lines.Count} lines")
Console.WriteLine(page.Text)
Next
' Save entire batch as a single searchable PDF
result.SaveAsSearchablePdf("batch-searchable.pdf")
End Using
Dynamsoft 접근 방식은 각 프레임 추출을 위해 System.Drawing가 필요하며, 디스크에 프레임당 임시 파일이 필요하고, 각 통과 후 수동 정리가 필요합니다. IronOCR의 LoadImageFrames는 한 번의 호출로 모든 프레임을 읽습니다 — 임시 파일 없음, 프레임 인덱스 추적 없음. OCR 후, SaveAsSearchablePdf는 전체 배치를 검색 가능한 문서로 한 번의 메서드 호출로 보관합니다. 다중 프레임 TIFF 가이드 와 검색 가능한 PDF 출력 가이드 는 두 가지 기능 모두를 자세히 다룹니다.
구조화된 단어 수준 결과 구문 분석
Dynamsoft RecognizeFile는 DLRResult 배열을 반환합니다. 각 DLRResult는 LineResults 객체의 DLRLineResult 컬렉션을 포함하며 Text 속성과 바운딩 사변형을 가지고 있는 Location 속성을 가지고 있습니다. 단어 수준의 위치를 추출하려면 공백을 기준으로 줄의 텍스트를 분할하고 줄 경계 상자를 비례적으로 나누어야 하는데, 이 근사치는 비례 글꼴에서는 제대로 작동하지 않습니다. IronOCR는 모든 OcrResult.Word 객체에서 단어 수준 바운딩 박스를 타이핑된 속성으로 노출합니다.
Dynamsoft 접근 방식:
using Dynamsoft.LabelRecognizer;
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(settingsJson);
var results = recognizer.RecognizeFile("form-scan.jpg");
foreach (var dlrResult in results)
{
foreach (var lineResult in dlrResult.LineResults)
{
// Line-level data only — word boundaries are not provided
Console.WriteLine($"Text: {lineResult.Text}");
Console.WriteLine($"Confidence: {lineResult.Confidence}");
// Location is a quadrilateral — four corner points
var loc = lineResult.Location;
Console.WriteLine($"Top-left: ({loc.Points[0].X}, {loc.Points[0].Y})");
// To get word positions: split text and divide bounding box manually
var words = lineResult.Text.Split(' ');
int approxWidth = (loc.Points[1].X - loc.Points[0].X) / words.Length;
for (int i = 0; i < words.Length; i++)
{
int wordX = loc.Points[0].X + (i * approxWidth);
Console.WriteLine($" Word '{words[i]}' approx at x={wordX}");
}
}
}
recognizer.Dispose();
using Dynamsoft.LabelRecognizer;
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(settingsJson);
var results = recognizer.RecognizeFile("form-scan.jpg");
foreach (var dlrResult in results)
{
foreach (var lineResult in dlrResult.LineResults)
{
// Line-level data only — word boundaries are not provided
Console.WriteLine($"Text: {lineResult.Text}");
Console.WriteLine($"Confidence: {lineResult.Confidence}");
// Location is a quadrilateral — four corner points
var loc = lineResult.Location;
Console.WriteLine($"Top-left: ({loc.Points[0].X}, {loc.Points[0].Y})");
// To get word positions: split text and divide bounding box manually
var words = lineResult.Text.Split(' ');
int approxWidth = (loc.Points[1].X - loc.Points[0].X) / words.Length;
for (int i = 0; i < words.Length; i++)
{
int wordX = loc.Points[0].X + (i * approxWidth);
Console.WriteLine($" Word '{words[i]}' approx at x={wordX}");
}
}
}
recognizer.Dispose();
Imports Dynamsoft.LabelRecognizer
LabelRecognizer.InitLicense(licenseKey)
Dim recognizer As New LabelRecognizer()
recognizer.AppendSettingsFromString(settingsJson)
Dim results = recognizer.RecognizeFile("form-scan.jpg")
For Each dlrResult In results
For Each lineResult In dlrResult.LineResults
' Line-level data only — word boundaries are not provided
Console.WriteLine($"Text: {lineResult.Text}")
Console.WriteLine($"Confidence: {lineResult.Confidence}")
' Location is a quadrilateral — four corner points
Dim loc = lineResult.Location
Console.WriteLine($"Top-left: ({loc.Points(0).X}, {loc.Points(0).Y})")
' To get word positions: split text and divide bounding box manually
Dim words = lineResult.Text.Split(" "c)
Dim approxWidth As Integer = (loc.Points(1).X - loc.Points(0).X) \ words.Length
For i As Integer = 0 To words.Length - 1
Dim wordX As Integer = loc.Points(0).X + (i * approxWidth)
Console.WriteLine($" Word '{words(i)}' approx at x={wordX}")
Next
Next
Next
recognizer.Dispose()
IronOCR 접근 방식:
using IronOcr;
var result = new IronTesseract().Read("form-scan.jpg");
// Word-level positions are first-class properties — no manual division
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}");
foreach (var line in paragraph.Lines)
{
foreach (var word in line.Words)
{
Console.WriteLine(
$" Word: '{word.Text}' " +
$"at ({word.X},{word.Y}) " +
$"size {word.Width}x{word.Height} " +
$"confidence {word.Confidence}%");
}
}
}
}
using IronOcr;
var result = new IronTesseract().Read("form-scan.jpg");
// Word-level positions are first-class properties — no manual division
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}");
foreach (var line in paragraph.Lines)
{
foreach (var word in line.Words)
{
Console.WriteLine(
$" Word: '{word.Text}' " +
$"at ({word.X},{word.Y}) " +
$"size {word.Width}x{word.Height} " +
$"confidence {word.Confidence}%");
}
}
}
}
Imports IronOcr
Dim result = New IronTesseract().Read("form-scan.jpg")
' Word-level positions are first-class properties — no manual division
For Each page In result.Pages
For Each paragraph In page.Paragraphs
Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}")
For Each line In paragraph.Lines
For Each word In line.Words
Console.WriteLine(
$" Word: '{word.Text}' " &
$"at ({word.X},{word.Y}) " &
$"size {word.Width}x{word.Height} " &
$"confidence {word.Confidence}%")
Next
Next
Next
Next
IronOCR 진정한 계층 구조를 제공합니다. 페이지는 단락으로, 단락은 줄로, 줄은 단어로, 단어는 문자로 구성됩니다. 모든 레벨은 .X, .Y, .Width, .Height, .Confidence을 타이핑된 정수 및 더블 속성으로 노출합니다 — 사변형 좌표 산술이 필요 없습니다. 구조화된 결과 안내서는 접근 가능한 모든 속성을 문서화하고, 신뢰도 점수 안내서는 자동 문서 검토 파이프라인에 대한 신뢰도 임계값을 설명합니다.
대용량 라벨 스캔을 위한 비동기 병렬 처리
Dynamsoft 레이블 인식기는 스레드 안전하지만 RecognizeFile 호출은 동기적입니다. Task.Run으로 래핑하면 병렬 처리가 발생하지만, 각 호출은 AppendSettingsFromString를 통해 구성 상태를 공유합니다 — 여러 스레드에서 템플릿을 로드하려면 초기화 순서를 주의해야 합니다. IronOCR의 IronTesseract 인스턴스는 독립적입니다: 작업당 하나를 생성하고 Read를 호출하면 스레드 모델이 단순해집니다.
Dynamsoft 접근 방식:
using Dynamsoft.LabelRecognizer;
using System.Threading.Tasks;
// InitLicense must be called once before parallel work begins
LabelRecognizer.InitLicense(licenseKey);
// Each thread needs its own recognizer instance with its own template load
var results = new System.Collections.Concurrent.ConcurrentBag<string>();
await Task.WhenAll(imagePaths.Select(async path =>
{
// Cannot share recognizer instances safely across tasks
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(templateJson); // reload JSON per instance
await Task.Run(() =>
{
var dlrResults = recognizer.RecognizeFile(path);
var text = string.Join("\n",
dlrResults.SelectMany(r => r.LineResults).Select(l => l.Text));
results.Add(text);
});
recognizer.Dispose();
}));
Console.WriteLine($"Processed {results.Count} images");
using Dynamsoft.LabelRecognizer;
using System.Threading.Tasks;
// InitLicense must be called once before parallel work begins
LabelRecognizer.InitLicense(licenseKey);
// Each thread needs its own recognizer instance with its own template load
var results = new System.Collections.Concurrent.ConcurrentBag<string>();
await Task.WhenAll(imagePaths.Select(async path =>
{
// Cannot share recognizer instances safely across tasks
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(templateJson); // reload JSON per instance
await Task.Run(() =>
{
var dlrResults = recognizer.RecognizeFile(path);
var text = string.Join("\n",
dlrResults.SelectMany(r => r.LineResults).Select(l => l.Text));
results.Add(text);
});
recognizer.Dispose();
}));
Console.WriteLine($"Processed {results.Count} images");
Imports Dynamsoft.LabelRecognizer
Imports System.Threading.Tasks
Imports System.Collections.Concurrent
' InitLicense must be called once before parallel work begins
LabelRecognizer.InitLicense(licenseKey)
' Each thread needs its own recognizer instance with its own template load
Dim results As New ConcurrentBag(Of String)()
Await Task.WhenAll(imagePaths.Select(Async Function(path)
' Cannot share recognizer instances safely across tasks
Dim recognizer As New LabelRecognizer()
recognizer.AppendSettingsFromString(templateJson) ' reload JSON per instance
Await Task.Run(Sub()
Dim dlrResults = recognizer.RecognizeFile(path)
Dim text = String.Join(vbLf, dlrResults.SelectMany(Function(r) r.LineResults).Select(Function(l) l.Text))
results.Add(text)
End Sub)
recognizer.Dispose()
End Function))
Console.WriteLine($"Processed {results.Count} images")
IronOCR 접근 방식:
using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;
var extractedTexts = new ConcurrentDictionary<string, string>();
// Each IronTesseract instance is independent — no shared state
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
extractedTexts[imagePath] = result.Text;
});
foreach (var (path, text) in extractedTexts)
Console.WriteLine($"{System.IO.Path.GetFileName(path)}: {text.Length} characters");
using IronOcr;
using System.Collections.Concurrent;
using System.Threading.Tasks;
var extractedTexts = new ConcurrentDictionary<string, string>();
// Each IronTesseract instance is independent — no shared state
Parallel.ForEach(imagePaths, imagePath =>
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
extractedTexts[imagePath] = result.Text;
});
foreach (var (path, text) in extractedTexts)
Console.WriteLine($"{System.IO.Path.GetFileName(path)}: {text.Length} characters");
Imports IronOcr
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Dim extractedTexts As New ConcurrentDictionary(Of String, String)()
' Each IronTesseract instance is independent — no shared state
Parallel.ForEach(imagePaths, Sub(imagePath)
Dim ocr As New IronTesseract()
Dim result = ocr.Read(imagePath)
extractedTexts(imagePath) = result.Text
End Sub)
For Each kvp In extractedTexts
Dim path = kvp.Key
Dim text = kvp.Value
Console.WriteLine($"{System.IO.Path.GetFileName(path)}: {text.Length} characters")
Next
IronOCR 병렬 작업 시작 전에 초기화 순서를 요구하지 않습니다. 응용 프로그램 시작 시 IronOcr.License.LicenseKey 할당 한 번만으로 모든 인스턴스를 활성화합니다. 스레드별 템플릿 재로드가 없으며, 인스턴스별 JSON 유효성 검사도 없습니다. 비차단 서버측 시나리오의 경우, 비동기 OCR 가이드는 ASP.NET Core 및 Azure Functions를 위한 await 기반 패턴을 다룹니다.
스캔한 라벨 아카이브에서 검색 가능한 PDF 출력
Dynamsoft는 PDF 출력 기능을 전혀 지원하지 않습니다. Dynamsoft를 통해 처리된 스캔된 라벨 아카이브는 이미지 파일로만 남아 검색이 불가능하고 문서 관리 시스템에서 색인화할 수 없으며 PDF/A 아카이브 표준을 준수하지 않습니다. IronOCR는 OcrResult 객체에 단일 메서드 호출로 검색 가능한 PDF 출력을 추가합니다.
Dynamsoft 접근 방식:
using Dynamsoft.LabelRecognizer;
// Process scanned label — extract text into a string
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(labelTemplate);
var results = recognizer.RecognizeFile("scanned-labels.jpg");
var extractedText = new StringBuilder();
foreach (var r in results)
foreach (var line in r.LineResults)
extractedText.AppendLine(line.Text);
// Cannot create a searchable PDF — save text to a sidecar .txt file instead
System.IO.File.WriteAllText("scanned-labels.txt", extractedText.ToString());
// The original image remains unsearchable
Console.WriteLine("No PDF output available in Dynamsoft Label Recognizer.");
recognizer.Dispose();
using Dynamsoft.LabelRecognizer;
// Process scanned label — extract text into a string
LabelRecognizer.InitLicense(licenseKey);
var recognizer = new LabelRecognizer();
recognizer.AppendSettingsFromString(labelTemplate);
var results = recognizer.RecognizeFile("scanned-labels.jpg");
var extractedText = new StringBuilder();
foreach (var r in results)
foreach (var line in r.LineResults)
extractedText.AppendLine(line.Text);
// Cannot create a searchable PDF — save text to a sidecar .txt file instead
System.IO.File.WriteAllText("scanned-labels.txt", extractedText.ToString());
// The original image remains unsearchable
Console.WriteLine("No PDF output available in Dynamsoft Label Recognizer.");
recognizer.Dispose();
Imports Dynamsoft.LabelRecognizer
Imports System.IO
Imports System.Text
' Process scanned label — extract text into a string
LabelRecognizer.InitLicense(licenseKey)
Dim recognizer = New LabelRecognizer()
recognizer.AppendSettingsFromString(labelTemplate)
Dim results = recognizer.RecognizeFile("scanned-labels.jpg")
Dim extractedText = New StringBuilder()
For Each r In results
For Each line In r.LineResults
extractedText.AppendLine(line.Text)
Next
Next
' Cannot create a searchable PDF — save text to a sidecar .txt file instead
File.WriteAllText("scanned-labels.txt", extractedText.ToString())
' The original image remains unsearchable
Console.WriteLine("No PDF output available in Dynamsoft Label Recognizer.")
recognizer.Dispose()
IronOCR 접근 방식:
using IronOcr;
// Read, preprocess, and produce a searchable PDF archive in one pipeline
using var input = new OcrInput();
input.LoadImage("scanned-labels.jpg");
input.Deskew();
input.Contrast();
var ocr = new IronTesseract();
var result = ocr.Read(input);
// Searchable PDF: original image layer preserved, invisible text layer added
result.SaveAsSearchablePdf("scanned-labels-searchable.pdf");
Console.WriteLine($"Searchable PDF created. Confidence: {result.Confidence}%");
Console.WriteLine($"Extracted text preview: {result.Text.Substring(0, 100)}");
using IronOcr;
// Read, preprocess, and produce a searchable PDF archive in one pipeline
using var input = new OcrInput();
input.LoadImage("scanned-labels.jpg");
input.Deskew();
input.Contrast();
var ocr = new IronTesseract();
var result = ocr.Read(input);
// Searchable PDF: original image layer preserved, invisible text layer added
result.SaveAsSearchablePdf("scanned-labels-searchable.pdf");
Console.WriteLine($"Searchable PDF created. Confidence: {result.Confidence}%");
Console.WriteLine($"Extracted text preview: {result.Text.Substring(0, 100)}");
Imports IronOcr
' Read, preprocess, and produce a searchable PDF archive in one pipeline
Using input As New OcrInput()
input.LoadImage("scanned-labels.jpg")
input.Deskew()
input.Contrast()
Dim ocr As New IronTesseract()
Dim result = ocr.Read(input)
' Searchable PDF: original image layer preserved, invisible text layer added
result.SaveAsSearchablePdf("scanned-labels-searchable.pdf")
Console.WriteLine($"Searchable PDF created. Confidence: {result.Confidence}%")
Console.WriteLine($"Extracted text preview: {result.Text.Substring(0, 100)}")
End Using
검색 가능한 PDF 출력물은 원본 스캔 이미지를 전체 해상도로 유지하고 그 위에 보이지 않는 OCR 텍스트 레이어를 추가합니다. 이제 문서 관리 시스템, 검색 색인 및 PDF 뷰어에서 라벨 내용을 검색할 수 있습니다. 검색 가능한 PDF 사용 방법 안내서 와 스캔한 문서 처리 가이드는 여러 페이지로 구성된 아카이브 및 일괄 변환 워크플로를 다룹니다.
Dynamsoft OCR API와IronOCR매핑 참조
| Dynamsoft 라벨 인식기 | IronOCR에 상응하는 |
|---|---|
LabelRecognizer.InitLicense(key) |
IronOcr.License.LicenseKey = key |
new LabelRecognizer() |
new IronTesseract() |
recognizer.AppendSettingsFromString(json) |
필수 아님 — 자동 구성됨 |
recognizer.RecognizeFile(path) |
ocr.Read(path) |
recognizer.RecognizeByFile(path, templateName) |
ocr.Read(path) |
recognizer.RecognizeBuffer(buffer, width, height, ...) |
input.LoadImage(imageBytes) 그런 다음 ocr.Read(input) |
DLRResult[] (결과 배열) |
OcrResult (단일 결과 객체) |
DLRResult.LineResults |
OcrResult.Lines |
DLRLineResult.Text |
OcrResult.Line.Text |
DLRLineResult.Confidence |
OcrResult.Line.Words[i].Confidence |
DLRLineResult.Location.Points[i] |
OcrResult.Line.X, .Y, .Width, .Height |
ReferenceRegionArray (JSON) |
new CropRectangle(x, y, w, h) |
LabelRecognizerParameterArray (JSON) |
필요하지 않음 |
템플릿의 CharacterModelName |
필요하지 않음 |
recognizer.Dispose() |
using var ocr = new IronTesseract() |
| PDF 입력은 지원하지 않습니다. | input.LoadPdf(path) |
| 검색 가능한 PDF 출력 없음 | result.SaveAsSearchablePdf(path) |
| 여러 페이지로 구성된 TIFF 파일 입력은 지원하지 않습니다. | input.LoadImageFrames(path) |
| 바코드 판독 (별도 제품) | ocr.Configuration.ReadBarCodes = true |
여러 InitLicense 호출 (제품별) |
단일 IronOcr.License.LicenseKey 할당 |
일반적인 마이그레이션 문제와 해결책
문제 1: 마이그레이션 후 AppendSettingsFromString 메서드가 빈 결과를 반환함
Dynamsoft: AppendSettingsFromString이 잘못된 형식의 JSON 문자열을 받으면 인식이 조용히 빈 DLRResult 배열을 반환합니다. 예외가 발생하지 않습니다. Dynamsoft에서 마이그레이션하는 팀은 이러한 숨겨진 오류를 방지하기 위해 결과 구문 분석 코드 전체에 방어적인 null 검사를 추가하는 경우가 있습니다.
해결책: AppendSettingsFromString을 완전히 제거하십시오.IronOCR템플릿 구성이 필요하지 않습니다. 특정 지역 타깃 설정이 필요하다면, ReferenceRegionArray JSON을 CropRectangle로 교체하십시오:
// Remove all AppendSettingsFromString calls
// Replace region JSON with a CropRectangle constructor
var region = new CropRectangle(x: 0, y: 400, width: 1200, height: 300);
using var input = new OcrInput();
input.LoadImage(imagePath, region);
var result = new IronTesseract().Read(input);
// Remove all AppendSettingsFromString calls
// Replace region JSON with a CropRectangle constructor
var region = new CropRectangle(x: 0, y: 400, width: 1200, height: 300);
using var input = new OcrInput();
input.LoadImage(imagePath, region);
var result = new IronTesseract().Read(input);
Imports System
' Remove all AppendSettingsFromString calls
' Replace region JSON with a CropRectangle constructor
Dim region As New CropRectangle(x:=0, y:=400, width:=1200, height:=300)
Using input As New OcrInput()
input.LoadImage(imagePath, region)
Dim result = New IronTesseract().Read(input)
End Using
IronTesseract 설정 가이드에는 JSON 문자열이 아닌 속성으로 설정할 수 있는 모든 엔진 구성 옵션이 문서화되어 있습니다.
문제 2: 애플리케이션 시작 시 InitLicense 함수가 여러 번 호출됨
Dynamsoft: 라벨 인식기, 바코드 리더 및 문서 정규화기를 사용하는 응용 프로그램은 시작 시 세 개의 InitLicense 메서드를 호출하며, 각각 자체 라이선스 키가 필요합니다. 팀은 세 가지 환경 변수를 저장하고, 세 가지 키를 독립적으로 변경하며, 세 가지 개별 초기화 오류를 디버깅합니다.
해결책: 모든 Dynamsoft InitLicense 호출을 제거하십시오.IronOCR코드 한 줄로 대체하세요:
// Remove:
// LabelRecognizer.InitLicense(mrzKey);
// BarcodeReader.InitLicense(barcodeKey);
// DocumentNormalizer.InitLicense(docKey);
// Add once, at application startup:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// Remove:
// LabelRecognizer.InitLicense(mrzKey);
// BarcodeReader.InitLicense(barcodeKey);
// DocumentNormalizer.InitLicense(docKey);
// Add once, at application startup:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
' Remove:
' LabelRecognizer.InitLicense(mrzKey)
' BarcodeReader.InitLicense(barcodeKey)
' DocumentNormalizer.InitLicense(docKey)
' Add once, at application startup:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
하나의 환경 변수만으로IronOCR모든 기능(OCR, 바코드, PDF 처리 및 125개 이상의 모든 언어 지원)을 활성화할 수 있으며, 각 기능별로 초기화할 필요가 없습니다.
문제 3: LineResult 텍스트 집계 시 깨진 출력이 생성됨
Dynamsoft: RecognizeFile는 감지된 라벨 영역당 하나의 DLRResult를 반환합니다. 모든 결과를 lineResult.Text로 연결하여 \n 구분자로 사용하는 응용 프로그램은 페이지의 다른 라벨 영역에서 줄을 혼합한 출력을 생성합니다 — DLRResult 객체의 순서는 읽기 순서가 아닌 지역 감지 순서이기 때문입니다.
해결책: IronOCR의 결과 계층 구조는 읽기 순서대로 출력을 정리합니다. 문서의 자연 순서에 있는 텍스트에 접근하기 위해 Pages → Paragraphs → Lines 구조를 사용하십시오:
var result = new IronTesseract().Read(imagePath);
// Reading-order text — no manual aggregation
Console.WriteLine(result.Text);
// Or access paragraph-level groupings
foreach (var paragraph in result.Pages[0].Paragraphs)
Console.WriteLine(paragraph.Text);
var result = new IronTesseract().Read(imagePath);
// Reading-order text — no manual aggregation
Console.WriteLine(result.Text);
// Or access paragraph-level groupings
foreach (var paragraph in result.Pages[0].Paragraphs)
Console.WriteLine(paragraph.Text);
Imports IronOcr
Dim result = New IronTesseract().Read(imagePath)
' Reading-order text — no manual aggregation
Console.WriteLine(result.Text)
' Or access paragraph-level groupings
For Each paragraph In result.Pages(0).Paragraphs
Console.WriteLine(paragraph.Text)
Next
문제 4: 배포 서버에서 템플릿 JSON 파일이 누락됨
Dynamsoft: 템플릿 JSON 파일은 별도의 배포 아티팩트입니다. 새 서버에서 템플릿 파일이 없거나 잘못된 경로일 때, AppendSettingsFromString은 가끔 조용히 실패하거나 런타임 예외와 함께 실패하며, 응용 프로그램 코드를 건드리지 않고 인식이 깨집니다.
해결책:IronOCR에는 템플릿 파일이 없습니다. NuGet 패키지를 교체하고 네임스페이스를 업데이트한 후 배포 아티팩트 목록이 애플리케이션 바이너리와 하나의 환경 변수로 줄어듭니다. 필요한 경우 시작 유효성 검사 로직을 추가하세요.
// Validate license at startup — no template files to check
if (!IronOcr.License.IsValidLicense)
throw new InvalidOperationException("IronOCR license key is invalid or missing.");
var ocr = new IronTesseract();
// Ready to process — no file dependencies
// Validate license at startup — no template files to check
if (!IronOcr.License.IsValidLicense)
throw new InvalidOperationException("IronOCR license key is invalid or missing.");
var ocr = new IronTesseract();
// Ready to process — no file dependencies
Imports IronOcr
' Validate license at startup — no template files to check
If Not IronOcr.License.IsValidLicense Then
Throw New InvalidOperationException("IronOCR license key is invalid or missing.")
End If
Dim ocr As New IronTesseract()
' Ready to process — no file dependencies
제5호: 여러 제품에 걸친 폐기 관리
Dynamsoft: 각 Dynamsoft 제품 인스턴스 (LabelRecognizer, BarcodeReader, DocumentNormalizer)는 IDisposable를 구현합니다. 여러 제품을 통합하는 서비스 클래스는 다중 수준의 Dispose 구현을 가지고 있으며, 어떤 제품 인스턴스라도 Dispose 호출을 누락하면 로드 중 메모리 증가로 나타나는 네이티브 리소스 누수가 발생합니다.
해결책: IronOCR의 IronTesseract와 OcrInput는 모두 IDisposable를 구현하지만, 폐기 모델은 단순합니다 — 하나의 클래스, 하나의 패턴. 단일 IronTesseract 인스턴스를 DI 컨테이너에 단일톤으로 등록하거나, 단기 인스턴스를 위해 using 블록을 사용하십시오:
// Short-lived pattern
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = new IronTesseract().Read(input);
// Long-lived singleton (register in Program.cs)
builder.Services.AddSingleton<IronTesseract>();
// Short-lived pattern
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = new IronTesseract().Read(input);
// Long-lived singleton (register in Program.cs)
builder.Services.AddSingleton<IronTesseract>();
Imports IronOcr
' Short-lived pattern
Using input As New OcrInput()
input.LoadImage(imagePath)
Dim result = (New IronTesseract()).Read(input)
End Using
' Long-lived singleton (register in Program.vb)
builder.Services.AddSingleton(Of IronTesseract)()
진행 상황 추적 가이드는 장기 실행 배치 작업의 수명 주기 관리를 다루고, 비동기 OCR 가이드는 ASP.NET Core 에서 싱글턴 패턴을 보여줍니다.
문제 6: 사용자 지정 레이블 형식에 사용할 수 없는 문자 모델
Dynamsoft: 템플릿의 CharacterModelName 필드는 Dynamsoft SDK 설치 디렉토리에 존재해야 하는 모델 파일을 참조합니다. 사용자 지정 캐릭터 모델을 사용하려면 Dynamsoft 포털에서 추가 모델 파일을 다운로드하여 올바른 SDK 경로에 배치해야 합니다. 모델이 누락되면 모호한 런타임 오류와 함께 인식이 실패합니다.
해결책:IronOCR문자 모델 파일을 사용하지 않습니다. 사용자 지정 또는 특수 글꼴의 경우 사용자 지정 언어 학습을 사용하십시오.
// No character model files needed
// For specialized fonts, use a custom language pack
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English; // or load a custom trained pack
using var input = new OcrInput();
input.LoadImage(specializedFontImage);
input.Binarize(); // helps with specialized font clarity
var result = ocr.Read(input);
// No character model files needed
// For specialized fonts, use a custom language pack
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English; // or load a custom trained pack
using var input = new OcrInput();
input.LoadImage(specializedFontImage);
input.Binarize(); // helps with specialized font clarity
var result = ocr.Read(input);
Imports IronTesseract
' No character model files needed
' For specialized fonts, use a custom language pack
Dim ocr As New IronTesseract()
ocr.Language = OcrLanguage.English ' or load a custom trained pack
Using input As New OcrInput()
input.LoadImage(specializedFontImage)
input.Binarize() ' helps with specialized font clarity
Dim result = ocr.Read(input)
End Using
사용자 지정 글꼴 학습 가이드는 파일 경로 구성 없이 독점 레이블 글꼴용 사용자 지정 언어 팩을 학습하는 방법을 다룹니다.
Dynamsoft OCR 마이그레이션 체크리스트
사전 마이그레이션
코드베이스에서 Dynamsoft 관련 참조를 모두 검토하십시오.
# Find all Dynamsoft using statements
grep -r "using Dynamsoft" --include="*.cs" .
# Find InitLicense calls (one per product)
grep -r "InitLicense" --include="*.cs" .
# Find AppendSettingsFromString calls (template loads)
grep -r "AppendSettingsFromString" --include="*.cs" .
# Find template JSON strings (inline or file references)
grep -r "LabelRecognizerParameterArray\|ReferenceRegionArray\|CharacterModelName" --include="*.cs" .
# Find RecognizeFile and RecognizeByFile calls
grep -r "RecognizeFile\|RecognizeByFile\|RecognizeBuffer" --include="*.cs" .
# Find LineResult result parsing patterns
grep -r "LineResults\|DLRResult\|DLRLineResult" --include="*.cs" .
# Identify any JSON template files in the project
find . -name "*.json" | xargs grep -l "LabelRecognizerParameterArray" 2>/dev/null
# Find all Dynamsoft using statements
grep -r "using Dynamsoft" --include="*.cs" .
# Find InitLicense calls (one per product)
grep -r "InitLicense" --include="*.cs" .
# Find AppendSettingsFromString calls (template loads)
grep -r "AppendSettingsFromString" --include="*.cs" .
# Find template JSON strings (inline or file references)
grep -r "LabelRecognizerParameterArray\|ReferenceRegionArray\|CharacterModelName" --include="*.cs" .
# Find RecognizeFile and RecognizeByFile calls
grep -r "RecognizeFile\|RecognizeByFile\|RecognizeBuffer" --include="*.cs" .
# Find LineResult result parsing patterns
grep -r "LineResults\|DLRResult\|DLRLineResult" --include="*.cs" .
# Identify any JSON template files in the project
find . -name "*.json" | xargs grep -l "LabelRecognizerParameterArray" 2>/dev/null
재고 조사 결과:
InitLicense호출 위치 나열 (사용 중인 각 Dynamsoft 제품당 하나)AppendSettingsFromString호출 위치 나열 (각 인식 템플릿당 하나)- 마이그레이션 후 삭제될 모든 JSON 템플릿 파일 목록을 제공합니다.
- 모든
ReferenceRegionArray정의 식별 (CropRectangle으로 변환) - 바코드, 문서 표준화 등 어떤 기능이 별도의 제품으로 제공되는지 확인하십시오.
코드 마이그레이션
Dynamsoft.LabelRecognizerNuGet 패키지 (및 다른 모든 Dynamsoft 패키지) 제거IronOcrNuGet Install-Package (dotnet add package IronOcr)- 모든
using Dynamsoft.LabelRecognizer;및using Dynamsoft.Core;를using IronOcr;로 교체 - 응용 프로그램 시작 시 모든
LabelRecognizer.InitLicense(key)호출을 단일IronOcr.License.LicenseKey = key로 교체 - 모든
AppendSettingsFromString(json)호출을 제거 — 동등한 것이 필요하지 않습니다 ReferenceRegionArrayJSON 좌표를new CropRectangle(x, y, width, height)생성자로 교체new LabelRecognizer()인스턴스화를new IronTesseract()로 교체recognizer.RecognizeFile(path)를ocr.Read(path)로 교체DLRLineResult결과 반복을.Words계층 구조로 교체- 수동
lineResult.Text문자열 집계를result.Text또는 구조화된 페이지 열거로 교체 BarcodeReader.InitLicense+BarcodeReader.DecodeFile을ocr.Configuration.ReadBarCodes = true로 교체- 다중 제품
Dispose체인을 제거하고using var ocr = new IronTesseract()로 교체 - 프로젝트 및 배포 아티팩트에서 JSON 템플릿 파일을 삭제합니다.
- TIFF 파일에 대한 프레임 반복 루프를
input.LoadImageFrames(path)로 교체 - 스캔된 출력물을 아카이브해야 하는 곳에
result.SaveAsSearchablePdf(outputPath)추가
마이그레이션 이후
- 응용 프로그램 시작 시
IronOcr.License.IsValidLicense가true를 반환하는지 확인 - 모든 인식 결과가 이전에 작동하던 입력에 대해 비어 있지 않은
result.Text을 반환하는지 확인 - 대표 샘플에서
result.Confidence점검 — 80% 이상의 값은 좋은 인식 품질을 나타냅니다 - 이전 Dynamsoft 지역 결과와 비교하여
CropRectangle출력을 통해 지역 타겟팅 정확성을 테스트 - Dynamsoft 바코드 리더가 필요했던 입력에
ocr.Configuration.ReadBarCodes = true을 실행하여 바코드 읽기 유효성 확인 - 다중 페이지 TIFF 처리에서 프레임당 하나의
OcrResult.Page을 생성하는지 확인 - 검색 가능한 PDF 출력물이 PDF 뷰어에서 텍스트 검색이 가능한지 확인합니다.
Parallel.ForEach과 함께 병렬 처리 테스트를 실행하고 스레드 경쟁이 없는지 확인- 모든 배포 대상(Linux, Docker, Azure)을 테스트하여 JSON 템플릿 파일 없이 단일 패키지 배포가 제대로 작동하는지 확인합니다.
- 배포 구성에 Dynamsoft 라이선스 키 환경 변수가 남아 있지 않은지 확인하십시오.
IronOCR로 마이그레이션할 때의 주요 이점
하나의 패키지가 다중 제품 조정세를 제거합니다. 일반 OCR, MRZ 추출, 바코드 읽기, 네이티브 PDF 입력, 검색 가능한 PDF 출력, 전처리 및 125개 이상의 언어 모든 기능이 단일 IronOcr NuGet 패키지로 제공됩니다. 버전 업그레이드는 하나의 .csproj 파일에서 하나의 패키지 엔트리와 관련됩니다. 라이선스 키 순환은 하나의 환경 변수입니다. 배포 아티팩트 목록이 애플리케이션 바이너리로 축소되고, JSON 템플릿 파일이나 문자 모델 디렉터리는 포함되지 않습니다.
설정 파일 종속성이 전혀 없습니다. Dynamsoft 템플릿 시스템은 런타임 시 JSON 파일이 존재하고 경로가 올바르게 지정되어 있어야 합니다.IronOCR NuGet 패키지 자체를 제외하고는 런타임 파일에 대한 종속성이 없습니다. Docker 이미지는 결정론적이 됩니다. CI를 통과한 이미지가 프로덕션 환경에서 정확히 실행됩니다. Docker 배포 가이드는 Linux에 필요한 단 하나의 apt-get install 줄을 포함하는 전체 Dockerfile을 보여줍니다.
구조화된 출력이 통합 코드를 줄입니다. Dynamsoft는 원시 LineResult 텍스트 문자열을 반환합니다. 구조화된 데이터 추출(필드 위치, 단어 경계, 토큰별 신뢰도)에는 코드 자체에서 수행하고 테스트하는 후처리 작업이 필요합니다. IronOCR의 결과 계층 구조는 페이지, 단락, 줄, 단어 및 문자를 각 수준별 좌표와 신뢰도 점수와 함께 입력된 모음으로 표시합니다. Dynamsoft에서 IronOCR로 마이그레이션하는 팀은 일반적으로 결과 처리 코드의 30~50%를 제거합니다.IronOCR팀이 수동으로 구축하던 구조를 그대로 제공하기 때문입니다. OCR 결과 기능 페이지에는 전체 출력 모델이 문서화되어 있습니다.
영구 라이선스는 연간 예산 불확실성을 해소합니다. Dynamsoft Label Recognizer는 영구 라이선스 옵션을 제공하지 않습니다. 라벨 인식 기능만 사용하는 처리 클러스터를 5년간 운영하는 데 드는 비용은 연간 2,995달러 이상이며, 바코드 또는 문서 표준화 제품을 추가하기 전 금액입니다. IronOCR의 $999 Lite 라이선스는 모든 기능을 무기한 커버하는 일회성 구매입니다. 정부, Enterprise 및 장기적인 운영 환경의 경우, 핵심 문서 처리 구성 요소에서 연간 갱신 의존성을 제거하면 조달 복잡성이 줄어들고 프로젝트 중간에 구독이 만료될 위험이 없어집니다. IronOCR 라이선스 페이지에는 모든 등급과 각 등급의 내용이 명시되어 있습니다.
플랫폼별 설정 없이 크로스 플랫폼을 지원합니다.IronOCR NuGet의 런타임 식별자 그래프를 통해 Windows x64, Linux x64, macOS x64 및 macOS ARM에 맞는 런타임 바이너리를 찾아냅니다. 조건부 <PackageReference> 블록 없음, 플랫폼 감지 코드 없음, 네이티브 바이너리 경로 설정 없음. 동일한 using IronOcr; 코드가 수정 없이 Windows, Linux, AWS Lambda, Azure App Service에서 컴파일되고 실행됩니다.
Dynamsoft Label Recognizer는 애플리케이션 요구 사항에 따라 언어 지원 범위를 확장합니다. 라틴 문자 MRZ 형식에 최적화되어 있습니다. 라틴어 이외의 문자 체계, 즉 아랍어, 중국어, 일본어, 한국어, 히브리어는 설계 범위에서 제외됩니다. IronOCR는 개별 NuGet 패키지로 설치된 125개 이상의 언어를 지원합니다: dotnet add package IronOcr.Languages.Arabic는 인식 파이프라인에서 코드 변경 없이 아랍어 지원을 추가합니다. 언어 색인에서 이용 가능한 모든 언어 팩을 나열합니다. 국제 신분증, 다국어 배송 라벨 또는 국경 간 송장을 처리하는 애플리케이션의 경우, 이러한 광범위한 기능은 하나의 라이브러리로 성장하는 애플리케이션에서 접하는 모든 문서 유형을 처리할 수 있음을 의미합니다.
자주 묻는 질문
Dynamsoft OCR SDK에서 IronOCR로 마이그레이션해야 하는 이유는 무엇인가요?
일반적인 동인으로는 COM 상호 운용의 복잡성 제거, 파일 기반 라이선스 관리 대체, 페이지당 과금 방지, Docker/컨테이너 배포 활성화, 표준 .NET 툴링과 통합되는 NuGet 네이티브 워크플로 채택 등이 있습니다.
Dynamsoft OCR SDK에서 IronOCR로 마이그레이션할 때 주요 코드 변경 사항은 무엇인가요?
Dynamsoft OCR 초기화 시퀀스를 IronTesseract 인스턴스화로 대체하고, COM 수명 주기 관리(명시적 생성/로드/폐쇄 패턴)를 제거하며, 결과 속성 이름을 업데이트합니다. 그 결과 상용구 줄이 현저히 줄어듭니다.
마이그레이션을 시작하려면 IronOCR을 어떻게 설치하나요?
패키지 관리자 콘솔에서 '설치-패키지 IronOcr'을 실행하거나 CLI에서 '닷넷 추가 패키지 IronOcr'을 실행하세요. 언어 팩은 별도의 패키지입니다: 예를 들어 프랑스어의 경우 '닷넷 추가 패키지 IronOcr.Languages.French'를 실행합니다.
IronOCR은 표준 비즈니스 문서용 Dynamsoft OCR SDK의 OCR 정확도와 일치하나요?
IronOCR은 송장, 계약서, 영수증, 타이핑된 양식 등 표준 비즈니스 콘텐츠에 대해 높은 정확도를 달성합니다. 이미지 전처리 필터(데스큐, 노이즈 제거, 대비 향상)는 품질이 저하된 입력에 대한 인식률을 더욱 향상시킵니다.
IronOCR은 Dynamsoft OCR SDK가 별도로 설치하는 언어 데이터를 어떻게 처리하나요?
IronOCR의 언어 데이터는 NuGet 패키지로 배포됩니다. '닷넷 추가 패키지 IronOcr.Languages.German'은 독일어 지원을 설치합니다. 수동 파일 배치나 디렉터리 경로는 필요하지 않습니다.
Dynamsoft OCR SDK에서 IronOCR로 마이그레이션하려면 배포 인프라를 변경해야 하나요?
IronOCR은 Dynamsoft OCR SDK보다 인프라 변경이 더 적게 필요합니다. SDK 바이너리 경로, 라이선스 파일 배치 또는 라이선스 서버 구성이 필요하지 않습니다. NuGet 패키지에는 완전한 OCR 엔진이 포함되어 있으며 라이선스 키는 애플리케이션 코드에 설정된 문자열입니다.
마이그레이션 후 IronOCR 라이선싱은 어떻게 구성하나요?
애플리케이션 시작 코드에 IronOcr.License.LicenseKey = "YOUR-KEY"를 할당하세요. Docker 또는 Kubernetes에서 키를 환경 변수로 저장하고 시작 시 키를 읽습니다. 트래픽을 수락하기 전에 License.IsValidLicense를 사용하여 유효성을 검사하세요.
IronOCR은 Dynamsoft OCR과 동일한 방식으로 PDF를 처리할 수 있나요?
예. IronOCR은 원본 및 스캔한 PDF를 모두 읽습니다. IronTesseract를 인스턴스화하고, 입력이 PDF 경로 또는 OcrPdfInput인 경우 ocr.Read(input)를 호출하고, OcrResult 페이지를 반복하면 됩니다. 별도의 PDF 렌더링 파이프라인이 필요하지 않습니다.
IronOCR은 대량 처리에서 스레딩을 어떻게 처리하나요?
IronTesseract는 스레드별로 인스턴스화해도 안전합니다. Parallel.ForEach 또는 Task 풀에서 스레드당 하나의 인스턴스를 스핀업하고, OCR을 동시에 실행하고, 완료되면 각 인스턴스를 폐기하면 됩니다. 전역 상태나 잠금이 필요하지 않습니다.
IronOCR은 텍스트 추출 후 어떤 출력 형식을 지원하나요?
IronOCR은 텍스트, 단어 좌표, 신뢰도 점수, 페이지 구조를 포함한 구조화된 결과를 반환합니다. 내보내기 옵션에는 일반 텍스트, 검색 가능한 PDF, 다운스트림 처리를 위한 구조화된 결과 개체가 포함됩니다.
워크로드 확장을 위해 IronOCR 가격이 Dynamsoft OCR SDK보다 더 예측 가능한가요?
IronOCR은 페이지당 또는 볼륨당 요금이 없는 정액제 영구 라이선스를 사용합니다. 10,000페이지를 처리하든 1,000만 페이지를 처리하든 라이선스 비용은 일정하게 유지됩니다. 볼륨 및 팀 라이선스 옵션은 IronOCR 가격 페이지에서 확인할 수 있습니다.
Dynamsoft OCR SDK에서 IronOCR로 마이그레이션한 후 기존 테스트는 어떻게 되나요?
추출된 텍스트 콘텐츠에 대해 어설트하는 테스트는 마이그레이션 후에도 계속 통과해야 합니다. API 호출 패턴 또는 COM 개체 수명 주기의 유효성을 검사하는 테스트는 IronOCR의 더 간단한 초기화 및 결과 모델을 반영하도록 업데이트해야 합니다.

