OCR API:Microsoft Azure Vision 與 IronOCR:哪個更擅長處理文件影像?
在您從Tesseract讀取單一OCR結果之前,您已經撰寫了一個前處理管道——灰階轉換、對比度增強、二值化、噪點移除、傾斜校正、DPI縮放——大約180行的圖像處理程式碼,與文字識別無關。 這是charlesw Tesseract包裝器的真正成本:不是零元的授權費,而是花費20-40小時的工程工作,以便在非理想條件下可靠地運行引擎處理文件。 然後您發現應用程式接收PDF,因此需要使用一個PDF渲染程式庫重新啟動整個管道。
理解Tesseract
Tesseract NuGet套件 (charlesw包裝器) 是一個P/Invoke橋樑,將本機Tesseract OCR引擎曝露給.NET應用程式。 它包裝了Leptonica圖像處理程式庫和Tesseract引擎二進制檔,使C#開發者能夠直接存取一個最強大的開源OCR引擎。
Tesseract本身是開源世界中OCR的骨幹。 最初由Hewlett-Packard於1980年代開發,並於2005年由Google開源,僅透過charlesw包裝器就積累了近800萬次NuGet下載。 這個數字反映了其真實的有用性,而不是一個小眾項目。 當圖像乾淨且格式良好時,Tesseract在最少配置下達到95%+的準確率。
每個生產環境中使用此程式庫的關鍵架構事實:。
- 僅圖像輸入: Tesseract處理圖像。 它沒有內建的PDF渲染器。 每個PDF工作流需要一個單獨的程式庫(PdfiumViewer、PDFtoImage、Docnet.Core、GhostScript)來將每個頁面轉換為圖像,這樣Tesseract才能處理它。
- 需要手動前處理: Tesseract期望接收到乾淨、高解析度、方向正確的圖像。 它沒有提供內建的濾鏡。 傾斜、噪點、低DPI和色彩背景都會在未經校正的情況下降低準確性,而這種校正完全由開發者負責。
- Tessdata檔案管理: 語言識別依賴於從GitHub下載的
tessdata資料夾中。 每個語言檔案為15至100 MB。 每個環境——開發、CI、測試、正式、Docker——都必須在正確的路徑下具備正確的檔案。 - 本地二進制部署: 包裝器附帶平台特定的本地程式庫(
tesseract50.dll,leptonica-1.82.0.dll在Windows上; Linux上的.so檔案)。 這些必須與應用程式同時部署,並與目標架構匹配。 - 非執行緒安全引擎:
TesseractEngine實例不能跨執行緒共享。 並行處理需要為每個執行緒建立一個引擎,將引擎初始化的40-100 MB記憶體佔用量按並行程度進行乘算。 - 固定在4.1.1版本的Tesseract: charlesw包裝器跟蹤Tesseract 4.1.1,於2019年發布。不提供Tesseract 5.x的提升LSTM準確率的版本。
前處理缺口
這個前處理需求並不是您可以跳過的配置選項。這正是生產準確性與現實世界文件中不可用結果之間的差異。 image-preprocessing-tesseract.cs 的來源檔案記錄了完整的手動管道:
// Tesseract requires every one of these steps to be written manually
public static string ExtractWithPreprocessing(string imagePath)
{
using (var original = new Bitmap(imagePath))
{
// Step 2: Convert to grayscale (~25 lines)
using (var grayscale = ConvertToGrayscale(original))
{
// Step 3: Apply contrast enhancement (~15 lines)
using (var enhanced = EnhanceContrast(grayscale))
{
// Step 4: Binarize — convert to black and white (~15 lines)
using (var binarized = Binarize(enhanced, 128))
{
// Step 5: Remove noise (~25 lines)
using (var denoised = RemoveNoise(binarized))
{
// Step 6: Deskew if rotated (~50 lines, simplified)
using (var deskewed = Deskew(denoised))
{
// Step 7: Scale to 300 DPI (~20 lines)
using (var scaled = ScaleToDpi(deskewed, 300))
{
return RunTesseract(scaled); // Save to temp file, load Pix, process
}
}
}
}
}
}
}
}
// Tesseract requires every one of these steps to be written manually
public static string ExtractWithPreprocessing(string imagePath)
{
using (var original = new Bitmap(imagePath))
{
// Step 2: Convert to grayscale (~25 lines)
using (var grayscale = ConvertToGrayscale(original))
{
// Step 3: Apply contrast enhancement (~15 lines)
using (var enhanced = EnhanceContrast(grayscale))
{
// Step 4: Binarize — convert to black and white (~15 lines)
using (var binarized = Binarize(enhanced, 128))
{
// Step 5: Remove noise (~25 lines)
using (var denoised = RemoveNoise(binarized))
{
// Step 6: Deskew if rotated (~50 lines, simplified)
using (var deskewed = Deskew(denoised))
{
// Step 7: Scale to 300 DPI (~20 lines)
using (var scaled = ScaleToDpi(deskewed, 300))
{
return RunTesseract(scaled); // Save to temp file, load Pix, process
}
}
}
}
}
}
}
}
Imports System.Drawing
Public Class ImageProcessor
' Tesseract requires every one of these steps to be written manually
Public Shared Function ExtractWithPreprocessing(imagePath As String) As String
Using original As New Bitmap(imagePath)
' Step 2: Convert to grayscale (~25 lines)
Using grayscale As Bitmap = ConvertToGrayscale(original)
' Step 3: Apply contrast enhancement (~15 lines)
Using enhanced As Bitmap = EnhanceContrast(grayscale)
' Step 4: Binarize — convert to black and white (~15 lines)
Using binarized As Bitmap = Binarize(enhanced, 128)
' Step 5: Remove noise (~25 lines)
Using denoised As Bitmap = RemoveNoise(binarized)
' Step 6: Deskew if rotated (~50 lines, simplified)
Using deskewed As Bitmap = Deskew(denoised)
' Step 7: Scale to 300 DPI (~20 lines)
Using scaled As Bitmap = ScaleToDpi(deskewed, 300)
Return RunTesseract(scaled) ' Save to temp file, load Pix, process
End Using
End Using
End Using
End Using
End Using
End Using
End Using
End Function
' Placeholder methods for conversion
Private Shared Function ConvertToGrayscale(original As Bitmap) As Bitmap
' Implementation here
Return Nothing
End Function
Private Shared Function EnhanceContrast(grayscale As Bitmap) As Bitmap
' Implementation here
Return Nothing
End Function
Private Shared Function Binarize(enhanced As Bitmap, threshold As Integer) As Bitmap
' Implementation here
Return Nothing
End Function
Private Shared Function RemoveNoise(binarized As Bitmap) As Bitmap
' Implementation here
Return Nothing
End Function
Private Shared Function Deskew(denoised As Bitmap) As Bitmap
' Implementation here
Return Nothing
End Function
Private Shared Function ScaleToDpi(deskewed As Bitmap, dpi As Integer) As Bitmap
' Implementation here
Return Nothing
End Function
Private Shared Function RunTesseract(scaled As Bitmap) As String
' Implementation here
Return Nothing
End Function
End Class
那個巢狀的using結構不是樣板程式碼——每一個步驟都是一個完整的實現:灰階的色彩矩陣、對比度的像素迭代、二值化的另一個像素迭代、噪點的中值濾波器,以及傾斜校正的Hough變換替代品。 image-preprocessing-tesseract.cs來源直接註明:"簡化的傾斜校正——真正的實現需要Hough變換。 這通常需要使用OpenCV或類似的程式庫。"
總計:在讀取單詞之前大約180行。 同一個檔案中的準確性表格顯示為何這項投資是有必要的——在傾斜5度的文件上,未經前處理的Tesseract能產生60-70%的準確率,而妥善前處理後的輸入可達到90%+。
理解 IronOCR
IronOCR 是一個商業.NET OCR程式庫,內嵌了一個優化的Tesseract 5 LSTM引擎,並配有內建的前處理管道、原生PDF支持和無需本地二進制管理的管理API。 該程式庫以單一NuGet套件的形式安裝,無需tessdata資料夾,無需針對平台的DLL部署步驟,也無需額外的PDF渲染程式庫。
定義IronOCR設計的關鍵特徵:
- 自動前處理: Deskew, DeNoise, Contrast, Binarize和EnhanceResolution都是
OcrInput上的單行方法調用。 引擎在OCR開始之前還會預設應用智能自動前處理。 - 原生PDF輸入:
input.LoadPdf()接受掃描的PDF、數位PDF和混合PDF,無需外部依賴。 對於加密保護的PDF,需要額外的參數。 - 超過125個語言包(NuGet): 語言包安裝為標準的NuGet套件——
IronOcr.Languages.French,IronOcr.Languages.Arabic,無需資料夾管理或路徑配置。 - 執行緒安全的
IronTesseract實例: 單一實例同時服務於所有執行緒。 並行的批次處理不需為每個執行緒初始化引擎。 - 跨平台單一套件: Windows、Linux、macOS、Docker、Azure和AWS均可從同一個NuGet套件部署,無需平台特定配置。
- 可搜尋的PDF輸出: OCR結果可以在一次方法調用中轉換為可搜索的PDF。
- 價格: $999 Lite永久/$1,499 Plus/$2,999 Professional/$5,999 無限——一次購買, 無需逐個文件收費。
功能比較
| 功能 | Tesseract(charlesw) | IronOCR |
|---|---|---|
| 授權 | Apache 2.0(免費) | 商業($999+永久) |
| PDF輸入 | 無——需要外部程式庫 | 原生內建 |
| 圖像預處理 | 手動——100多行程式碼 | 自動+單行方法 |
| 語言管理 | 手動tessdata文件下載 | NuGet套件安裝 |
| 執行緒安全 | 不執行緒安全(每執行緒一引擎) | 執行緒安全單一實例 |
| 部署 | 本地DLL+tessdata資料夾 | 單一NuGet包 |
| Tesseract版本 | 4.1.1(2019) | 5.x優化 |
詳細功能比較
| 類別 / 功能 | Tesseract(charlesw) | IronOCR |
|---|---|---|
| 設置和安裝 | ||
| NuGet安裝 | Install-Package Tesseract |
Install-Package IronOcr |
| 額外的安裝步驟 | tessdata下載+路徑配置 | None |
| 原生二進制部署 | 需要 | 捆綁包 |
| Docker設置 | apt-get+tessdata複製 | 不需額外步驟 |
| 安裝時間估計 | 2-4小時 | 5 分鐘 |
| 預處理 | ||
| 糾偏 | 手動(50多行) | input.Deskew() |
| 降噪 | 手動(25多行) | input.DeNoise() |
| 對比增強 | 手動(15多行) | input.Contrast() |
| 二值化 | 手動(15多行) | input.Binarize() |
| 解析度縮放 | 手動(20多行) | input.EnhanceResolution(300) |
| 總前處理LOC | 約180行 | 1-10行 |
| PDF 支持 | ||
| 讀取掃描的PDF | 不原生支持 | 本地 |
| 讀取數位PDF | 不原生支持 | 本地 |
| 受密碼保護的PDF | 需要解密程式庫 | 一個參數 |
| 頁面範圍選擇 | 手動(通過PDF程式庫) | input.LoadPdfPages() |
| 建立可搜尋的PDF | 不支持 | result.SaveAsSearchablePdf() |
| 語言支持 | ||
| 英語 | 包含(需要檔案) | 包含 |
| 額外的語言 | 手動.traineddata下載 | NuGet套件 |
| 語言數量 | 100+(手動管理) | 125+(NuGet) |
| 多語言一次調用 | "eng+fra+deu"字串 |
AddSecondaryLanguage() |
| 執行緒處理 | ||
| 執行緒安全的引擎 | 不是 | 是 |
| 並行處理 | 每執行緒建立引擎 | 共享的單個實例 |
| 每執行緒記憶體 | 每個40-100 MB | 共享池 |
| 輸出和結果 | ||
| 純文字 | page.GetText() |
result.Text |
| 單詞級邊界框 | ResultIterator迴圈 |
result.WordsLINQ |
| 信心分數 | page.GetMeanConfidence() |
result.Confidence |
| 可搜尋的PDF | 不支持 | result.SaveAsSearchablePdf() |
| hOCR匯出 | page.GetHOCRText() |
result.SaveAsHocrFile() |
| 條碼檢測 | 不支持 | ocr.Configuration.ReadBarCodes = true |
| 平台支持 | ||
| Windows | 是 | 是 |
| Linux | 需要編譯/apt-get | 是 |
| macOS | 需要手動設置 | 是 |
| Docker | 多步驟設置 | 開箱即用 |
前處理缺口
前處理需求是20-40小時時間估計的來源。 這不是誇張。 從頭開始用Tesseract建立可靠的前處理管道意味着實現IronOCR內建的每一個轉換。
Tesseract方法
image-preprocessing-tesseract.cs中顯示的完整前處理管道需要System.Drawing.Common(僅Windows)或另外一個跨平台的程式庫如ImageSharp。單是傾斜校正實現就已註明它是簡化版——生產級的傾斜檢測算法需要Hough線變換,這意味著通常需要引入OpenCvSharp4作為額外依賴:
// image-preprocessing-tesseract.cs — the actual implementation pattern
private static Bitmap ConvertToGrayscale(Bitmap original)
{
var result = new Bitmap(original.Width, original.Height);
using (var graphics = Graphics.FromImage(result))
{
var colorMatrix = new ColorMatrix(new float[][]
{
new float[] { 0.299f, 0.299f, 0.299f, 0, 0 },
new float[] { 0.587f, 0.587f, 0.587f, 0, 0 },
new float[] { 0.114f, 0.114f, 0.114f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
using (var attributes = new ImageAttributes())
{
attributes.SetColorMatrix(colorMatrix);
graphics.DrawImage(original,
new Rectangle(0, 0, original.Width, original.Height),
0, 0, original.Width, original.Height,
GraphicsUnit.Pixel, attributes);
}
}
return result;
}
private static Bitmap EnhanceContrast(Bitmap image)
{
var result = new Bitmap(image.Width, image.Height);
float contrast = 1.5f;
for (int y = 0; y < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
{
var pixel = image.GetPixel(x, y);
int r = Clamp((int)((pixel.R - 128) * contrast + 128));
int g = Clamp((int)((pixel.G - 128) * contrast + 128));
int b = Clamp((int)((pixel.B - 128) * contrast + 128));
result.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
return result;
}
private static Bitmap RemoveNoise(Bitmap image)
{
var result = new Bitmap(image.Width, image.Height);
int kernelSize = 3;
int radius = kernelSize / 2;
for (int y = radius; y < image.Height - radius; y++)
{
for (int x = radius; x < image.Width - radius; x++)
{
var pixels = new List<int>();
for (int ky = -radius; ky <= radius; ky++)
for (int kx = -radius; kx <= radius; kx++)
pixels.Add(image.GetPixel(x + kx, y + ky).R);
pixels.Sort();
int median = pixels[pixels.Count / 2];
result.SetPixel(x, y, Color.FromArgb(median, median, median));
}
}
return result;
}
// After all preprocessing, save to temp file — Tesseract requires a file path
private static string RunTesseract(Bitmap preprocessed)
{
string tempPath = Path.GetTempFileName() + ".png";
try
{
preprocessed.Save(tempPath, ImageFormat.Png);
using (var engine = new TesseractEngine(TessDataPath, "eng", EngineMode.Default))
using (var img = Pix.LoadFromFile(tempPath))
using (var page = engine.Process(img))
return page.GetText();
}
finally
{
if (File.Exists(tempPath)) File.Delete(tempPath);
}
}
// image-preprocessing-tesseract.cs — the actual implementation pattern
private static Bitmap ConvertToGrayscale(Bitmap original)
{
var result = new Bitmap(original.Width, original.Height);
using (var graphics = Graphics.FromImage(result))
{
var colorMatrix = new ColorMatrix(new float[][]
{
new float[] { 0.299f, 0.299f, 0.299f, 0, 0 },
new float[] { 0.587f, 0.587f, 0.587f, 0, 0 },
new float[] { 0.114f, 0.114f, 0.114f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
using (var attributes = new ImageAttributes())
{
attributes.SetColorMatrix(colorMatrix);
graphics.DrawImage(original,
new Rectangle(0, 0, original.Width, original.Height),
0, 0, original.Width, original.Height,
GraphicsUnit.Pixel, attributes);
}
}
return result;
}
private static Bitmap EnhanceContrast(Bitmap image)
{
var result = new Bitmap(image.Width, image.Height);
float contrast = 1.5f;
for (int y = 0; y < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
{
var pixel = image.GetPixel(x, y);
int r = Clamp((int)((pixel.R - 128) * contrast + 128));
int g = Clamp((int)((pixel.G - 128) * contrast + 128));
int b = Clamp((int)((pixel.B - 128) * contrast + 128));
result.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
return result;
}
private static Bitmap RemoveNoise(Bitmap image)
{
var result = new Bitmap(image.Width, image.Height);
int kernelSize = 3;
int radius = kernelSize / 2;
for (int y = radius; y < image.Height - radius; y++)
{
for (int x = radius; x < image.Width - radius; x++)
{
var pixels = new List<int>();
for (int ky = -radius; ky <= radius; ky++)
for (int kx = -radius; kx <= radius; kx++)
pixels.Add(image.GetPixel(x + kx, y + ky).R);
pixels.Sort();
int median = pixels[pixels.Count / 2];
result.SetPixel(x, y, Color.FromArgb(median, median, median));
}
}
return result;
}
// After all preprocessing, save to temp file — Tesseract requires a file path
private static string RunTesseract(Bitmap preprocessed)
{
string tempPath = Path.GetTempFileName() + ".png";
try
{
preprocessed.Save(tempPath, ImageFormat.Png);
using (var engine = new TesseractEngine(TessDataPath, "eng", EngineMode.Default))
using (var img = Pix.LoadFromFile(tempPath))
using (var page = engine.Process(img))
return page.GetText();
}
finally
{
if (File.Exists(tempPath)) File.Delete(tempPath);
}
}
Imports System.Drawing
Imports System.Drawing.Imaging
Imports Tesseract
Imports System.IO
' image-preprocessing-tesseract.vb — the actual implementation pattern
Private Shared Function ConvertToGrayscale(original As Bitmap) As Bitmap
Dim result As New Bitmap(original.Width, original.Height)
Using graphics As Graphics = Graphics.FromImage(result)
Dim colorMatrix As New ColorMatrix(New Single()() {
New Single() {0.299F, 0.299F, 0.299F, 0, 0},
New Single() {0.587F, 0.587F, 0.587F, 0, 0},
New Single() {0.114F, 0.114F, 0.114F, 0, 0},
New Single() {0, 0, 0, 1, 0},
New Single() {0, 0, 0, 0, 1}
})
Using attributes As New ImageAttributes()
attributes.SetColorMatrix(colorMatrix)
graphics.DrawImage(original, New Rectangle(0, 0, original.Width, original.Height), 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes)
End Using
End Using
Return result
End Function
Private Shared Function EnhanceContrast(image As Bitmap) As Bitmap
Dim result As New Bitmap(image.Width, image.Height)
Dim contrast As Single = 1.5F
For y As Integer = 0 To image.Height - 1
For x As Integer = 0 To image.Width - 1
Dim pixel As Color = image.GetPixel(x, y)
Dim r As Integer = Clamp(CInt((pixel.R - 128) * contrast + 128))
Dim g As Integer = Clamp(CInt((pixel.G - 128) * contrast + 128))
Dim b As Integer = Clamp(CInt((pixel.B - 128) * contrast + 128))
result.SetPixel(x, y, Color.FromArgb(r, g, b))
Next
Next
Return result
End Function
Private Shared Function RemoveNoise(image As Bitmap) As Bitmap
Dim result As New Bitmap(image.Width, image.Height)
Dim kernelSize As Integer = 3
Dim radius As Integer = kernelSize \ 2
For y As Integer = radius To image.Height - radius - 1
For x As Integer = radius To image.Width - radius - 1
Dim pixels As New List(Of Integer)()
For ky As Integer = -radius To radius
For kx As Integer = -radius To radius
pixels.Add(image.GetPixel(x + kx, y + ky).R)
Next
Next
pixels.Sort()
Dim median As Integer = pixels(pixels.Count \ 2)
result.SetPixel(x, y, Color.FromArgb(median, median, median))
Next
Next
Return result
End Function
' After all preprocessing, save to temp file — Tesseract requires a file path
Private Shared Function RunTesseract(preprocessed As Bitmap) As String
Dim tempPath As String = Path.GetTempFileName() & ".png"
Try
preprocessed.Save(tempPath, ImageFormat.Png)
Using engine As New TesseractEngine(TessDataPath, "eng", EngineMode.Default)
Using img As Pix = Pix.LoadFromFile(tempPath)
Using page As Page = engine.Process(img)
Return page.GetText()
End Using
End Using
End Using
Finally
If File.Exists(tempPath) Then File.Delete(tempPath)
End Try
End Function
Private Shared Function Clamp(value As Integer) As Integer
Return Math.Max(0, Math.Min(255, value))
End Function
Private Const TessDataPath As String = "path_to_tessdata" ' Define the path to tessdata directory
這是真正來自源文件的程式碼——不是捏造出的最壞情況。 對比度和噪點移除的像素迭代方法在每個像素上以O(n²)運行。 臨時檔案保存和載入不是可選的; Pix.LoadFromFile需要磁碟上的檔案路徑。 對於一天處理1000份掃描文件的應用程式,這在OCR時間之外是可以測量的開銷。
IronOCR方法
在IronOCR中相同的前處理是一系列在OcrInput上的方法調用:
// dotnet add package IronOcr
using IronOcr;
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");
input.Deskew(); // Detects and corrects skew angle automatically
input.DeNoise(); // Removes scanner artifacts and specks
input.Contrast(); // Enhances contrast for character separation
input.Binarize(); // Converts to black and white with adaptive threshold
input.EnhanceResolution(300); // Scales to 300 DPI for optimal recognition
var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
Console.WriteLine(result.Text);
// dotnet add package IronOcr
using IronOcr;
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");
input.Deskew(); // Detects and corrects skew angle automatically
input.DeNoise(); // Removes scanner artifacts and specks
input.Contrast(); // Enhances contrast for character separation
input.Binarize(); // Converts to black and white with adaptive threshold
input.EnhanceResolution(300); // Scales to 300 DPI for optimal recognition
var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
Console.WriteLine(result.Text);
Imports IronOcr
Dim input As New OcrInput()
input.LoadImage("low-quality-scan.jpg")
input.Deskew() ' Detects and corrects skew angle automatically
input.DeNoise() ' Removes scanner artifacts and specks
input.Contrast() ' Enhances contrast for character separation
input.Binarize() ' Converts to black and white with adaptive threshold
input.EnhanceResolution(300) ' Scales to 300 DPI for optimal recognition
Using input
Dim result = New IronTesseract().Read(input)
Console.WriteLine($"Confidence: {result.Confidence}%")
Console.WriteLine(result.Text)
End Using
沒有臨時檔案。 沒有像素迭代。 沒有對System.Drawing.Common或OpenCvSharp4的依賴。圖像質量校正指南和圖像方向校正指南涵蓋了完整的過濾器目錄——有超過15種可用。 圖像濾鏡範例顯示了低質量掃描管道從開始到結束。
對於大多數現實世界的文件,預設讀取會在不顯式調用濾鏡的情況下應用智能自動前處理:
// Automatic preprocessing applied internally — no explicit filter calls needed
var text = new IronTesseract().Read("scanned-invoice.jpg").Text;
// Automatic preprocessing applied internally — no explicit filter calls needed
var text = new IronTesseract().Read("scanned-invoice.jpg").Text;
Imports IronTesseract
' Automatic preprocessing applied internally — no explicit filter calls needed
Dim text As String = New IronTesseract().Read("scanned-invoice.jpg").Text
在乾淨、高DPI輸入上這不會花費任何代價。 在72 DPI的手機照片上,引擎在識別文字之前會縮放、增強和常態化。
PDF缺口
PDF是商業文件的標準傳遞格式。 合同、發票、銀行報表、醫療記錄——它們都以PDF形式到達。 Tesseract無法開啟PDF。 搭建橋樑需要另一個程式庫,另一個本機依賴,和50-150行的粘合程式碼。
Tesseract方法
pdf-ocr-processing-tesseract.cs檔案記錄了三種不同的PDF渲染程式庫選擇——PdfiumViewer、PDFtoImage、和Docnet.Core——每個都有不同的依賴鏈和權衡。 那個檔案中顯示的PdfiumViewer模式具有代表性:
// Tesseract PDF processing — from pdf-ocr-processing-tesseract.cs
// Requires: PdfiumViewer NuGet + pdfium native DLL deployed to application directory
// NuGet: PdfiumViewer, PdfiumViewer.Native.x64
using PdfiumViewer;
public static string ExtractFromPdfWithPdfium(string pdfPath)
{
var results = new List<string>();
using (var document = PdfDocument.Load(pdfPath))
{
using (var engine = new TesseractEngine(TessDataPath, "eng", EngineMode.Default))
{
for (int pageIndex = 0; pageIndex < document.PageCount; pageIndex++)
{
// Render page to image at 300 DPI
using (var pageImage = document.Render(pageIndex, 300, 300,
PdfRenderFlags.CorrectFromDpi))
{
// Tesseract requires a file path — must write to disk first
string tempPath = Path.GetTempFileName() + ".png";
try
{
pageImage.Save(tempPath);
using (var img = Pix.LoadFromFile(tempPath))
using (var page = engine.Process(img))
results.Add(page.GetText());
}
finally
{
File.Delete(tempPath); // Must clean up or disk fills
}
}
}
}
}
return string.Join("\n\n--- Page Break ---\n\n", results);
}
// Tesseract PDF processing — from pdf-ocr-processing-tesseract.cs
// Requires: PdfiumViewer NuGet + pdfium native DLL deployed to application directory
// NuGet: PdfiumViewer, PdfiumViewer.Native.x64
using PdfiumViewer;
public static string ExtractFromPdfWithPdfium(string pdfPath)
{
var results = new List<string>();
using (var document = PdfDocument.Load(pdfPath))
{
using (var engine = new TesseractEngine(TessDataPath, "eng", EngineMode.Default))
{
for (int pageIndex = 0; pageIndex < document.PageCount; pageIndex++)
{
// Render page to image at 300 DPI
using (var pageImage = document.Render(pageIndex, 300, 300,
PdfRenderFlags.CorrectFromDpi))
{
// Tesseract requires a file path — must write to disk first
string tempPath = Path.GetTempFileName() + ".png";
try
{
pageImage.Save(tempPath);
using (var img = Pix.LoadFromFile(tempPath))
using (var page = engine.Process(img))
results.Add(page.GetText());
}
finally
{
File.Delete(tempPath); // Must clean up or disk fills
}
}
}
}
}
return string.Join("\n\n--- Page Break ---\n\n", results);
}
Imports PdfiumViewer
Imports Tesseract
Public Shared Function ExtractFromPdfWithPdfium(pdfPath As String) As String
Dim results As New List(Of String)()
Using document = PdfDocument.Load(pdfPath)
Using engine = New TesseractEngine(TessDataPath, "eng", EngineMode.Default)
For pageIndex As Integer = 0 To document.PageCount - 1
' Render page to image at 300 DPI
Using pageImage = document.Render(pageIndex, 300, 300, PdfRenderFlags.CorrectFromDpi)
' Tesseract requires a file path — must write to disk first
Dim tempPath As String = Path.GetTempFileName() & ".png"
Try
pageImage.Save(tempPath)
Using img = Pix.LoadFromFile(tempPath)
Using page = engine.Process(img)
results.Add(page.GetText())
End Using
End Using
Finally
File.Delete(tempPath) ' Must clean up or disk fills
End Try
End Using
Next
End Using
End Using
Return String.Join(vbCrLf & vbCrLf & "--- Page Break ---" & vbCrLf & vbCrLf, results)
End Function
pdf-ocr-processing-tesseract.cs來源直接註明了依賴鏈:"Tesseract:Apache 2.0,PdfiumViewer:BSD,iText:AGPL或商業,GhostScript:AGPL或商業。"最後一項在企業環境中很重要——GhostScript的AGPL授權要求您的應用程式開源,除非您購買商業的GhostScript授權。
加密保護的PDF增加了另一層。 同一檔案中的NotImplementedException,並附有評論:"需要具有加密支持的PDF程式庫(iText,PDFSharp)。 Tesseract不能解密PDF。"因此密碼保護意味著具有自身授權考量的第四個依賴。
IronOCR方法
IronOCR原生支持PDF,包括掃描的PDF、數位文字PDF、混合內容PDF和加密保護的PDF:
// dotnet add package IronOcr
using IronOcr;
// Scanned PDF — direct load, no rendering library required
var result = new IronTesseract().Read("scanned-contract.pdf");
Console.WriteLine(result.Text);
// Password-protected PDF — one additional parameter
using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");
var protectedResult = new IronTesseract().Read(input);
// Specific page range from a 200-page document
using var rangeInput = new OcrInput();
rangeInput.LoadPdfPages("large-report.pdf", 1, 10);
var rangeResult = new IronTesseract().Read(rangeInput);
// Create searchable PDF with embedded text layer
var searchable = new IronTesseract().Read("scanned-invoice.pdf");
searchable.SaveAsSearchablePdf("searchable-invoice.pdf");
// dotnet add package IronOcr
using IronOcr;
// Scanned PDF — direct load, no rendering library required
var result = new IronTesseract().Read("scanned-contract.pdf");
Console.WriteLine(result.Text);
// Password-protected PDF — one additional parameter
using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");
var protectedResult = new IronTesseract().Read(input);
// Specific page range from a 200-page document
using var rangeInput = new OcrInput();
rangeInput.LoadPdfPages("large-report.pdf", 1, 10);
var rangeResult = new IronTesseract().Read(rangeInput);
// Create searchable PDF with embedded text layer
var searchable = new IronTesseract().Read("scanned-invoice.pdf");
searchable.SaveAsSearchablePdf("searchable-invoice.pdf");
Imports IronOcr
' Scanned PDF — direct load, no rendering library required
Dim result = New IronTesseract().Read("scanned-contract.pdf")
Console.WriteLine(result.Text)
' Password-protected PDF — one additional parameter
Using input As New OcrInput()
input.LoadPdf("encrypted.pdf", Password:="secret")
Dim protectedResult = New IronTesseract().Read(input)
End Using
' Specific page range from a 200-page document
Using rangeInput As New OcrInput()
rangeInput.LoadPdfPages("large-report.pdf", 1, 10)
Dim rangeResult = New IronTesseract().Read(rangeInput)
End Using
' Create searchable PDF with embedded text layer
Dim searchable = New IronTesseract().Read("scanned-invoice.pdf")
searchable.SaveAsSearchablePdf("searchable-invoice.pdf")
無需PDF渲染程式庫。 沒有臨時檔案。 無需AGPL授權考量。 PDF輸入指南涵蓋了所有PDF輸入變體。 可搜尋的PDF指南解釋了文字層輸出。 對於構建文件處理管道的團隊,PDF OCR用案例頁面提供了生產架構樣式。
前處理方法在PDF輸入上同樣有效,允許在掃描PDF上進行相同的input.Deskew(), input.DeNoise(), input.EnhanceResolution()調用,無需任何中間轉換步驟。
Tessdata管理
每次Tesseract部署都面臨tessdata資料夾問題。 該資料夾必須存在,並填充正確的TesseractEngine初始化中指定的路徑上可存取。 這造成了一種隨著規模擴大而變得更複雜的部署複雜性問題。
Tesseract方法
multi-language-tesseract.cs檔案記錄了語言檔案尺寸和管理過程:
// Must exist before initialization:
// ./tessdata/eng.traineddata (~15 MB)
// ./tessdata/fra.traineddata (~15 MB)
// ./tessdata/deu.traineddata (~15 MB)
// ./tessdata/chi_sim.traineddata (~45 MB)
// ./tessdata/jpn.traineddata (~40 MB)
// 10 languages = 200-300 MB to download and manage
public string SafeMultiLanguageOcr(string imagePath, string[] languages)
{
// Check presence before attempting — runtime failures are worse
foreach (var lang in languages)
{
if (!File.Exists(Path.Combine(TessDataPath, $"{lang}.traineddata")))
{
throw new FileNotFoundException(
$"Missing {lang}.traineddata in {TessDataPath}. " +
"Download from https://github.com/tesseract-ocr/tessdata");
}
}
var langString = string.Join("+", languages); // e.g., "eng+fra+deu"
using var engine = new TesseractEngine(TessDataPath, langString, EngineMode.Default);
using var img = Pix.LoadFromFile(imagePath);
using var page = engine.Process(img);
return page.GetText();
}
// Must exist before initialization:
// ./tessdata/eng.traineddata (~15 MB)
// ./tessdata/fra.traineddata (~15 MB)
// ./tessdata/deu.traineddata (~15 MB)
// ./tessdata/chi_sim.traineddata (~45 MB)
// ./tessdata/jpn.traineddata (~40 MB)
// 10 languages = 200-300 MB to download and manage
public string SafeMultiLanguageOcr(string imagePath, string[] languages)
{
// Check presence before attempting — runtime failures are worse
foreach (var lang in languages)
{
if (!File.Exists(Path.Combine(TessDataPath, $"{lang}.traineddata")))
{
throw new FileNotFoundException(
$"Missing {lang}.traineddata in {TessDataPath}. " +
"Download from https://github.com/tesseract-ocr/tessdata");
}
}
var langString = string.Join("+", languages); // e.g., "eng+fra+deu"
using var engine = new TesseractEngine(TessDataPath, langString, EngineMode.Default);
using var img = Pix.LoadFromFile(imagePath);
using var page = engine.Process(img);
return page.GetText();
}
Imports System.IO
Imports Tesseract
Public Function SafeMultiLanguageOcr(imagePath As String, languages As String()) As String
' Check presence before attempting — runtime failures are worse
For Each lang In languages
If Not File.Exists(Path.Combine(TessDataPath, $"{lang}.traineddata")) Then
Throw New FileNotFoundException(
$"Missing {lang}.traineddata in {TessDataPath}. " &
"Download from https://github.com/tesseract-ocr/tessdata")
End If
Next
Dim langString = String.Join("+", languages) ' e.g., "eng+fra+deu"
Using engine As New TesseractEngine(TessDataPath, langString, EngineMode.Default)
Using img As Pix = Pix.LoadFromFile(imagePath)
Using page As Page = engine.Process(img)
Return page.GetText()
End Using
End Using
End Using
End Function
防禦性的文件存在性檢查並不是偏執狂——缺少的TesseractException: Failed to initialise tesseract engine,訊息並不總是明確表明缺少哪一個檔案。 BadImageFormatException因32/64位不匹配。
在Docker部署中,tessdata檔案必須被複製到容器映像中。 對於三個語言每個15 MB加上best模型每個50-100 MB,容器映像膨脹到數百兆字節。 CI/CD管道要麼必須快取這些下載,要麼接受快取冷啟動時的慢速構建時間。
IronOCR方法
IronOCR中的語言支持是NuGet套件引用:
// Install once: dotnet add package IronOcr.Languages.French
// Install once: dotnet add package IronOcr.Languages.German
using IronOcr;
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.French;
ocr.AddSecondaryLanguage(OcrLanguage.German);
var result = ocr.Read("multilingual-document.jpg");
// Install once: dotnet add package IronOcr.Languages.French
// Install once: dotnet add package IronOcr.Languages.German
using IronOcr;
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.French;
ocr.AddSecondaryLanguage(OcrLanguage.German);
var result = ocr.Read("multilingual-document.jpg");
Imports IronOcr
' Install once: dotnet add package IronOcr.Languages.French
' Install once: dotnet add package IronOcr.Languages.German
Dim ocr As New IronTesseract()
ocr.Language = OcrLanguage.French
ocr.AddSecondaryLanguage(OcrLanguage.German)
Dim result = ocr.Read("multilingual-document.jpg")
語言資料被嵌入在NuGet套件中。 無需建立資料夾,無需配置路徑,無需從GitHub下載和驗證文件。 將語言新增到Docker意味著在PackageReference。 多語言指南涵蓋了完整的125+語言目錄,而多語言部落格帖子詳述了生產中的多語言管道,包括CJK字元集。
API 地圖參考
| Tesseract(charlesw)API | IronOCR 等效 |
|---|---|
new TesseractEngine(tessDataPath, "eng", EngineMode.Default) |
new IronTesseract() |
Pix.LoadFromFile(path) |
ocr.Read(path) |
Pix.LoadFromMemory(bytes) |
input.LoadImage(bytes) |
engine.Process(img) |
ocr.Read(input) |
page.GetText() |
result.Text |
page.GetMeanConfidence() |
result.Confidence |
page.GetHOCRText(0) |
result.SaveAsHocrFile(path) |
engine.Process(img, tessRect) |
input.LoadImage(path, new CropRectangle(...)) |
iter.GetText(PageIteratorLevel.Word) |
result.Words[i].Text |
iter.GetConfidence(PageIteratorLevel.Word) |
result.Words[i].Confidence |
iter.TryGetBoundingBox(PageIteratorLevel.Word, out bounds) |
result.Words[i].X, .Y, .Width, .Height |
"eng+fra+deu"語言字串 |
ocr.AddSecondaryLanguage(OcrLanguage.French) |
| 不適用——需要PdfiumViewer或類似 | input.LoadPdf(path) |
| 不適用——需要PDF程式庫 | input.LoadPdf(path, Password: "secret") |
| 不支持 | result.SaveAsSearchablePdf(outputPath) |
| 手動前處理管道 | input.Deskew(), input.DeNoise(), input.Binarize() |
| 每個執行緒手動多執行緒引擎 | 執行緒安全的單一IronTesseract實例 |
當團隊考慮從Tesseract轉向IronOCR
前處理里程碑達到
每個Tesseract專案都從乾淨的測試圖像開始。 樣本發票、清晰掃描的文件、首讀可用的300 DPI的PNG檔。 前處理問題被推遲。 然後第一批生產批次到達:150 DPI的傳真採購訂單,傾斜3度的掃描合同,在熒光燈下拍攝的收據照片。 準確度下降至60-70%。 團隊現在面臨實現之前推遲的前處理管道,發現灰階轉換和對比度增強是可管理的,但傾斜校正需要Hough變換,去噪需要中值濾波器,這都不是兩小時的工作。 處於這一里程碑的團隊——前處理債務變成沖刺待辦事項——常常評估IronOCR,因為其授權成本低於兩週開發者的圖像處理工作,而他們並不是被雇來做這件事的。
PDF需求出現
文件處理應用程式幾乎總是最終需要PDF支持。 第一次反應通常是"新增PdfiumViewer"——它文件齊全並且處理許多情況良好。 問題在生產中顯現:本機.so檔案,加密保護的PDF需要一個單獨的解密程式庫,其也有自己的授權。 管理三條獨立的依賴鏈的團隊——Tesseract本機程式庫、Leptonica和pdfium——在四個環境中(Windows、Linux、Docker、CI)達到維護的門檻,在這時單一套件的替代方案值得評估。
大規模運行並行處理
批次OCR作業處理500份發票能從並行化中受益。 使用charlesw包裝器,安全的並行處理模式為每個執行緒建立一個引擎實例,每個載入40-100 MB的語言模型資料。 在八個執行緒中,就是320-800 MB的引擎記憶體,還沒載入任何文件。 分析他們的OCR服務團隊發現記憶體壓力集中於引擎初始化——而不是文件內容——發現IronOCR的執行緒安全單實例模型直接解決了根本原因。 多執行緒範例展示了模式。
部署環境增加
一個始於Windows的專案增加了一個用於雲部署的Linux容器。 Dockerfile 現在需要本地程式庫安裝步驟,tessdata檔案必須被複製到容器中,並且必須正確設置tessdata path環境變數。 然後一位macOS開發者加入了團隊。 然後有人希望部署到AWS Lambda。 每個平台增加一個可能無聲失敗的配置表面——在生產容器中運行時缺失本機程式庫的後果比稍高的NuGet套件成本要糟糕。IronOCR Docker部署指南顯示了對比:無系統套件,無tessdata複製步驟,無環境變數。
Tesseract版本貨幣化至關重要
Tesseract 5.x引入了LSTM準確性的改進,這在某些文件型別上是可測量的。charlesw包裝器目標是Tesseract 4.1.1。對於那些OCR在困難文件上的準確度是產品質量衡量標準的團隊,版本差距是一個真正需要考慮的問題——尤其是在可作為商業維護套裝的替代方案跟踪當前引擎版本時。
常見的遷移考量
Tessdata 資料夾的移除
遷移到IronOCR後的首個清理步驟是刪除tessdata資料夾並從專案檔案中移除相應的basic-text-extraction-tesseract.cs中出現過——也會消失。 TesseractEngine, Pix, 和using IronOcr;, IronTesseract, OcrInput, 和OcrResult替換。
PDF程式庫移除
任何為支持Tesseract PDF處理而新增的PDF渲染程式庫——PdfiumViewer、PDFtoImage、Docnet.Core——都可以被移除。 這些套件所需的本機二進制依賴(pdfium.dll, GhostScript二進製檔)也會消失。 Dockerfile apt-get行對於那些依賴不再需要。 IronOCR PDF輸入指南涵蓋了那些程式庫處理的每種PDF輸入變化,包括頁碼範圍選擇和加密保護文件。 整個渲染再OCR區塊——通常跨三個程式庫長達50-80行——收縮為Read()調用。
前處理程式碼替換
現有的前處理方法——ConvertToGrayscale, EnhanceContrast, Binarize, RemoveNoise, Deskew, ScaleToDpi——直接映射到IronOCR濾鏡方法。 臨時檔案保存和載入模式完全消失。 參考圖像色彩校正指南進行色彩特定轉換,參考DPI設定指南進行解析度管理。
執行緒模型改變
在IronTesseract並在所有執行緒中共享。 這是一個正確性的改變,不僅僅是重構:舊的模式是圍繞非執行緒安全API的防禦性編程; 新模式是執行緒安全API的預期使用方式。 每執行緒引擎初始化開銷——每個執行緒40-100 MB的語言模型資料——隨著這個變更消失,因為IronOCR維護了一個共享內部池,而不是對每個引擎實例載入完整模型狀態。
其他IronOCR功能
除了前處理和PDF支持,IronOCR還包括擴展到核心比較以外的能力:
- 基於區域的OCR:從定義的裁剪矩形中提取文字,而不處理整個圖像。 區域OCR指南和裁剪範例涵蓋了發票標題提取和表單字段隔離。
- 基於信心的質量路由:
result.Confidence提供一個文件級別的準確性估計,使得將低信心結果路由到人工審查隊列無需重新運行OCR。參見信心分數指南。 - 異步OCR: 異步OCR指南涵蓋了非阻塞OCR,適用於將請求執行緒阻塞在CPU綁定操作上的ASP.NET Core應用程式。
- 專門的文件型別: 護照閱讀, MICR/支票閱讀, 和 車牌閱讀可作為針對性功能,無需定制訓練的模型。
- 速度配置: 速度優化指南和速度調優範例記錄了高吞吐量批處理的配置選項,其中每個文件的延遲問題。
.NET 相容性和未來準備
IronOCR目標為.NET 6、.NET 7、.NET 8 和.NET 9,並且在2026年.NET 10發布時積極支持它。 對於尚未遷移到現代.NET的專案,該程式庫還支持.NET Standard 2.0。 charlesw Tesseract包裝器目標是.NET Standard 2.0,它固定在2019年的Tesseract引擎版本4.1.1上,沒有宣布通過此包裝器支持Tesseract 5.x的路線圖。 對於綠色田地專案和計劃多年維護窗口的團隊,引擎版本差距和包裝器維護節奏的減緩是值得權衡的因素,與零成本的授權一起。
結論
通過charlesw NuGet包裝器的Tesseract是一個真正的OCR引擎,而不是玩具。 800萬次下載反映了在真實應用程式中的實際使用情況,而且在乾淨、格式良好的圖像上,達到了證明其受歡迎的準確性水平。 實際的比較不關乎OCR質量——而是在生產條件下讓這種質量可用所需的工程工作面積。
前處理缺口是中央的權衡點。 大約180行的圖像處理程式碼在現實世界文件中將好的準確性與差的準確性分隔開來,這不是一個小麻煩。 這是一項需要圖像處理知識的工程任務, 需要額外的依賴關係,並且隨著新文件型別的出現需要持續維護。 PDF缺口又增加了一層:第二個程式庫,第二套本機二進製檔,另一個部署表面以及可能的與GhostScript或iText的授權糾葛。 總的來說,這兩個差距構成了20-40小時的設置估計,這區分了一個原型與一個生產系統。
IronOCR直接解決了這兩個差距:前處理是一行方法調用,PDF是一個原生輸入格式,整個解決方案作為一個NuGet套件部署。 $999永久授權是避免耗費兩週在圖像處理程式碼和依賴鏈管理上的成本。 對於開發者時間成本大於授權價格的團隊而言,數學計算是直接的。 對於有開源授權需求或預算為零的團隊,Tesseract仍然是前進的道路——對應的還有隨之來的工程投入。
這個決策與文件型別和操作上下文相吻合:在單一環境部署中乾淨、受控的圖像有利於Tesseract的免費授權。 現實世界的掃描、PDF工作流、多環境的部署以及大規模的並行處理都增加了摩擦,這使得計算更加偏向於IronOCR。 大多數生產文件處理系統至少遇到其中兩種條件。
[[i:(Ghostscript、PDFium、PDFSharp、Tesseract和iText是其各自所有者的註冊商標。 此網站與Artifex Software、Chromium Project、Google、empira Software GmbH或iText Group無關聯、無認可或無贊助。所有產品名稱、標誌和品牌均屬於其各自所有者。 比較僅供資訊用途,並反映撰寫時獲得的公開資訊。)]]
常見問題
什麼是Tesseract OCR?
Tesseract OCR是一個被開發者和企業用來從影像和文件中提取文字的OCR解決方案。它是IronOCR for .NET應用開發評估的幾個OCR選項之一。
IronOCR相比於Tesseract OCR對.NET開發者有什麼不同?
IronOCR是一個NuGet原生的.NET OCR程式庫,其核心引擎使用IronTesseract。相較於Tesseract OCR,它提供更簡易的部署(無需SDK安裝者)、固定價格及一個整潔的C# API,沒有COM互操作或雲端依賴。
IronOCR比Tesseract OCR更容易設置嗎?
IronOCR 通過一個單一的 NuGet 套件安裝。無需 SDK 安裝程式、複製授權文件、註冊 COM 元件或管理單獨的運行時二進位檔案。整個 OCR 引擎都打包在套件中。
Tesseract OCR和IronOCR之間在準確度上有何不同?
IronOCR 在標準商業文件、發票、收據和掃描表單上達到了高識別準確度。對於極度退化的文件或罕見文字,準確度會根據來源品質變化。IronOCR 包含影像預處理篩選器,以改善低品質輸入的識別。
IronOCR 支援 PDF 文字提取嗎?
是的。IronOCR 能從原生 PDF 和掃描的 PDF 圖像中一次性提取文字。它還支持多頁 TIFF 檔案、影像和流。對於掃描的 PDF,OCR 會逐頁應用並生成每頁的結果物件。
Tesseract OCR的授權與IronOCR有何不同?
IronOCR 採用固定費率的永久授權,無須為每頁或每次掃描支付費用。處理大量文件的組織無論數量多少都支付相同的授權費用。詳細資訊和批量定價在 IronOCR 授權頁面上。
IronOCR 支援哪些語言?
IronOCR 透過單獨的 NuGet 語言包支持 127 種語言。新增一種語言只需一個 'dotnet add package IronOcr.Languages.{Language}' 命令。無需手動放置文件或配置路徑。
如何在.NET專案中安裝IronOCR?
通過 NuGet 安裝:在套件管理員控制台或 CLI 中分別使用 'Install-Package IronOcr' 或 'dotnet add package IronOcr'。其他語言包也是這樣安裝的。無需本地 SDK 安裝程式。
IronOCR是否適合與Docker和容器化部署,與Tesseract OCR不同?
是的。IronOCR 通過其 NuGet 載於 Docker 容器中運行。授權金鑰通過環境變數設置。無需授權文件、SDK 路徑或量掛載來執行 OCR 引擎。
我可以在購買前試用IronOCR,與Tesseract OCR相比嗎?
是的。IronOCR 試用模式中處理文件並在輸出上附上浮水印結果。您可以在購買授權前驗證自己文件的準確性。
IronOCR 支援條碼閱讀與文字提取嗎?
IronOCR 專注於文字提取和 OCR。對於條碼閱讀,Iron Software 提供了額外的 IronBarcode 程式庫。兩者均可個別使用或作為 Iron Suite 套件的一部分。
從Tesseract OCR遷移到IronOCR是否容易?
從Tesseract OCR遷移到IronOCR通常涉及用IronTesseract實例化替換初始化序列,去除COM生命週期管理,並更新API呼叫。大多數的遷移可顯著減少程式碼複雜性。

