Migracja z Dynamsoft OCR do IronOCR
Niniejszy przewodnik zawiera kompletną ścieżkę migracji dla programistów .NET przechodzących zDynamsoft Label Recognizerna IronOCR. Obejmuje zastąpienie pakietu NuGet, aktualizacje przestrzeni nazw, inicjalizację licencji oraz praktyczne przykłady migracji kodu dla scenariuszy odbiegających od ogólnych porównań możliwości — w tym eliminację konfiguracji szablonów, usunięcie ustawień środowiska uruchomieniowego JSON, migrację definicji regionów oraz uproszczenie analizowania wyników.
Dlaczego warto przejść z Dynamsoft OCR
Dynamsoft Label Recognizer to specjalistyczne narzędzie stworzone do konkretnego celu. Ta precyzja sprawdza się dobrze w wąskich zastosowaniach, ale stwarza trudności w momencie, gdy zakres zastosowania aplikacji wykracza poza pierwotny przypadek użycia MRZ lub VIN.
Konfiguracja JSON ustawień wykonawczych jest powierzchnią utrzymania. Każdy przepływ pracy rozpoznawania Dynamsoft zaczyna się od AppendSettingsFromString, ładowania dokumentu JSON, który deklaruje tablice parametrów, modele znaków i odniesienia regionów. Te szablony JSON są oddzielnymi artefaktami wdrożeniowymi — nie są kompilowane do pliku binarnego. Wymagają one kontroli wersji, zarządzania procesem wdrażania oraz ręcznych aktualizacji, gdy firma Dynamsoft zmienia schematy szablonów w różnych wersjach SDK.IronOCR nie wymaga żadnych plików konfiguracyjnych: utwórz IronTesseract, wywołaj .Read(), a silnik automatycznie dobierze odpowiednie ustawienia.
Ceny rocznych subskrypcji są złożone. LicencjeDynamsoft Label Recognizerkosztują 599 USD+ za urządzenie rocznie. Nie ma opcji wieczystej. Klaster przetwarzający składający się z pięciu urządzeń kosztuje ponad 2995 USD rocznie — a budżet ten obejmuje jedynie rozpoznawanie MRZ i ustrukturyzowanych etykiet. Dodaj Dynamsoft BarCode Reader do kodów kreskowych lub Dynamsoft Document Normalizer do korekcji krawędzi, a roczny rachunek pomnoży się przez liczbę produktów. Licencja Lite IronOCR jest $999 jednorazowo i obejmuje ogólne OCR, etykiety strukturalne, kody kreskowe, natywną obsługę PDF, wyjście PDF z możliwością przeszukiwania oraz ponad 125 języków w jednym pakiecie.
Definiowanie regionu wymaga szablonów JSON. Definiowanie regionu rozpoznawania w Dynamsoft oznacza tworzenie bloku JSON ReferenceRegionArray, odniesienie go w LabelRecognizerParameterArray, a następnie załadowanie całego dokumentu przed rozpoczęciem przetwarzania obrazu.IronOCR używa jednego CropRectangle(x, y, width, height) konstruktora przekazywanego bezpośrednio do OcrInput.LoadImage. Zmiana regionu to edycja jednej liczby, a nie ponowne parsowanie dokumentu JSON.
Parsowanie wyników jest całkowicie Twoją odpowiedzialnością. RecognizeFile i RecognizeByFile zwracają tablice LineResult zawierające surowe ciągi tekstowe. Każda potrzebna struktura — przesunięcia pól, konwersje dat, sprawdzanie cyfr kontrolnych, obsługa separatorów nazw — wymaga niestandardowego kodu parsującego nałożonego na ten surowy wynik.IronOCR zwraca OcrResult z .Pages, .Lines, .Words i .Characters jako typowe kolekcje z już wypełnionymi współrzędnymi obramowania, wynikami zaufania i metadanymi czcionki.
Brak natywnej obsługi plików PDF powoduje powstanie ukrytej zależności.Dynamsoft Label Recognizernie obsługuje plików PDF. Każdy plik PDF, który trafia do Twojego procesu przetwarzania, wymaga zewnętrznej biblioteki do renderowania każdej strony do postaci bitmapy, pętli iteracji stron oraz etapu agregacji wyników przed pierwszym wywołaniem Dynamsoft.IronOCR odczytuje PDF-y natywnie: new IronTesseract().Read("document.pdf") przetwarza każdą stronę bez dodatkowych zależności, pętli renderowania czy folderu obrazów tymczasowych.
Bloki inicjalizacji wieloproduktowej rosną wraz z zakresem. Aplikacja Dynamsoft, która obsługuje etykiety strukturalne, kody kreskowe i normalizację dokumentów, wykonuje trzy statyczne wywołania InitLicense podczas uruchamiania, trzy łańcuchy usuwania i trzy niezależne zależności wersji SDK. Aktualizacja zestawu SDK oznacza koordynację działań we wszystkich produktach.IronOCR ma jedną linię inicjalizacyjną i jedną wersję pakietu, niezależnie od tego, z jakich funkcji korzysta aplikacja.
Podstawowy problem
Dynamsoft wymaga pliku konfiguracyjnego JSON załadowanego w czasie wykonywania, zanim rozpocznie się rozpoznawanie:
// 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 a Dynamsoft OCR: porównanie funkcji
Poniższa tabela przedstawia pełną różnicę w możliwościach obu bibliotek.
| Funkcja | Dynamsoft Label Recognizer | IronOCR |
|---|---|---|
| Ogólne OCR dokumentów | Nieobsługiwane | Pełne wsparcie |
| Rozpoznawanie MRZ | Specjalistyczne (tekst w formacie surowym) | Wbudowane z polami strukturalnymi |
| Rozpoznawanie numerów VIN | Specjalistyczne (wymagany szablon) | Standardowe OCR z wyodrębnianiem regionów |
| Odczytywanie etykiet przemysłowych | Specjalistyczne (wymagany szablon) | Tak, poprzez CropRectangle |
| Konfiguracja ustawień środowiska uruchomieniowego | Wymagane (JSON przez AppendSettingsFromString) |
Nie jest wymagane |
| Artefakty wdrażania szablonów | Wymagane (pliki JSON) | None |
| Natywne wprowadzanie plików PDF | Nieobsługiwane | Tak |
| Plik PDF chroniony hasłem | Nieobsługiwane | Tak |
| Wielostronicowy plik wejściowy w formacie TIFF | Iteracja strony podręcznika | Rodzimy (LoadImageFrames) |
| Wynik w formacie PDF z możliwością wyszukiwania | Nieobsługiwane | Tak (SaveAsSearchablePdf) |
| Odczytywanie BarCode | Oddzielny produkt (Dynamsoft BarCode Reader) | Wbudowany (ReadBarCodes = true) |
| Automatyczne przetwarzanie wstępne | Ograniczone | Tak (Deskew, DeNoise, Contrast, Binarize, Sharpen, Dilate, Erode) |
| Struktura tekstu (słowa, wiersze, akapity) | Surowe ciągi tekstowe LineResult |
W pełni wpisane wraz ze współrzędnymi i poziomem pewności |
| Obsługa języków | Ograniczone (Latin MRZ) | Ponad 125 języków, dostępne w pakietach NuGet |
| Wielojęzyczne tłumaczenie symultaniczne | Nieobsługiwane | Tak (OcrLanguage.French + OcrLanguage.German) |
| Wyniki pewności | Tylko za linię | Za słowo, wiersz, stronę |
| eksport hOCR | Nieobsługiwane | Tak |
| Model licencyjny | Roczna subskrypcja (599 USD+/urządzenie/rok) | Wieczna ($999 jednorazowo, poziom Lite) |
| Wymagane jest przetłumaczenie wielu produktów | Tak (3+ dla pełnego pokrycia) | Nie (jeden pakiet) |
| Obsługa platformy .NET Framework | .NET Framework 4.x+ | .NET Framework 4.6.2+, .NET 5/6/7/8/9 |
| Wdrażanie wielopłatformowe | Tak | Tak (Windows, Linux, macOS, Docker, Azure, AWS) |
| Pakiet NuGet | Dynamsoft.LabelRecognizer |
IronOcr |
Szybki start: Migracja z Dynamsoft OCR do IronOCR
Krok 1: Zastąp pakiet NuGet
Usuń pakiet Dynamsoft:
dotnet remove package Dynamsoft.LabelRecognizer
dotnet remove package Dynamsoft.LabelRecognizer
Zainstaluj IronOCR z galerii NuGet:
dotnet add package IronOcr
Krok 2: Aktualizacja przestrzeni nazw
// 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
Krok 3: Inicjalizacja licencji
Zastąp każde statyczne wywołanie InitLicense Dynamsoft pojedynczym przypisaniem licencji IronOCR podczas uruchamiania aplikacji:
// 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"
Przykłady migracji kodu
Rozpoznawanie oparte na szablonach do silnika bezkonfigurowalnego
System szablonów JSON firmy Dynamsoft dostarcza SDK szczegółowych instrukcji dotyczących modeli znaków, specyfikacji regionów i parametrów rozpoznawania przed przetworzeniem jakiegokolwiek obrazu. W przypadku większości rzeczywistych zadań OCR taka konfiguracja zwiększa złożoność ustawień bez korzyści w zakresie rozpoznawania, ponieważ silnik Tesseract automatycznie obsługuje wykrywanie układu.
Podejście firmy 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()
Podejście 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
Podejście Dynamsoft wymaga stworzenia, sprawdzenia i wdrożenia szablonu JSON przed przetworzeniem jakiegokolwiek obrazu. Literówka w AppendSettingsFromString zwraca puste wyniki w czasie wykonywania — brak walidacji w czasie kompilacji. CropRectangleIronOCR to zwykły konstruktor: sprawdzanie typów w czasie kompilacji, brak zewnętrznych plików, brak artefaktów wdrożeniowych. Zobacz przewodnik po OCR dla poszczególnych regionów, aby zapoznać się ze wszystkimi wzorcami docelowymi.
Skanowanie kodów VIN z migracją regionu
Pobieranie numerów identyfikacyjnych pojazdów to specjalność programu Dynamsoft Label Recognizer. Model szablonu VIN jest zoptymalizowany pod kątem konkretnego 17-znakowego formatu alfanumerycznego. Przejście na IronOCR zastępuje model szablonowy potokiem przetwarzania wstępnego i kierowaniem na regiony, co pozwala obsługiwać te same warunki tablic VIN bez konieczności konfiguracji modelu znaków.
Podejście firmy 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()
Podejście 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
Współrzędne CropRectangle używają tej samej ramki odniesienia pikseli jak specyfikacja SecondPoint w procentach Dynamsoft — przeliczając Użyj procentowych wartości Dynamsoft na wymiary obrazka. Linia przetwarzania wstępnego (Contrast, Sharpen) zastępuje optymalizację modelu znaków, którą Dynamsoft włącza do swojego szablonu VIN. Przewodnik po korekcji jakości obrazu obejmuje dobór filtrów do powierzchni wytłoczonych i o niskim kontraście.
Przetwarzanie wielostronicowych plików TIFF w trybie wsadowym
Dynamsoft Label Recognizer przetwarza pojedyncze obrazy. Wielostronicowe dokumenty TIFF — powszechne w systemach zarządzania dokumentami, archiwach obrazów medycznych i potokach faksów — wymagają iteracji zewnętrznej: załadowania każdej klatki, przepuszczenia jej indywidualnie przez moduł rozpoznawania oraz agregacji wyników.IronOCR obsługuje wieloramkowe TIFF-y natywnie przez LoadImageFrames.
Podejście firmy 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()
Podejście 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
Podejście Dynamsoft wymaga System.Drawing do ekstrakcji klatek, plików tymczasowych na dysku dla każdej klatki i ręcznego czyszczenia po każdym przebiegu. LoadImageFramesIronOCR odczytuje wszystkie klatki jednym wywołaniem — brak plików tymczasowych, brak śledzenia indeksów klatek. Po OCR, SaveAsSearchablePdf archiwizuje całą partię jako dokument przeszukiwalny w jednym wywołaniu metody. Wielokadrowy przewodnik w formacie TIFF oraz przewodnik w formacie PDF z funkcją wyszukiwania szczegółowo opisują obie te funkcje.
Strukturalne parsowanie wyników na poziomie słów
Dynamsoft RecognizeFile zwraca tablicę DLRResult. Każdy DLRResult zawiera kolekcję LineResults obiektów DLRLineResult z właściwością Text i właściwością Location zawierającą ograniczony czworokąt. Wyodrębnianie pozycji na poziomie słów wymaga podziału tekstu w wierszu na spacje i proporcjonalnego podziału ramki ograniczającej wiersz — jest to przybliżenie, które nie działa w przypadku czcionek proporcjonalnych.IronOCR uwypukla prostokąty obramowania na poziomie słów jako typowe właściwości na każdym obiekcie OcrResult.Word.
Podejście firmy 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()
Podejście 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 zapewnia prawdziwą hierarchię: strony zawierają akapity, akapity zawierają wiersze, wiersze zawierają słowa, a słowa zawierają znaki. Każdy poziom ujawnia .X, .Y, .Width, .Height i .Confidence jako typowe właściwości całkowite i zmiennoprzecinkowe - bez potrzeby wykonywania matematyki współrzędnych czworokątnych. Dokumentacja dotycząca wyników ustrukturyzowanych zawiera opis wszystkich dostępnych właściwości, a dokumentacja dotycząca oceny pewności wyjaśnia progi pewności stosowane w automatycznych procesach weryfikacji dokumentów.
Asynchroniczne przetwarzanie równoległe do skanowania etykiet o dużej objętości
Dynamsoft Label Recognizer jest bezpieczny dla wątków, ale jego wywołanie RecognizeFile jest synchroniczne. Obudowanie go w Task.Run umożliwia równoległe przetwarzanie, ale każde wywołanie współdzieli stan konfiguracji przez AppendSettingsFromString — ładowanie szablonów na wielu wątkach wymaga ostrożnej sekwencji inicjalizacji. Instancje IronTesseractIronOCRsą niezależne: utwórz jedną dla zadania, wywołaj Read, a model wątków jest prosty.
Podejście firmy 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")
Podejście 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 nie wymaga sekwencji inicjalizacji przed rozpoczęciem pracy równoległej. Jedno przypisanie IronOcr.License.LicenseKey podczas uruchamiania aplikacji aktywuje wszystkie instancje. Brak ponownego ładowania szablonu na wątek, brak walidacji JSON na instancję. Dla scenariuszy niewstrzymujących po stronie serwera, przewodnik po asynchronicznym OCR obejmuje wzorce oparte na await dla ASP.NET Core i Azure Functions.
Wyszukiwalny plik PDF z zeskanowanych archiwów etykiet
Dynamsoft nie posiada żadnej funkcji generowania plików PDF. Zeskanowane archiwa etykiet przetworzone przez Dynamsoft pozostają plikami zawierającymi wyłącznie obrazy — nie można ich przeszukiwać, nie są indeksowane przez systemy zarządzania dokumentami i nie są zgodne ze standardami archiwizacji PDF/A.IronOCR dodaje wyjście PDF z możliwością przeszukiwania jako pojedyncze wywołanie metody na obiekcie OcrResult.
Podejście firmy 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()
Podejście 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
Wynik w postaci pliku PDF z możliwością wyszukiwania zachowuje oryginalny zeskanowany obraz w pełnej rozdzielczości i dodaje na nim niewidoczną warstwę tekstową OCR. Systemy zarządzania dokumentami, indeksy wyszukiwania i przeglądarki plików PDF mogą teraz przeszukiwać zawartość etykiet. Przewodnik w formacie PDF z funkcją wyszukiwania oraz przewodnik dotyczący przetwarzania zeskanowanych dokumentów obejmują archiwa wielostronicowe i procesy konwersji zbiorczej.
Dynamsoft OCR API do IronOCR– dokumentacja API
| Dynamsoft Label Recognizer | Odpowiednik IronOCR |
|---|---|
LabelRecognizer.InitLicense(key) |
IronOcr.License.LicenseKey = key |
new LabelRecognizer() |
new IronTesseract() |
recognizer.AppendSettingsFromString(json) |
Nie jest wymagane — konfiguracja automatyczna |
recognizer.RecognizeFile(path) |
ocr.Read(path) |
recognizer.RecognizeByFile(path, templateName) |
ocr.Read(path) |
recognizer.RecognizeBuffer(buffer, width, height, ...) |
input.LoadImage(imageBytes) następnie ocr.Read(input) |
DLRResult[] (tablica wyników) |
OcrResult (pojedynczy obiekt wyniku) |
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) |
Nie jest wymagane |
CharacterModelName w szablonie |
Nie jest wymagane |
recognizer.Dispose() |
using var ocr = new IronTesseract() |
| Brak obsługi plików PDF jako danych wejściowych | input.LoadPdf(path) |
| Brak możliwości wyszukiwania w pliku PDF | result.SaveAsSearchablePdf(path) |
| Nie akceptujemy plików TIFF zawierających wiele stron | input.LoadImageFrames(path) |
| Odczytywanie BarCode (oddzielny produkt) | ocr.Configuration.ReadBarCodes = true |
Wiele wywołań InitLicense (na produkt) |
Pojedyncze przypisanie IronOcr.License.LicenseKey |
Typowe problemy związane z migracją i ich rozwiązania
Problem 1: Funkcja AppendSettingsFromString zwraca puste wyniki po migracji
Dynamsoft: Rozpoznanie cicho zwraca puste tablice DLRResult, gdy AppendSettingsFromString otrzymuje źle uformowany łańcuch JSON. Nie jest zgłaszany żaden wyjątek. Zespoły migrujące z Dynamsoft czasami dodają defensywne sprawdzanie wartości null w całym kodzie parsującym wyniki, aby zabezpieczyć się przed tą cichą awarią.
Rozwiązanie: Usuń całkowicie AppendSettingsFromString.IronOCR nie wymaga konfiguracji szablonów. Jeśli wymagane jest ukierunkowanie na konkretne regiony, zastąp JSON-a ReferenceRegionArray na 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
Podręcznik konfiguracji IronTesseract dokumentuje wszystkie opcje konfiguracji silnika, które można ustawić jako właściwości zamiast ciągów JSON.
Problem 2: Wielokrotne wywołania funkcji InitLicense podczas uruchamiania aplikacji
Dynamsoft: Aplikacja korzystająca z Label Recognizer, Barcode Reader i Document Normalizer wywołuje trzy oddzielne metody InitLicense podczas uruchamiania, z każdą potrzebującą własnego klucza licencyjnego. Zespoły przechowują trzy zmienne środowiskowe, niezależnie rotują trzy klucze i debugują trzy oddzielne błędy inicjalizacji.
Rozwiązanie: Usuń wszystkie wywołania InitLicense Dynamsoft. Zastąp jednym wierszem 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")
Jedna zmienna środowiskowa aktywuje wszystkie funkcje IronOCR— OCR, BarCode, przetwarzanie plików PDF oraz ponad 125 języków — bez konieczności inicjalizacji poszczególnych funkcji.
Problem 3: Agregacja tekstu LineResult powoduje zniekształcenie wyników
Dynamsoft: RecognizeFile zwraca jedno DLRResult na wykrytą region etykiety. Aplikacje, które łączą lineResult.Text we wszystkich wynikach z separatorami \n, generują wyjście, które miesza linie z różnych stref etykiet na stronie — ponieważ kolejność obiektów DLRResult jest kolejnością detekcji regionalnej, a nie kolejnością czytania.
Rozwiązanie: Hierarchia wyników IronOCR porządkuje dane wyjściowe zgodnie z kolejnością czytania. Użyj struktury Pages → Paragraphs → Lines, aby uzyskać dostęp do tekstu w naturalnej kolejności dokumentu:
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
Problem 4: Brak plików szablonów JSON na serwerze wdrożeniowym
Dynamsoft: Pliki szablonów JSON są oddzielnymi artefaktami wdrożeniowymi. Gdy plik szablonu jest nieobecny lub ma nieprawidłową ścieżkę na nowym serwerze, AppendSettingsFromString zawodzi — czasami cicho, czasami z wyjątkiem w czasie wykonywania — i wdrożenie łamie rozpoznanie bez dotykania kodu aplikacji.
Rozwiązanie:IronOCR nie posiada plików szablonów. Po zastąpieniu pakietu NuGet i aktualizacji przestrzeni nazw lista artefaktów wdrożeniowych zmniejsza się do plików binarnych aplikacji i jednej zmiennej Środowiska. W razie potrzeby dodaj sprawdzanie poprawności uruchamiania:
// 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
Zagadnienie 5: Zarządzanie łańcuchem utylizacji w odniesieniu do wielu produktów
Dynamsoft: Każda instancja produktu Dynamsoft (LabelRecognizer, BarcodeReader, DocumentNormalizer) implementuje IDisposable. Klasy usługowe, które agregują wiele produktów, zawierają wielopoziomowe implementacje Dispose, a pominięcie wywołania Dispose na dowolnej instancji produktu powoduje wycieki zasobów natywnych, które objawiają się wzrostem pamięci przy obciążeniu.
Rozwiązanie: Zarówno IronTesseract, jak i OcrInputIronOCR implementują IDisposable, ale model usuwania jest prostszy — jedna klasa, jeden wzorzec. Zarejestruj pojedynczą instancję IronTesseract w kontenerze DI jako singleton, lub użyj bloków using dla instancji krótkotrwałych:
// 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)()
Przewodnik dotyczący śledzenia postępów obejmuje zarządzanie cyklem życia długotrwałych zadań wsadowych, a przewodnik dotyczący asynchronicznego OCR przedstawia wzorce singletonowe w ASP.NET Core.
Problem 6: Model znaków niedostępny dla niestandardowego formatu etykiety
Dynamsoft: Pole CharacterModelName w szablonie odnosi się do pliku modelu, który musi istnieć w katalogu instalacyjnym SDK Dynamsoft. Niestandardowe modele znaków wymagają pobrania dodatkowych plików modeli z portalu Dynamsoft i umieszczenia ich w odpowiedniej ścieżce SDK. Brak modelu powoduje niepowodzenie rozpoznawania i wyświetlenie niezrozumiałego błędu wykonania.
Rozwiązanie:IronOCR nie korzysta z plików modeli znaków. W przypadku czcionek niestandardowych lub specjalistycznych należy skorzystać z niestandardowego szkolenia językowego:
// 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
Przewodnik po szkoleniu dotyczącym czcionek niestandardowych obejmuje szkolenie w zakresie pakietu językowego dla zastrzeżonych czcionek etykiet bez konieczności konfiguracji ścieżki pliku.
Lista kontrolna migracji Dynamsoft OCR
Przed migracją
Sprawdź kod źródłowy pod kątem wszystkich odniesień do 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
Wyniki przeglądu zasobów:
- Policz miejsca wywołań
InitLicense(po jednym na każdy używany produkt Dynamsoft) - Policz miejsca wywołań
AppendSettingsFromString(po jednym na każdy szablon rozpoznawania) - Wymień wszystkie pliki szablonów JSON, które zostaną usunięte po migracji
- Zidentyfikuj wszystkie definicje
ReferenceRegionArray(przekształć naCropRectangle) - Zwróć uwagę, które funkcje są obsługiwane przez oddzielne produkty (BARCODE, normalizacja dokumentów)
Migracja kodu
- Usuń pakiet NuGet
Dynamsoft.LabelRecognizer(i wszystkie inne pakiety Dynamsoft) - Zainstaluj pakiet NuGet
IronOcr(dotnet add package IronOcr) - Zastąp wszystkie
using Dynamsoft.LabelRecognizer;iusing Dynamsoft.Core;zusing IronOcr; - Zastąp wszystkie wywołania
LabelRecognizer.InitLicense(key)pojedynczym wywołaniemIronOcr.License.LicenseKey = keyprzy starcie aplikacji - Usuń wszystkie wywołania
AppendSettingsFromString(json)— brak wymaganego ekwiwalentu - Zastąp współrzędne JSON
ReferenceRegionArrayz konstruktoraminew CropRectangle(x, y, width, height) - Zastąp instancję
new LabelRecognizer()przeznew IronTesseract() - Zastąp
recognizer.RecognizeFile(path)przezocr.Read(path) - Zastąp iterację wyników
DLRLineResultprzez hierarchię.Words - Zastąp ręczną agregację ciągów
lineResult.Textprzezresult.Textlub strukturalną enumerację stron - Zastąp
BarcodeReader.InitLicense+BarcodeReader.DecodeFileprzezocr.Configuration.ReadBarCodes = true - Usuń łańcuchy
Disposewieloproduktowe i zastąp przezusing var ocr = new IronTesseract() - Usuń pliki szablonów JSON z projektu i artefaktów wdrożeniowych
- Zastąp pętle iteracyjne ramki nad plikami TIFF przez
input.LoadImageFrames(path) - Dodaj
result.SaveAsSearchablePdf(outputPath)zawsze, gdy zeskanowane wyniki muszą być zarchiwizowane
Po migracji
- Zweryfikuj, że
IronOcr.License.IsValidLicensezwracatrueprzy starcie aplikacji - Potwierdź, że wszystkie wyniki rozpoznawania zwracają niepuste
result.Textdla wcześniej działających danych wejściowych - Sprawdź
result.Confidencena reprezentatywnych próbkach — wartości powyżej 80% wskazują na dobrą jakość rozpoznawania - Testuj dokładność ukierunkowania regionalnego, porównując wyniki
CropRectanglez wcześniejszymi wynikami regionów Dynamsoft - Zwaliduj odczytywanie kodów kreskowych, uruchamiając
ocr.Configuration.ReadBarCodes = truena danych wejściowych, które wcześniej wymagały Dynamsoft Barcode Reader - Zweryfikuj przetwarzanie wielu stron TIFF, które produkuje jeden
OcrResult.Pagena każdą ramkę - Upewnij się, że plik PDF z możliwością wyszukiwania umożliwia wyszukiwanie tekstu w przeglądarce plików PDF
- Uruchom testy przetwarzania równoległego z
Parallel.ForEachi zweryfikuj brak przeciążeń wątków - Przetestuj wszystkie środowiska docelowe (Linux, Docker, Azure), aby potwierdzić, że wdrożenie w postaci pojedynczego pakietu działa bez plików szablonów JSON
- Upewnij się, że w konfiguracji wdrożenia nie pozostały żadne zmienne środowiskowe klucza licencyjnego Dynamsoft
Kluczowe korzyści z migracji do IronOCR
Jedno opakowanie eliminuje podatek koordynacyjny wieloproduktowy. Każda funkcjonalność — ogólne OCR, ekstrakcja MRZ, odczytywanie kodów kreskowych, natywne wejście PDF, wyjście PDF z możliwością przeszukiwania, przetwarzanie wstępne oraz ponad 125 języków — jest wysyłana jako pojedynczy IronOcr pakiet NuGet. Aktualizacje wersji wpływają na jedno wejście pakietu w jednym pliku .csproj. Rotacja klucza licencyjnego jest jednym zmienną środowiskową. Zawartość pakietu wdrożeniowego ogranicza się do plików binarnych aplikacji, bez plików szablonów JSON i katalogów modeli znaków.
Brak zależności od plików konfiguracyjnych. System szablonów Dynamsoft wymaga obecności plików JSON i poprawnie ustawionych ścieżek dostępu w czasie wykonywania.IronOCR nie ma żadnych zależności od plików w czasie wykonywania poza samym pakietem NuGet. Obrazy Docker stają się deterministyczne: to, co przechodzi CI, jest dokładnie tym, co działa w środowisku produkcyjnym. Przewodnik wdrożeniowy Docker pokazuje pełny Dockerfile wymagający jedynie jednej linii apt-get install dla Linuxa.
Zorganizowane wyjście redukuje kod integracyjny. Dynamsoft zwraca surowe ciągi tekstowe LineResult. Pobieranie danych strukturalnych — pozycje pól, granice słów, poziom pewności dla każdego tokenu — wymaga przetwarzania końcowego, które kod sam wykonuje i testuje. Hierarchia wyników IronOCR przedstawia strony, akapity, wiersze, słowa i znaki jako typowane zbiory z współrzędnymi i wynikami pewności na każdym poziomie. Zespoły migrujące z Dynamsoft zazwyczaj usuwają 30–50% kodu przetwarzającego wyniki, ponieważIronOCR dostarcza strukturę, którą wcześniej budowali ręcznie. Strona z wynikami OCR dokumentuje kompletny model wyjściowy.
Licencja wieczysta eliminuje niepewność związaną z rocznym budżetem.Dynamsoft Label Recognizernie oferuje opcji licencji wieczystej. Klaster przetwarzający działający przez pięć lat kosztuje ponad 2995 USD rocznie tylko za rozpoznawanie etykiet, nie licząc produktów do normalizacji BARCODE lub dokumentów. Licencja Lite IronOCR$999 to jednorazowy zakup, który obejmuje wszystkie funkcje na czas nieokreślony. W przypadku wdrożeń rządowych, Enterprise i długoterminowych usunięcie konieczności corocznego odnawiania licencji z podstawowego komponentu przetwarzania dokumentów zmniejsza złożoność procesu zakupowego i eliminuje ryzyko wygaśnięcia subskrypcji w trakcie realizacji projektu. Strona licencyjna IronOCR zawiera listę wszystkich poziomów oraz opis tego, co każdy z nich obejmuje.
Wielopłatformowość bez konfiguracji specyficznej dla platformy.IronOCR wybiera odpowiedni plik binarny środowiska uruchomieniowego dla systemów Windows x64, Linux x64, macOS x64 i macOS ARM za pomocą grafu identyfikatorów środowiska uruchomieniowego NuGet. Brak warunkowych bloków <PackageReference>, brak kodu wykrywania platformy, brak konfiguracji ścieżek natywnych. Ten sam kod using IronOcr; kompiluje się i działa na Windows, Linux, AWS Lambda oraz Azure App Service bez modyfikacji.
Zakres obsługiwanych języków dostosowuje się do potrzeb aplikacji.Dynamsoft Label Recognizerzostał zaprojektowany z myślą o formatach MRZ z alfabetem łacińskim. Pisma niełacińskie — arabskie, chińskie, japońskie, koreańskie, hebrajskie — wykraczają poza zakres projektu.IronOCR obsługuje ponad 125 języków instalowanych jako indywidualne pakiety NuGet: dotnet add package IronOcr.Languages.Arabic dodaje wsparcie dla języka arabskiego bez zmiany kodu w linii rozpoznawania. Indeks języków wymienia każdy dostępny pakiet językowy. W przypadku aplikacji przetwarzających międzynarodowe dokumenty tożsamości, wielojęzyczne etykiety wysyłkowe lub faktury transgraniczne, ten szeroki zakres oznacza, że jedna biblioteka obsługuje każdy typ dokumentu, z jakim spotyka się rozwijająca się aplikacja.
Często Zadawane Pytania
Dlaczego warto przejść z Dynamsoft OCR SDK na IronOCR?
Typowe czynniki motywujące to eliminacja złożoności interoperacyjności COM, zastąpienie zarządzania licencjami opartego na plikach, uniknięcie rozliczeń za stronę, umożliwienie wdrażania w Dockerze/kontenerach oraz przyjęcie natywnego dla NuGet przepływu pracy, który integruje się ze standardowymi narzędziami .NET.
Jakie są główne zmiany w kodzie podczas migracji z Dynamsoft OCR SDK do IronOCR?
Zastąp sekwencje inicjalizacji Dynamsoft OCR instancjonowaniem IronTesseract, usuń zarządzanie cyklem życia COM (jawnymi wzorcami Create/Load/Close) i zaktualizuj nazwy właściwości wyników. W rezultacie znacznie zmniejsza się liczba powtarzających się linii kodu.
Jak zainstalować IronOCR, aby rozpocząć migrację?
Uruchom polecenie „Install-Package IronOcr” w konsoli menedżera pakietów lub „dotnet add package IronOcr” w interfejsie CLI. Pakiety językowe są oddzielnymi pakietami: na przykład „dotnet add package IronOcr.Languages.French” dla języka francuskiego.
Czy IronOCR dorównuje dokładnością OCR bibliotece Dynamsoft OCR SDK w przypadku standardowych dokumentów biznesowych?
IronOCR zapewnia wysoką dokładność w przypadku standardowych treści biznesowych, w tym faktur, umów, paragonów i formularzy wypełnionych na komputerze. Filtry przetwarzania wstępnego obrazu (prostowanie, usuwanie szumów, wzmacnianie kontrastu) dodatkowo poprawiają rozpoznawanie w przypadku pogorszonej jakości danych wejściowych.
W jaki sposób IronOCR obsługuje dane językowe, które Dynamsoft OCR SDK instaluje oddzielnie?
Dane językowe w IronOCR są dystrybuowane jako pakiety NuGet. Polecenie „dotnet add package IronOcr.Languages.German” instaluje obsługę języka niemiećkiego. Nie wymaga to ręcznego umieszczania plików ani podawania ścieżek katalogów.
Czy migracja z Dynamsoft OCR SDK do IronOCR wymaga zmian w infrastrukturze wdrożeniowej?
IronOCR wymaga mniej zmian w infrastrukturze niż Dynamsoft OCR SDK. Nie ma ścieżek binarnych SDK, lokalizacji plików licencyjnych ani konfiguracji serwerów licencyjnych. Pakiet NuGet zawiera kompletny silnik OCR, a klucz licencyjny jest ciągiem znaków ustawionym w kodzie aplikacji.
Jak skonfigurować licencjonowanie IronOCR po migracji?
W kodzie uruchamiającym aplikację przypisz IronOcr.License.LicenseKey = „YOUR-KEY”. W Dockerze lub Kubernetesie zapisz klucz jako zmienną środowiskową i odczytaj go podczas uruchamiania. Użyj License.IsValidLicense do sprawdzenia ważności przed przyjęciem ruchu.
Czy IronOCR może przetwarzać pliki PDF w taki sam sposób jak Dynamsoft OCR?
Tak. IronOCR odczytuje zarówno natywne, jak i zeskanowane pliki PDF. Należy utworzyć instancję IronTesseract, wywołać ocr.Read(input), gdzie input jest ścieżką do pliku PDF lub obiektem OcrPdfInput, a następnie iterować strony OcrResult. Nie jest wymagany oddzielny proces renderowania plików PDF.
W jaki sposób IronOCR radzi sobie z wątkami podczas przetwarzania dużych ilości danych?
IronTesseract można bezpiecznie instancjonować dla każdego wątku. Uruchom jedną instancję na wątek w Parallel.ForEach lub puli zadań, uruchom OCR równolegle i usuń każdą instancję po zakończeniu. Nie jest wymagany żaden stan globalny ani blokowanie.
Jakie formaty wyjściowe obsługuje IronOCR po wyodrębnieniu tekstu?
IronOCR zwraca ustrukturyzowane wyniki, w tym tekst, współrzędne słów, wyniki pewności i strukturę strony. Opcje eksportu obejmują zwykły tekst, PDF z możliwością wyszukiwania oraz obiekty wyników ustrukturyzowanych do dalszego przetwarzania.
Czy ceny IronOCR są bardziej przewidywalne niż Dynamsoft OCR SDK w przypadku skalowania obciążeń?
IronOCR stosuje licencję wieczystą z opłatą ryczałtową, bez opłat za stronę lub wolumen. Niezależnie od tego, czy przetwarzasz 10 000, czy 10 milionów stron, koszt licencji pozostaje stały. Opcje licencji wolumenowych i zespołowych znajdują się na stronie z cennikiem IronOCR.
Co stanie się z moimi istniejącymi testami po migracji z Dynamsoft OCR SDK do IronOCR?
Testy sprawdzające wyodrębnioną treść tekstową powinny nadal przechodzić pomyślnie po migracji. Testy weryfikujące wzorce wywołań API lub cykl życia obiektów COM będą wymagały aktualizacji, aby odzwierciedlały prostszy model inicjalizacji i wyników IronOCR.

