Migracja z TesseractOCR do IronOCR
Ten przewodnik przeprowadza programistów .NET przez proces pełnej migracji z pakietu NuGetTesseractOCR(fork Sicos1977/Kees van Spelde) do IronOCR. Obejmuje to pełną ścieżkę wymiany: usunięcie zewnętrznych zależności związanych z przetwarzaniem wstępnym, umożliwienie natywnego wprowadzania plików PDF i generowania plików PDF z możliwością wyszukiwania, aktualizację przestrzeni nazw i wywołań API oraz weryfikację przeniesionej integracji. Nie jest wymagana wcześniejsza lektura artykułu porównawczego.
Dlaczego warto przejść z TesseractOCR
TesseractOCR to aktywnie rozwijana biblioteka społecznościowa przeznaczona dla nowoczesnego środowiska .NET, zawierająca natywne biblioteki Tesseract 5. Przejście na tę wersję z starszych opakowań rozwiązuje problem kompatybilności frameworków. Nie rozwiązuje to luk architektonicznych znajdujących się poniżej warstwy opakowującej. Kiedy te luki ujawniają się w środowisku produkcyjnym, rozpoczyna się dyskusja na temat migracji.
**Przetwarzanie wstępne odbywa się całkowicie poza biblioteką.**TesseractOCRwywołuje engine.Process(image) na dowolnych pikselach, które podasz. Przekrzywiony skan, faks o niskim kontraście, zdjęcie paragonu zrobione telefonem — wszystkie trafiają do silnika Tesseract w postaci surowych danych. Odzyskanie użytecznego wyjścia wymaga dodania SixLabors.ImageSharp, SkiaSharp lub podobnej biblioteki obrazów, pisania ręcznych łańcuchów filtrów z parametrami dostosowanymi do typu dokumentu i przetwarzania obrazu przetworzonego wstępnie przez plik tymczasowy, ponieważ TesseractOCR.Pix.Image oczekuje ścieżki pliku. Funkcja Deskew nie jest w ogóle dostępna w standardowych bibliotekach obrazówania .NET — wymaga to zaimplementowania od podstaw algorytmu wykrywania kąta transformacji Hougha, co zazwyczaj oznacza od 50 do 100 dodatkowych linii kodu. Nie jest to jednorazowy koszt konfiguracji; powtarza się on za każdym razem, gdy do procesu trafia nowy typ dokumentu.
**Wprowadzanie plików PDF wymaga drugiej biblioteki i potoku plików tymczasowych.**TesseractOCRprzetwarza obrazy, a nie pliki PDF. Każdy proces przetwarzania plików PDF wymaga dodatkowego pakietu — Docnet.Core, PdfiumViewer lub podobnego — do renderowania stron PDF do tablic bajtów BGRA, metody pomocniczej do konwersji tych bajtów do formatu, który może odczytać TesseractOCR, oraz logiki tworzenia i czyszczenia plików tymczasowych obejmującej całą pętlę. W rezultacie każda operacja OCR pliku PDF wymaga około 100 linii kodu infrastruktury. Chronione hasłem PDF wymagają trzeciej biblioteki (iText z licencją AGPL lub PDFSharp), aby je odszyfrować przed przetwarzaniem.
Wynik w postaci pliku PDF z możliwością wyszukiwania nie ma ścieżki. Zespoły, które muszą tworzyć pliki PDF nadające się do odczytu maszynowego na podstawie zeskanowanych dokumentów — co jest częstym wymogiem w procesach zarządzania dokumentami, archiwizacji i zapewniania zgodności — stwierdzają, żeTesseractOCRnie zapewnia mechanizmu do tego celu. Nie ma SaveAsSearchablePdf(), brak rurociągu hOCR-to-PDF, brak formatu wyjściowego poza wyodrębnionym tekstem. Dodanie tej funkcji wymaga albo osobnej biblioteki PDF, albo całkowitej rezygnacji z TesseractOCR.
Dokumenty TIFF zawierające wiele ramek wymagają ręcznego przechodzenia między stronami. Pliki TIFF zawierające wiele stron, powszechnie spotykane w procesach faksowania i skanowania dokumentów, nie są natywnie obsługiwane przez TesseractOCR. Wyodrębnienie wszystkich klatek wymaga załadowania pliku TIFF za pomocą zewnętrznej biblioteki, iteracji klatek, zapisania każdej z nich w pliku tymczasowym oraz oddzielnego przetworzenia każdego pliku tymczasowego przez silnik OCR.
**Wielkość społeczności ogranicza praktyczne wsparcie.**TesseractOCRma około 200 000 pobrań z NuGet. Stack Overflow, posty na blogach oraz wątki na GitHubie o .NET Tesseract wrapperach w przeważającej mierze odnoszą się do API charlesw — TesseractEngine, Pix.LoadFromFile — nie do API Sicos1977. Praktyczne rozwiązywanie problemów związanych zTesseractOCRszybko napotyka tę przeszkodę.
Podstawowy problem
TesseractOCR nie posiada funkcji przetwarzania wstępnego ani obsługi plików PDF. Każdy proces tworzenia dokumentów wymaga w końcu bibliotek zewnętrznych, aby w ogóle można było uruchomić OCR:
// TesseractOCR: three packages, a temp file, and manual byte conversion
// just to OCR one PDF page — before any preprocessing
// dotnet add package TesseractOCR
// dotnet add package Docnet.Core
// dotnet add package SixLabors.ImageSharp (preprocessing)
using var library = DocLib.Instance;
using var docReader = library.GetDocReader(pdfPath, new PageDimensions(200, 200));
using var pageReader = docReader.GetPageReader(0);
var bytes = pageReader.GetImage(); // BGRA — not a format Pix.Image accepts directly
string tempPath = Path.GetTempFileName() + ".png";
SaveBgraAsPng(bytes, pageReader.GetPageWidth(), pageReader.GetPageHeight(), tempPath);
// ^ 30+ line helper method needed here
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var image = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(image);
string text = page.Text;
File.Delete(tempPath); // hope this succeeds
// IronOCR: one package, three lines, preprocessing automatic
// dotnet add package IronOcr
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(pdfPath);
string text = ocr.Read(input).Text;
##IronOCR vs TesseractOCR: Porównanie funkcji
Poniższa tabela przedstawia funkcje, które mają największe znaczenie podczas oceny migracji.
| Funkcja | TesseractOCR | IronOCR |
|---|---|---|
| Pakiet NuGet | TesseractOCR | IronOcr |
| Kompatybilność z platformą .NET | .NET 6.0, 7.0, 8.0 | .NET Framework 4.6.2+, .NET Core, .NET 5/6/7/8/9 |
| Licencja | Apache 2.0 (bezpłatna) | Komercyjna (wieczysta, od $999) |
| Zarządzanie danymi Tessdata | Wymagane (ręczne pobranie z serwisu GitHub) | Nie jest wymagane (dołączone wewnętrznie) |
| Wbudowane przetwarzanie wstępne | None | Wyrównanie, Usuwanie szumów, Kontrast, Binaryzacja, Wyostrzanie, Skalowanie, Rozszerzanie, Erodowanie, Odwracanie |
| Głębokie usuwanie szumów tła | Nie | Tak (DeepCleanBackgroundNoise()) |
| Natywne wprowadzanie plików PDF | Nie (wymaga Docnet.Core lub podobnego) | Tak (input.LoadPdf()) |
| Plik PDF chroniony hasłem | Nie (wymaga biblioteki zewnętrznej do odszyfrowania) | Tak (pojedynczy parametr Password) |
| Wynik w formacie PDF z możliwością wyszukiwania | Nie | Tak (result.SaveAsSearchablePdf()) |
| Wprowadzanie plików TIFF z wieloma ramkami | Nie (wymaga zewnętrznego wyodrębniania ramki) | Tak (input.LoadImageFrames()) |
| Wejście strumieniowe i tablica bajtów | Nie (wymaga pośrednictwa pliku tymczasowego) | Tak (bezpośrednie LoadImage(stream), LoadImage(bytes)) |
| Bezpieczeństwo wątków | Nie (jedna instancja silnika na wątek) | Tak (pojedynczy IronTesseract dzielony przez wątki) |
| OCR oparte na regionie | Nie | Tak (CropRectangle) |
| Odczytywanie BarCode podczas OCR | Nie | Tak (ocr.Configuration.ReadBarCodes = true) |
| Wynik w formacie strukturalnym (strony, słowa, współrzędne) | Nie (tylko płaski ciąg tekstowy) | Tak (Pages, Paragraphs, Lines, Words z X/Y) |
| Ocena pewności | Wartość zmiennoprzecinkowa na poziomie dokumentu (0,0–1,0) | Ocena na poziomie dokumentu i WORD (0–100) |
| eksport hOCR | Nie | Tak |
| Pakiety NuGet w ponad 125 językach | Nie | Tak |
| Wdrażanie wielopłatformowe | Windows, Linux, macOS | Windows, Linux, macOS, Docker, Azure, AWS |
| Wsparcie komercyjne | Nie (jeden wolontariusz odpowiedzialny za utrzymanie) | Tak (e-mail, opcje umowy SLA) |
Szybki start: Migracja zTesseractOCRdo IronOCR
Krok 1: Zastąp pakiet NuGet
UsuńTesseractOCRi wszelkie biblioteki dodane w celu jego obsługi:
dotnet remove package TesseractOCR
dotnet remove package Docnet.Core
dotnet remove package SixLabors.ImageSharp
Zainstaluj IronOCR z NuGet:
Krok 2: Aktualizacja przestrzeni nazw
Zastąp wszystkie importy przestrzeni nazwTesseractOCRprzez IronOCR:
// Before (TesseractOCR)
using TesseractOCR;
using TesseractOCR.Enums;
// After (IronOCR)
using IronOcr;
Krok 3: Inicjalizacja licencji
Dodaj inicjalizację licencji raz podczas uruchamiania aplikacji, przed jakimkolwiek wywołaniem OCR:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"Bezpłatna licencja próbna jest dostępna na stronie licencyjnej IronOCR w celu oceny.
Przykłady migracji kodu
Zastąpienie zewnętrznego potoku przetwarzania wstępnego
TesseractOCR wymaga zewnętrznej biblioteki obrazówania w celu poprawy jakości każdego dokumentu. Poniższy kod pokazuje schemat, który zespoły stosują, gdy jakość dokumentów jest zmienna — konwersja do skali szarości, regulacja kontrastu, redukcja szumów oraz zapis pliku tymczasowego przed uruchomieniem OCR. Funkcja Deskew (korygująca przechylony skan) nie jest dostępna w standardowych bibliotekach obrazówania .NET Standard i wymaga oddzielnego algorytmu.
Podejście TesseractOCR:
// Requires: dotnet add package SixLabors.ImageSharp
// Manual preprocessing — parameters must be tuned per document type
// Deskew is NOT in ImageSharp — requires custom Hough transform (~50-100 lines)
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromLowQualityScan(string imagePath)
{
using var image = Image.Load(imagePath);
image.Mutate(x => x.Grayscale());
image.Mutate(x => x.Contrast(1.5f)); // manual tuning required
image.Mutate(x => x.GaussianBlur(0.5f)); // noise reduction approximation
image.Mutate(x => x.BinaryThreshold(0.5f)); // threshold requires per-doc adjustment
// Deskew omitted — no built-in support, ~80 lines of additional code
string tempPath = Path.GetTempFileName() + ".png";
try
{
image.Save(tempPath);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
return page.Text;
}
finally
{
File.Delete(tempPath);
}
}
Podejście IronOCR:
// Nie external imaging library
// Nie temp file — OcrInput accepts a path, stream, or byte array directly
// Deskew is built in — automatic angle detection and correction
using IronOcr;
public string ExtractFromLowQualityScan(string imagePath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
input.Deskew(); // automatic angle correction
input.DeNoise(); // intelligent noise removal
input.Contrast(); // automatic contrast enhancement
input.Binarize(); // clean black-and-white conversion
var ocr = new IronTesseract();
return ocr.Read(input).Text;
}
Usunięcie zależności od ImageSharp całkowicie eliminuje cykl dostrajania. Rurociąg przetwarzania wstępnego OcrInput stosuje algorytmy skalibrowane do dokumentów OCR — bez zgadywania współczynników kontrastu czy promieni rozmycia. Samouczek dotyczący filtrów obrazu oraz przewodnik po korekcji jakości obrazu obejmują wszystkie dostępne filtry wraz z opcjami parametrów na wypadek, gdyby konieczne było dostosowanie ustawień domyślnych.
Zastąpienie przetwarzania plików TIFF z wieloma ramkami
Dokumenty faksowe, wyniki skanowania dokumentów oraz pliki archiwalne często są dostarczane jako wielostronicowe pliki TIFF.TesseractOCRnie obsługuje wielu klatek — każdą klatkę należy wyodrębnić za pomocą zewnętrznej biblioteki, zapisać na dysku i przekazać do silnika pojedynczo.IronOCRładuje cały plik TIFF za pomocą jednego wywołania.
Podejście TesseractOCR:
// Requires: dotnet add package SixLabors.ImageSharp
// Manual frame extraction — every frame becomes a temp file on disk
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Tiff;
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromMultiPageTiff(string tiffPath)
{
var allText = new System.Text.StringBuilder();
var tempFiles = new List<string>();
try
{
using var image = Image.Load(tiffPath);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
for (int frameIndex = 0; frameIndex < image.Frames.Count; frameIndex++)
{
// Clone frame and save to temp file — no in-memory path
using var frameImage = image.Frames.CloneFrame(frameIndex);
string tempPath = Path.GetTempFileName() + ".png";
tempFiles.Add(tempPath);
frameImage.SaveAsPng(tempPath);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
allText.AppendLine($"=== Frame {frameIndex + 1} ===");
allText.AppendLine(page.Text);
}
}
finally
{
foreach (var f in tempFiles)
try { File.Delete(f); } catch { }
}
return allText.ToString();
}
Podejście IronOCR:
// Nie external library for frame extraction
// All frames processed in one Read() call — no manual loop required
using IronOcr;
public string ExtractFromMultiPageTiff(string tiffPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // loads all frames automatically
var result = ocr.Read(input);
// Access per-page text if needed
foreach (var page in result.Pages)
Console.WriteLine($"Frame {page.PageNumber}: {page.Text}");
return result.Text;
}
Pętla wyodrębniania ramek, lista plików tymczasowych, blok sprzątania finally — to wszystko znika. W przypadku 20-stronicowego pliku TIFF z faksem zastępuje to około 40 wierszy 6-ma. Przewodnik dotyczący plików wejściowych TIFF i GIF obejmuje opcje ładowania wielu klatek, w tym wybrane zakresy klatek.
Generowanie plików PDF z możliwością wyszukiwania
Ten scenariusz nie ma ścieżki migracji wTesseractOCR— po prostu nie da się tego zrobić. Zeskanowane pliki PDF, które muszą stać się dokumentami nadającymi się do odczytu maszynowego i umożliwiającymi zaznaczanie tekstu (w celu indeksowania wyszukiwania, zapewnienia dostępności lub archiwizacji), wymagają utworzenia pliku PDF z możliwością wyszukiwania.TesseractOCRgeneruje wyłącznie wyodrębniony tekst.IronOCR bezpośrednio generuje plik PDF z możliwością wyszukiwania.
Podejście TesseractOCR:
// Nie path available —TesseractOCRcannot produce any PDF output.
// The closest workaround requires a separate PDF library (iTextSharp AGPL,
// or similar) to overlay extracted text onto the original PDF manually.
// This is 150-300 lines of additional code and introduces AGPL license concerns.
// The best available output from TesseractOCR:
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile("scanned-page.png");
using var page = engine.Process(pix);
string extractedText = page.Text; // flat string — no PDF output possible
File.WriteAllText("output.txt", extractedText);
// Cannot produce a searchable PDF — no API exists for this
Podejście IronOCR:
// Native searchable PDF output — no additional library required
// Input can be a scanned image, a scanned PDF, or a multi-page TIFF
using IronOcr;
public void CreateSearchablePdf(string scannedPdfPath, string outputPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(scannedPdfPath);
input.Deskew(); // improve accuracy before generating the output
input.DeNoise();
var result = ocr.Read(input);
result.SaveAsSearchablePdf(outputPath); // searchable, text-selectable PDF
}
Wywołanie SaveAsSearchablePdf() osadza tekst OCR w PDF jako niewidoczną warstwę za oryginalnym zeskanowanym obrazem. Dokument pozostaje identyczny pod względem wizualnym, ale staje się w pełni przeszukiwalny, zaznaczalny i indeksowalny. Przewodnik w formacie PDF z funkcją wyszukiwania obejmuje pełny zakres API, a przykład w formacie PDF z funkcją wyszukiwania pokazuje kompletny wzorzec działania.
Zastąpienie wejścia typu Byte-Array i wyeliminowanie plików tymczasowych
API Pix.ImageTesseractOCRakceptuje ścieżkę pliku. Gdy dane obrazu przychodzą jako tablica bajtów — z bazy danych, wieloczęściowego przesyłania HTTP, pamięci podręcznej —TesseractOCRwymusza zapis do pliku tymczasowego przed przetworzeniem. API OcrInputIronOCR akceptuje bezpośrednio tablice bajtów i strumienie, całkowicie eliminując krok z plikiem tymczasowym.
Podejście TesseractOCR:
// TesseractOCR.Pix.Image has no byte[] or Stream overload
// Every in-memory image must be written to disk before processing
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromBytes(byte[] imageBytes)
{
// Force a disk write just to satisfy the file-path API
string tempPath = Path.GetTempFileName() + ".png";
try
{
File.WriteAllBytes(tempPath, imageBytes);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
return page.Text;
}
finally
{
// Risk: if an exception fires between WriteAllBytes and Delete,
// temp files accumulate on the server disk
if (File.Exists(tempPath))
File.Delete(tempPath);
}
}
Podejście IronOCR:
// OcrInput accepts byte arrays and streams natively
// Nie disk write, no temp file cleanup, no cleanup failure risk
using IronOcr;
public string ExtractFromBytes(byte[] imageBytes)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imageBytes); // direct byte array — no temp file
return ocr.Read(input).Text;
}
public string ExtractFromStream(Stream imageStream)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imageStream); // direct stream — no intermediate buffer
return ocr.Read(input).Text;
}
W aplikacjach internetowych przetwarzających przesłane dokumenty wzorzec plików tymczasowych powoduje wzrost zużycia miejsca na dysku pod obciążeniem i wprowadza warunki wyścigu, jeśli kod czyszczący zostanie wywołany. Przewodnik po strumieniach wejściowych oraz przewodnik po obrazach wejściowych obejmują każdy obsługiwany format wejściowy, w tym MemoryStream, byte[], Bitmap i ścieżkę pliku.
Filtrowanie pewności na poziomie słów z wykorzystaniem danych strukturalnych
TesseractOCR zwraca pojedynczy wynik na poziomie dokumentu (page.MeanConfidence, wartość float z zakresu 0.0 do 1.0) i płaski łańcuch tekstowy. Nie ma pewności co do poszczególnych słów, nie ma pozycjonowania słów ani hierarchii strukturalnej. Stworzenie przepływu pracy, który zaznacza niepewne słowa, wyodrębnia określone obszary lub mapuje tekst na współrzędne dokumentu, wymaga przejścia na zasadniczo inny model wyjściowy.
Podejście TesseractOCR:
// Only document-level confidence available
// Nie word coordinates, no structural hierarchy
using TesseractOCR;
using TesseractOCR.Enums;
public void ProcessWithConfidence(string imagePath)
{
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(imagePath);
using var page = engine.Process(pix);
float docConfidence = page.MeanConfidence; // 0.0 to 1.0 for the whole document
if (docConfidence >= 0.7f)
Console.WriteLine($"Accepted ({docConfidence:P0}): {page.Text}");
else
Console.WriteLine($"Rejected ({docConfidence:P0}): document needs preprocessing");
// Nie way to identify WHICH words are uncertain
// Nie word coordinates available
}
Podejście IronOCR:
// Per-word confidence and coordinate data
// Filter individual uncertain words without discarding the whole document
using IronOcr;
public void ProcessWithWordLevelConfidence(string imagePath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = ocr.Read(input);
Console.WriteLine($"Document confidence: {result.Confidence}%");
// Iterate words and flag those below threshold
foreach (var page in result.Pages)
{
foreach (var word in page.Words)
{
if (word.Confidence < 70)
{
// Low-confidence word — log position for review
Console.WriteLine(
$"Low confidence word '{word.Text}' ({word.Confidence}%) " +
$"at X:{word.X} Y:{word.Y}");
}
}
}
// Extract only high-confidence text
var reliableWords = result.Pages
.SelectMany(p => p.Words)
.Where(w => w.Confidence >= 70)
.Select(w => w.Text);
Console.WriteLine(string.Join(" ", reliableWords));
}
Filtrowanie pewności na poziomie poszczególnych WORD-ów jest niezbędne w przetwarzaniu faktur, ekstrakcji formularzy oraz w każdym przepływie pracy, w którym podejmowanie działań na podstawie niepewnego tekstu jest gorsze niż oznaczenie go do weryfikacji. Przewodnik po wynikach pewności obejmuje pełny model punktacji, a przewodnik po wynikach odczytu dokumentuje kompletną hierarchię wyników.
Odnośnik do dokumentacji APITesseractOCRdo IronOCR
| TesseractOCR | IronOCR | Uwagi |
|---|---|---|
new Engine(tessDataPath, Language.English, EngineMode.Default) | new IronTesseract() | Brak ścieżki do plików tessdata; nie jest wymagany wybór trybu silnika |
TesseractOCR.Pix.Image.LoadFromFile(path) | input.LoadImage(path) | Również akceptuje byte[] i Stream |
engine.Process(pixImage) | ocr.Read(input) | Zwraca OcrResult zamiast Page |
page.Text | result.Text | Identyczna semantyka |
page.MeanConfidence (float z zakresu 0,0–1,0) | result.Confidence (double z zakresu 0–100) | Skala się różni — aktualizacja porównań progów |
Language.English | Language.French | OcrLanguage.English + OcrLanguage.French | Operator dodawania, a nie bitowe OR |
EngineMode.Default | Nie dotyczy | IronOCR wybiera tryb wewnętrznie |
EngineMode.LstmOnly | Nie dotyczy | Automatyczne |
TesseractOCR.Exceptions.TesseractException | IronOcr.Exceptions.OcrException | Mniej typów wyjątków do obsługi |
DllNotFoundException (natywny brakujący) | Nie dotyczy | IronOCR zawiera swoje natywne zależności |
BadImageFormatException (niezgodność architektury) | Nie dotyczy | Obsługiwane wewnętrznie |
Zewnętrzny Image.Mutate(x => x.Grayscale()) | input.Binarize() | Wbudowane, bez zewnętrznej biblioteki |
Zewnętrzny Image.Mutate(x => x.Contrast(...)) | input.Contrast() | Automatyczna kalibracja |
| Zewnętrzna transformacja Hougha do prostowania | input.Deskew() | Wbudowane, jedno wywołanie metody |
Zewnętrzny filtr szumów GaussianBlur | input.DeNoise() | Inteligentne usuwanie szumów |
DocLib.GetDocReader(pdfPath, ...) | input.LoadPdf(pdfPath) | Nie jest wymagany Docnet.Core |
docReader.GetPageReader(i).GetImage() + plik tymczasowy | input.LoadPdf(pdfPath) | Cała pętla została zastąpiona |
input.LoadPdf(encrypted, Password: "...") | Pojedynczy parametr — nie jest potrzebna żadna trzecia biblioteka | |
| Nie dotyczy (brak pliku PDF) | result.SaveAsSearchablePdf(outputPath) | Brak odpowiednika wTesseractOCR |
| Nie dotyczy (brak obsługi ramek) | input.LoadImageFrames(tiffPath) | Wielokadrowy plik TIFF w jednym wywołaniu |
| Nie dotyczy (tylko ścieżka do pliku) | input.LoadImage(stream) / input.LoadImage(bytes) | Eliminuje wzorzec plików tymczasowych |
Instancje Engine na wątek | Pojedynczy IronTesseract dzielony przez wątki | Zabezpieczone przed współbieżnością już w fazie projektowania |
page.MeanConfidence (tylko dokument) | word.Confidence na słowo | Dostępna ocena na poziomie słów |
Typowe problemy związane z migracją i ich rozwiązania
Problem 1: Wartości progów ufności ulegają zmianie po migracji
TesseractOCR: page.MeanConfidence zwraca wartość float w zakresie od 0,0 do 1,0. Kod często sprawdza if (confidence >= 0.7f), aby zaakceptować wyniki.
**Rozwiązanie:**IronOCR podaje poziom pewności jako wartość podwójną w skali od 0 do 100. Pomnóż wszystkie wartości progowe przez 100. Próg 0.7f staje się 70.0. Pewność na poziomie dokumentu wynosi result.Confidence; Pewność na poziomie słowa wynosi word.Confidence wewnątrz result.Pages[n].Words.
// Before (TesseractOCR): page.MeanConfidence >= 0.7f
// After (IronOCR):
var result = new IronTesseract().Read("document.png");
if (result.Confidence >= 70.0)
{
Console.WriteLine(result.Text);
}
Problem 2: Katalog tymczasowy zapełnia się po próbie migracji
TesseractOCR: Kod napisany wokół ograniczenia Pix.Image.LoadFromFile() często tworzy pliki tymczasowe, które są oczyszczane w blokach finally. Jeśli sam blok finally rzuca wyjątek lub jeśli aplikacja zostanie przymusowo zakończona, pliki tymczasowe gromadzą się.
Rozwiązanie: Zastąp wszystkie wzorce File.WriteAllBytes(tempPath, bytes) + Pix.Image.LoadFromFile(tempPath) wzorcem input.LoadImage(bytes) lub input.LoadImage(stream). Gdy kod nie tworzy już plików tymczasowych, logikę czyszczenia oraz tworzenie katalogu do przechowywania tymczasowego można całkowicie usunąć. Wyszukaj GetTempFileName, GetTempPath i SaveBgraAsPng, aby znaleźć wszystkie wystąpienia.
grep -rn "GetTempFileName\|GetTempPath\|SaveBgraAsPng" --include="*.cs" .
// Before: byte[] → temp file → Pix.Image.LoadFromFile
// After: byte[] → OcrInput directly
using var input = new OcrInput();
input.LoadImage(imageBytes); // no disk write
var result = ocr.Read(input);
Zobacz przewodnik dotyczący obrazów, aby zapoznać się ze wszystkimi obsługiwanymi formatami.
Problem 3: Zmiana operatora językowego powoduje błąd kompilatora
TesseractOCR: Wielojęzyczne OCR wykorzystuje operację bitową OR na wyliczeniu flag: Language.English | Język: francuski. To jest wzorzec [Flags]` enumeracji.
**Rozwiązanie:**IronOCR używa operatora dodawania: OcrLanguage.English + OcrLanguage.French. Wyglądają podobnie, ale są to różne operatory. Znajdź i zastąp Language. na OcrLanguage. w połączeniu z | to + w wyrażeniach językowych obsługuje większość przypadków. Zweryfikuj, że wszelkie językowe kombinacje budowane w czasie działania również używają +.
// Before (TesseractOCR):
var engine = new Engine(@"./tessdata",
Language.English | Language.French | Language.German,
EngineMode.Default);
// After (IronOCR):
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;
Problem 4: Pakiety Docnet i ImageSharp są nadal odwołane po odinstalowaniu
TesseractOCR: Projekty wykorzystująceTesseractOCRw procesach związanych z plikami PDF zazwyczaj mają Docnet.Core jako bezpośrednią zależność oraz SixLabors.ImageSharp lub SkiaSharp do przetwarzania wstępnego. Po przejściu na IronOCR, te pakiety często pozostają w .csproj, ponieważ instrukcje 'using' nie zostały w pełni usunięte.
Rozwiązanie: Po usunięciu pakietów z .csproj, przeszukaj wszystkie pozostałe using Docnet.Core, using SixLabors.ImageSharp i powiązane odniesienia do przestrzeni nazw. Jeśli instrukcje using odnoszą się do przestrzeni nazw, które już nie istnieją w drzewie zależności, kompilator je oznaczy — ale tylko wtedy, gdy polecenia dotnet remove package zostały faktycznie uruchomione.
grep -rn "using Docnet\|using SixLabors\|using SkiaSharp" --include="*.cs" .
Usuń odniesienia do zidentyfikowanych plików, a następnie usuń metody pomocnicze do przetwarzania wstępnego (SaveBgraAsPng, ApplyGrayscale, ApplyThreshold i podobne), które służyły staremu rurociągowi.
Problem 5: Wzrost rozmiaru obrazu Docker po migracji
TesseractOCR: Niektóre konfiguracje Docker instalują Tesseract za pomocą apt-get install tesseract-ocr tesseract-ocr-eng jako pakiet systemowy, a następnie odnoszą się do tych binariów systemowych. W zależności od pakietów językowych powoduje to zwiększenie rozmiaru obrazu o około 30–80 MB.
**Rozwiązanie:**IronOCR dołącza własne pliki binarne Tesseract do pakietu NuGet. Linia apt-get install tesseract-ocr w Dockerfile nie jest już potrzebna i powinna zostać usunięta. Paczki językowe również pochodzą z NuGet, a nie z apt-get install tesseract-ocr-fra. Przewodnik wdrażania Docker zawiera sprawdzone konfiguracje obrazów bazowych oraz dokładne pakiety wymagane do uruchomienia IronOCR w kontenerze.
# Remove these lines after migration:
# RUN apt-get install -y tesseract-ocr tesseract-ocr-eng tesseract-ocr-fra
# COPY ./tessdata /app/tessdata
Problem 6: Bloki TesseractException i DllNotFoundException Catch stają się niedostępne
TesseractOCR: Produkcyjne integracjeTesseractOCRwychwytują TesseractOCR.Exceptions.TesseractException, DllNotFoundException (dla brakujących natywnych binariów) i BadImageFormatException (dla niezgodności architektury). Te typy wyjątków są reakcją obronną na niestabilność tessdata i natywnego wdrażania plików binarnych.
**Rozwiązanie:**IronOCRłączy natywne zależności i zarządza inicjalizacją wewnętrznie. DllNotFoundException i BadImageFormatException nie mają zastosowania. Usuń te bloki catch. Powierzchnia wyjątków redukuje się do IronOcr.Exceptions.OcrException dla błędów OCR i standardowego IOException dla problemów z dostępem do plików.
// Before: five exception types to handle
catch (TesseractOCR.Exceptions.TesseractException ex) { ... }
catch (DllNotFoundException ex) { ... }
catch (BadImageFormatException ex) { ... }
catch (OutOfMemoryException ex) { ... }
// After: two exception types
catch (IronOcr.Exceptions.OcrException ex) { ... }
catch (IOException ex) { ... }
Lista kontrolna migracji TesseractOCR
Przed migracją
Sprawdź wszystkie miejsca użyciaTesseractOCRw kodzie:
grep -rn "using TesseractOCR" --include="*.cs" .
grep -rn "new Engine(" --include="*.cs" .
grep -rn "Pix\.Image\.LoadFromFile\|engine\.Process\|page\.Text\|MeanConfidence" --include="*.cs" .
grep -rn "Language\." --include="*.cs" .
Zidentyfikuj całą infrastrukturę pomocniczą, która zostanie usunięta:
grep -rn "using Docnet\|using SixLabors\|GetTempFileName\|SaveBgraAsPng" --include="*.cs" .
grep -rn "tessdata" --include="*.cs" .
grep -rn "tessdata" --include="*.csproj" .
grep -rn "tessdata" Dockerfile 2>/dev/null || true
Przed migracją należy udokumentować aktualny poziom dokładności na reprezentatywnej próbie dokumentów, aby można było zweryfikować jakość po migracji.
Migracja kodu
- Uruchom
dotnet remove package TesseractOCR - Uruchom
dotnet remove package Docnet.Core(jeśli obecny) - Uruchom
dotnet remove package SixLabors.ImageSharp(jeśli dodany do przetwarzania wstępnego) - Uruchom
dotnet add package IronOcr - Dodaj
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"przy starcie aplikacji - Zastąp
using TesseractOCRiusing TesseractOCR.Enumsprzezusing IronOcr - Zastąp
new Engine(tessDataPath, Language.English, EngineMode.Default)przeznew IronTesseract() - Zastąp
TesseractOCR.Pix.Image.LoadFromFile(path)przezinput.LoadImage(path)na instancjiOcrInput - Zastąp
engine.Process(pixImage)przezocr.Read(input) - Zastąp
page.Textprzezresult.Text - Zaktualizuj porównania progów pewności — pomnóż wszystkie wartości z przedziału 0,0–1,0 przez 100 dla skali IronOCR 0–100
- Zastąp
Language.X | Language.YwithOcrLanguage.X + OcrLanguage.Y - Usuń wszystkie metody pomocnicze do przetwarzania wstępnego (
SaveBgraAsPng, ręczne łańcuchy filtrów, logikę plików tymczasowych) - Zastąp pętle renderowania PDF Docnet przez
input.LoadPdf(path)lubinput.LoadPdfPages(path, start, end) - Zastąp pętle TIFF z wieloma ramkami przez
input.LoadImageFrames(tiffPath) - Zastąp
File.WriteAllBytes(tempPath, bytes)+LoadFromFile(tempPath)przezinput.LoadImage(bytes) - Zaktualizuj bloki catch — usuń
TesseractException,DllNotFoundException,BadImageFormatException - Usuń folder tessdata z konfiguracji katalogu wyjściowego projektu i obrazów Docker
Po migracji
- Potwierdź, że
dotnet buildgeneruje zero błędów kompilatora i zero ostrzeżeń o niedostępnych blokach catch - Uruchom OCR na próbce referencyjnej dokładności sprzed migracji i porównaj wyniki
- Sprawdź, czy wielo-stronicowe pliki TIFF generują prawidłową liczbę wyodrębnionych stron
- Upewnij się, że plik PDF z możliwością wyszukiwania otwiera się w przeglądarce PDF z możliwością zaznaczania tekstu
- Przetestuj ścieżki wejściowe tablicy bajtów i strumienia z rzeczywistych źródeł danych aplikacji
- Sprawdź, czy wartości pewności na poziomie WORD mieszczą się w przedziale 0–100 (a nie 0,0–1,0)
- Przeprowadź testy przetwarzania równoległego, aby upewnić się, że nie pojawiają się ostrzeżenia dotyczące alokacji silnika na wątek
- Wdróż do docelowego środowiska (Docker, Azure, Linux) i potwierdź, że IronOCR inicjalizuje się bez
DllNotFoundException - Zweryfikuj, że żadna teczka tessdata ani plik
.traineddatanie są odwołane w żadnych skryptach wdrożeniowych
Kluczowe korzyści z migracji do IronOCR
Przetwarzanie wstępne staje się konfiguracją jednolinijkową, a nie zależnością stu-liniową. Po migracji, input.Deskew(), input.DeNoise() i input.Contrast() zastępują zewnętrzną bibliotekę obrazów, ręczne dostrajanie parametrów i zapis pliku tymczasowego, który łączył obie. Zdjęcia z telefonu, przekrzywione skany i faksy o niskim kontraście — typy dokumentów, które wcześniej wymagały zaangażowania inżyniera ds. przetwarzania wstępnego — generują niezawodne wyniki dzięki wbudowanemu potokowi. Strona funkcji przetwarzania wstępnego zawiera listę wszystkich dostępnych filtrów.
PDF jest formatem wejściowym i wyjściowym pierwszej klasy. Zależność od Docnet, pomocnik konwersji BGRA na PNG, pętla zarządzania plikami tymczasowymi, trzecia biblioteka do obsługi plików chronionych hasłem — wszystko to znika. Każdy PDF przybywający do systemu trafia bezpośrednio do input.LoadPdf(). Każdy zeskanowany dokument, który musi stać się przeszukiwalny, przechodzi przez result.SaveAsSearchablePdf(). Cały proces przetwarzania plików PDF, który wTesseractOCRwymagał ponad 100 linii kodu, sprowadza się do kilku wywołań metod. Zapoznaj się ze stroną poświęconą zastosowaniom OCR w plikach PDF, aby poznać pełen zakres obsługiwanych procesów związanych z plikami PDF.
Strukturalne wyjście zastępuje płaskie łańcuchy tekstowe. result.Pages, result.Paragraphs, result.Lines i result.Words ujawniają strukturę dokumentu wraz z koordynatami dla każdego elementu i ocenami pewności dla każdego słowa. W procesach, które wcześniej wymagały heurystycznego parsowania w celu znalezienia określonych pól — numerów faktur, dat, kwot — można teraz zamiast tego używać współrzędnych na poziomie słów i filtrowania na podstawie pewności. Stanowi to podstawę do tworzenia niezawodnych procesów ekstrakcji formularzy i przetwarzania dokumentów w oparciu o funkcje wyników OCR IronOCR.
Wdrożenie przestaje wymagać orkiestracji tessdata. Teczka tessdata, skrypty pobierania curl, warstwa Docker COPY ./tessdata, konfiguracja pamięci podręcznej CI/CD dla plików .traineddata — to wszystko znika. Języki są dostarczane jako pakiety NuGet, wersjonowane, przywracane wraz z pozostałymi zależnościami projektu i wdrażane w identyczny sposób, niezależnie od tego, czy celem jest stacja robocza programisty, kontener Docker, usługa Azure App Service czy AWS Lambda. Przewodnik wdrażania platformy Azure oraz przewodnik wdrażania systemu Linux zawierają sprawdzone konfiguracje dla środowisk produkcyjnych.
**Model licencjonowania jest przewidywalny.**TesseractOCRjest bezpłatny, ale wymagana infrastruktura już nie — czas programisty na wdrożenie przetwarzania wstępnego, ocenę biblioteki PDF, tworzenie skryptów wdrażania tessdata oraz bieżącą konserwację łańcucha zależności zewnętrznych. Wieczysta licencja IronOCR($999 Lite, $1,499 Professional, $2,399 Enterprise) to jednorazowy koszt zastępujący tygodnie pracy infrastrukturalnej i eliminujący powierzchnię konserwacji cyklicznej. Komercjalne wsparcie z gwarantowaną ścieżką odpowiedzi zastępuje poleganie na kolejce zgłoszeń na GitHubie prowadzonej przez jednego wolontariusza.
