從 Asprise OCR 遷移到 IronOCR
這份指南逐步指導.NET開發者如何以IronOCR取代Asprise OCR。 它涵蓋了機械包交換、命名空間變更,以及大部分在生產.NET應用中會使用到的四種程式碼遷移模式。 已經決定遷移並需要具體行動計劃的開發者是目標讀者。
為什麼要從Asprise OCR遷移
Asprise OCR最初設計為Java產品。.NET介面是包裝在Java原生引擎的周圍,這個起源影響了該程式庫在.NET中的每一個方面——從部署到API設計再到授權限制。
JRE和本地二進位依賴。Asprise OCRfor .NET需要在每台運行應用程式的機器上存在平台特定的本地二進位(aocr.dll, aocr_x64.dll, libaocr.so, libaocr.dylib)。 每個二進位必須與目標平台和處理器架構完全匹配。 使用32位DLL構建的64位Docker容器在運行時會拋出DllNotFoundException。 這些錯誤在構建時不會顯示出來。每一個新的部署目標——一台新伺服器,一個新容器映像,一個CI代理——都成為了一個手動二進位來源的練習。
來源於Java的字串常數API。 Asprise揭示了用於識別型別和輸出格式的整數常數:Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT, Ocr.OUTPUT_FORMAT_XML。 這些常數直接對應到Java SDK的基於整數的API。 .NET開發者不會在合法的常數值上接收到IntelliSense指導,無法組合品參數的編譯時安全保障,也沒有強型別的結果物件。 抽取結構化輸出需要手動解析XML字串。
不支持異步而無需解決辦法。 Asprise不提供本地異步API。 將同步的Asprise調用包裹在Task.Run中以避免阻塞ASP.NET執行緒會產生執行緒池壓力,並且不會解決在Lite和Standard層級禁止同步執行的授權限制。 現代.NET應用中的異步模式——背景服務、最小API端點、Azure Functions——在Asprise中無清晰對應。
多幀TIFF處理需要手動分割。 Asprise針對單個圖像文件進行操作。 處理多頁TIFF需要外部程式碼將幀分割成單個文件,然後在迴圈中處理每個文件。沒有幀元資料或頁碼攜帶到輸出。
執行緒限制妨礙生產部署。Lite(~$299)和Standard(~$699)授權合約限制只在單執行緒和單進程中執行。 ASP.NET Core在執行緒池上處理所有HTTP請求。 每一個調用Asprise的網路API端點在這些層級上從第一個併發請求開始就是授權違反。升級到Enterprise解除限制但需要聯繫銷售人員,無公開價格——估計範圍從$2,000到$5,000+,視部署範圍而定。
輸出格式處理需要字串解析。 當指定OUTPUT_FORMAT_XML時,Asprise返回原始XML字串。 應用程式負責對該字串進行反序列化,驗證其結構,並提取單詞及其坐標。 每個詞的置信分數嵌入在XML屬性中。 沒有物件模型——只有字串操作。
根本問題
Asprise需要在可以執行第一次OCR調用之前進行與JRE相鄰的本地二進位配置。 IronOCR除了NuGet包之外不需要其他任何東西:
// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp(); // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST); // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine(); // Must call or native memory leaks
// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp(); // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST); // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine(); // Must call or native memory leaks
' Asprise: native binary must exist in PATH or application directory
' aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp() ' Static init — touches native binary
Dim ocr As New Ocr()
ocr.StartEngine("eng", Ocr.SPEED_FAST) ' Allocates native engine memory
Dim text As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
ocr.StopEngine() ' Must call or native memory leaks
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
' IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim text As String = New IronTesseract().Read(imagePath).Text
IronOCRvs Asprise OCR:功能比較
下表涵蓋了最相關於評估此遷移的開發者的功能。
| 功能 | Asprise OCR | IronOCR |
|---|---|---|
| 主要平台 | Java(傳統) | .NET 原生 |
| NuGet安裝 | 包裝器+平台本地DLL | 單個包(IronOcr) |
| 運行時需要本地二進位 | 是(每平台DLL) | 不是 |
| .NET API風格 | 整數常數,字串返回 | 強型別的類和枚舉 |
IDisposable / using模式 |
未實現 | 是(OcrInput) |
| 異步 OCR | 沒有本地支持 | 是(ReadAsync) |
| 多執行緒—Lite/Standard層級 | 授權禁用 | 允許 |
| 多執行緒——所有層次 | 僅限ENTERPRISE | 所有層級 |
| ASP.NET Core Web API支持 | 需要Enterprise | 任何層級 |
| Azure Functions / AWS Lambda | 需要Enterprise | 任何層級 |
| 本地PDF輸入 | 不是 | 是 |
| 多幀TIFF輸入 | 否(手動幀分割) | 是(LoadImageFrames) |
| 字節陣列和流輸入 | 有限 | 是 |
| 內建圖像預處理 | 不是 | 是(9個以上的過濾器) |
| 可搜尋的 PDF 輸出 | 不是 | 是(SaveAsSearchablePdf) |
| 結構化的結果物件模型 | 否(僅XML字串) | 是(頁、段落、字、字元) |
| 每個單詞的信心分數 | 否(XML屬性解析) | 是(result.Confidence) |
| 字詞像素坐標 | XML屬性解析 | 強型別屬性 |
| 語言數量 | 20+ | 125+ |
| 強型別語言選擇 | 否(字串程式碼) | 是(OcrLanguage枚舉) |
| 條碼讀取 | 是(單獨識別型別) | 是(配置標誌) |
| hOCR匯出 | 不是 | 是 |
| 跨平台部署 | 每平台手動二進位 | NuGet處理所有平台 |
| Docker / Linux / macOS | 手動LD_LIBRARY_PATH配置 |
開箱即用 |
| .NET相容性 | 有限(Java橋樑) | .NET Framework 4.6.2+, .NET 5–9 |
| 伺服器使用的起始價格 | Enterprise(~$2,000+) | $999(Lite,所有功能) |
| 許可型別 | 每層,聯繫銷售以了解Enterprise | 永久(一經購買) |
快速開始:Asprise OCR到IronOCR的遷移
步驟1:替換NuGet包
移除Asprise OCR:
dotnet remove package asprise-ocr-api
dotnet remove package asprise-ocr-api
從NuGet包頁面安裝IronOCR:
dotnet add package IronOcr
步驟2:更新命名空間
用IronOCR命名空間替換Asprise命名空間:
// Before (Asprise)
using asprise.ocr;
// After (IronOCR)
using IronOcr;
// Before (Asprise)
using asprise.ocr;
// After (IronOCR)
using IronOcr;
Imports IronOcr
步驟3:初始化許可證
在應用程式啟動時新增授權金鑰分配——在進任何OCR調用之前的Startup.Configure中,或在一個靜態建構函式中:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
免費試用金鑰可從IronOCR授權頁面獲得。 在開發和評估期間,IronOCR運行時無需金鑰並在輸出上印上試用浮水印。
程式碼遷移範例
JRE路徑配置和引擎初始化移除
以Linux或macOS運行的Asprise應用程式通常包括啟動程式碼,其中設置JRE路徑或驗證本地二進位的存在。 這個基礎設施在IronOCR中沒有對應。
Asprise OCR方法:
// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
// Validate native library is reachable before first use
string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
: RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/usr/lib/libaocr.so"
: "/usr/local/lib/libaocr.dylib";
if (!File.Exists(nativePath))
throw new FileNotFoundException(
$"Asprise native binary not found: {nativePath}. " +
"Deploy the correct platform binary before starting.");
// Static global init — must run before any Ocr instance is created
Ocr.SetUp();
}
// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
// Validate native library is reachable before first use
string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
: RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/usr/lib/libaocr.so"
: "/usr/local/lib/libaocr.dylib";
if (!File.Exists(nativePath))
throw new FileNotFoundException(
$"Asprise native binary not found: {nativePath}. " +
"Deploy the correct platform binary before starting.");
// Static global init — must run before any Ocr instance is created
Ocr.SetUp();
}
Imports System
Imports System.IO
Imports System.Runtime.InteropServices
' AppStartup.vb — native binary validation before accepting any requests
Public Module AppStartup
Public Sub InitializeOcr()
' Validate native library is reachable before first use
Dim nativePath As String = If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows),
Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll"),
If(RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
"/usr/lib/libaocr.so",
"/usr/local/lib/libaocr.dylib"))
If Not File.Exists(nativePath) Then
Throw New FileNotFoundException($"Asprise native binary not found: {nativePath}. " &
"Deploy the correct platform binary before starting.")
End If
' Static global init — must run before any Ocr instance is created
Ocr.SetUp()
End Sub
End Module
IronOCR方法:
// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// That is it.不是binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// That is it.不是binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
Asprise模式通常跨多個文件有15-30行——一個啟動校驗器,平台開關,帶有部署資訊的異常,以及SetUp()調用。 IronOCR用單一分配替代所有這些。 IronTesseract設置指南涵蓋了需要自定義tessdata路徑或離線操作的環境的部署配置選項。
用結構化的結果物件替換XML輸出格式
當指定OUTPUT_FORMAT_XML時,Asprise產生結構化輸出作為原始XML字串。 從該字串中擷取單詞文字、坐標和置信度需要XML解析程式碼。 IronOCR返回一個型別化的物件圖。
Asprise OCR方法:
// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
string xmlOutput = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_XML); // Returns raw XML, not an object
// Parse the XML manually to extract words and coordinates
var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
var words = doc.Descendants("word")
.Select(w => new
{
Text = (string)w.Attribute("text"),
Confidence = (float)w.Attribute("confidence"),
X = (int)w.Attribute("x"),
Y = (int)w.Attribute("y"),
})
.ToList();
foreach (var word in words)
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
ocr.StopEngine();
}
// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
string xmlOutput = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_XML); // Returns raw XML, not an object
// Parse the XML manually to extract words and coordinates
var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
var words = doc.Descendants("word")
.Select(w => new
{
Text = (string)w.Attribute("text"),
Confidence = (float)w.Attribute("confidence"),
X = (int)w.Attribute("x"),
Y = (int)w.Attribute("y"),
})
.ToList();
foreach (var word in words)
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
ocr.StopEngine();
}
Imports System.Xml.Linq
' Asprise: structured output is an XML string — must parse manually
Ocr.SetUp()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
Dim xmlOutput As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_XML) ' Returns raw XML, not an object
' Parse the XML manually to extract words and coordinates
Dim doc As XDocument = XDocument.Parse(xmlOutput)
Dim words = doc.Descendants("word") _
.Select(Function(w) New With {
.Text = CStr(w.Attribute("text")),
.Confidence = CSng(w.Attribute("confidence")),
.X = CInt(w.Attribute("x")),
.Y = CInt(w.Attribute("y"))
}) _
.ToList()
For Each word In words
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}")
Next
Finally
ocr.StopEngine()
End Try
IronOCR方法:
// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
foreach (var word in paragraph.Words)
{
Console.WriteLine(
$"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
}
}
}
// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
foreach (var word in paragraph.Words)
{
Console.WriteLine(
$"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
}
}
}
Imports IronOcr
' IronOCR: structured result is a typed object — no XML parsing
Dim result = New IronTesseract().Read(imagePath)
For Each page In result.Pages
For Each paragraph In page.Paragraphs
For Each word In paragraph.Words
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%")
Next
Next
Next
無需XML反序列化,無屬性強制轉換,無架構假設。 OcrResult物件模型通過型別化屬性公開頁、段落、行、字、字元。 讀取結果指南涵蓋了完整的層次結構和坐標系統,包括如何按置信度閾值進行過濾以實現自動化工作流。
多幀TIFF處理
Asprise接受單個圖像文件。 在文件掃描工作流中常用的多幀TIFF必須分離成單獨的幀文件才能被Asprise處理。 IronOCR通過LoadImageFrames直接接受多幀TIFF。
Asprise OCR方法:
// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
for (int i = 0; i < frameCount; i++)
{
tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
string framePath = $"frame_{i}.png";
tiff.Save(framePath);
frameFiles.Add(framePath);
}
}
// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
foreach (var framePath in frameFiles)
{
string pageText = ocr.Recognize(
framePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
allText.AppendLine(pageText);
}
}
finally
{
ocr.StopEngine();
// Clean up temporary frame files
foreach (var f in frameFiles)
File.Delete(f);
}
Console.WriteLine(allText.ToString());
// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
for (int i = 0; i < frameCount; i++)
{
tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
string framePath = $"frame_{i}.png";
tiff.Save(framePath);
frameFiles.Add(framePath);
}
}
// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
foreach (var framePath in frameFiles)
{
string pageText = ocr.Recognize(
framePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
allText.AppendLine(pageText);
}
}
finally
{
ocr.StopEngine();
// Clean up temporary frame files
foreach (var f in frameFiles)
File.Delete(f);
}
Console.WriteLine(allText.ToString());
Imports System.Drawing
Imports System.Text
Imports System.IO
' Asprise: no multi-frame TIFF support — split frames externally first
' Using an external imaging library (e.g., System.Drawing or Magick.NET)
Dim frameFiles As New List(Of String)()
Using tiff As Image = Image.FromFile("scanned-batch.tiff")
Dim frameCount As Integer = tiff.GetFrameCount(Imaging.FrameDimension.Page)
For i As Integer = 0 To frameCount - 1
tiff.SelectActiveFrame(Imaging.FrameDimension.Page, i)
Dim framePath As String = $"frame_{i}.png"
tiff.Save(framePath)
frameFiles.Add(framePath)
Next
End Using
' Now process each frame individually — sequential on LITE/STANDARD
Dim allText As New StringBuilder()
Ocr.SetUp()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
For Each framePath As String In frameFiles
Dim pageText As String = ocr.Recognize(framePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
allText.AppendLine(pageText)
Next
Finally
ocr.StopEngine()
' Clean up temporary frame files
For Each f As String In frameFiles
File.Delete(f)
Next
End Try
Console.WriteLine(allText.ToString())
IronOCR方法:
// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff"); // All frames, one call
var result = new IronTesseract().Read(input);
// Access each page independently with its page number
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff"); // All frames, one call
var result = new IronTesseract().Read(input);
// Access each page independently with its page number
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
Imports IronOcr
' IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
Using input As New OcrInput()
input.LoadImageFrames("scanned-batch.tiff") ' All frames, one call
Dim result = New IronTesseract().Read(input)
' Access each page independently with its page number
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
Next
End Using
Asprise方法需要外部成像依賴,臨時文件管理,手動清理,和逐幀的順序處理。 IronOCR在單次通過中處理所有幀。 TIFF和GIF輸入指南涵蓋了選擇大TIFF的幀範圍,其中只需要特定頁。
可搜尋PDF生成
Asprise在任何授權層級上都沒有可搜尋PDF的輸出能力。 從掃描的文件建立帶有嵌入OCR文字的PDF需要外部PDF庫,需有一個單獨的OCR通過來獲取文字位置,還需手動疊加建構。 IronOCR直接從識別結果產生可搜尋PDF。
Asprise OCR方法:
// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
recognizedText = ocr.Recognize(
"scanned-contract.jpg",
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT); // Only plain text — no position data
}
finally
{
ocr.StopEngine();
}
// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
recognizedText = ocr.Recognize(
"scanned-contract.jpg",
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT); // Only plain text — no position data
}
finally
{
ocr.StopEngine();
}
// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
' Asprise: no searchable PDF output — external PDF library required
' Step 1: OCR the document to get text
Ocr.SetUp()
Dim ocr As New Ocr()
Dim recognizedText As String
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
recognizedText = ocr.Recognize( _
"scanned-contract.jpg", _
Ocr.RECOGNIZE_TYPE_TEXT, _
Ocr.OUTPUT_FORMAT_PLAINTEXT) ' Only plain text — no position data
Finally
ocr.StopEngine()
End Try
' Step 2: Use an external PDF library to embed text over the image
' (iTextSharp, PdfSharp, or similar — adds another dependency and license)
' Text positioning requires coordinate data Asprise cannot provide in plain text mode
' ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone")
IronOCR方法:
// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");
// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
var batchResult = new IronTesseract().Read(imagePath);
string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
batchResult.SaveAsSearchablePdf(outputPath);
Console.WriteLine($"Converted: {outputPath}");
}
// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");
// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
var batchResult = new IronTesseract().Read(imagePath);
string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
batchResult.SaveAsSearchablePdf(outputPath);
Console.WriteLine($"Converted: {outputPath}");
}
Imports System.IO
Imports IronOcr
' IronOCR: searchable PDF in two lines — no external PDF library
Dim result = New IronTesseract().Read("scanned-contract.jpg")
result.SaveAsSearchablePdf("searchable-contract.pdf")
' Batch: convert a folder of scanned images to searchable PDFs
For Each imagePath In Directory.GetFiles("scans", "*.jpg")
Dim batchResult = New IronTesseract().Read(imagePath)
Dim outputPath As String = Path.ChangeExtension(imagePath, ".searchable.pdf")
batchResult.SaveAsSearchablePdf(outputPath)
Console.WriteLine($"Converted: {outputPath}")
Next
可搜尋PDF包含作為視覺層的原始圖像,帶有在正確坐標上覆蓋的不可見OCR文字——這是歸檔和合規工作流的標準格式。 查看可搜尋PDF指南和可搜尋PDF範例以得到包括長期歸檔的PDF/A輸出的選項。
Web應用中的異步OCR
Asprise沒有異步API。 開發者可以将同步調用包裹在Task.Run中以整合到.NET異步應用中,這樣會消耗執行緒池執行緒但無法消除阻塞。 IronOCR提供本地異步通道。
Asprise OCR方法:
// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
string tempPath = Path.GetTempFileName();
await using (var fs = new FileStream(tempPath, FileMode.Create))
await fileStream.CopyToAsync(fs);
// Task.Run wraps synchronous Asprise — occupies a thread pool thread
// Two concurrent requests still violate LITE/STANDARD license
return await Task.Run(() =>
{
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
return ocr.Recognize(
tempPath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
}
finally
{
ocr.StopEngine();
File.Delete(tempPath);
}
});
}
// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
string tempPath = Path.GetTempFileName();
await using (var fs = new FileStream(tempPath, FileMode.Create))
await fileStream.CopyToAsync(fs);
// Task.Run wraps synchronous Asprise — occupies a thread pool thread
// Two concurrent requests still violate LITE/STANDARD license
return await Task.Run(() =>
{
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
return ocr.Recognize(
tempPath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
}
finally
{
ocr.StopEngine();
File.Delete(tempPath);
}
});
}
Imports System.IO
Imports System.Threading.Tasks
' Asprise: no async API — must offload to Task.Run
' This blocks a thread pool thread during the entire OCR operation
' On LITE/STANDARD, concurrent Task.Run calls = license violation
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
Dim tempPath As String = Path.GetTempFileName()
Await Using fs As New FileStream(tempPath, FileMode.Create)
Await fileStream.CopyToAsync(fs)
End Using
' Task.Run wraps synchronous Asprise — occupies a thread pool thread
' Two concurrent requests still violate LITE/STANDARD license
Return Await Task.Run(Function()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
Return ocr.Recognize(tempPath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
Finally
ocr.StopEngine()
File.Delete(tempPath)
End Try
End Function)
End Function
IronOCR方法:
// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
using var input = new OcrInput();
input.LoadImage(fileStream); // Stream input directly — no temp file
var ocr = new IronTesseract();
var result = await ocr.ReadAsync(input);
return result.Text;
}
// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
using var input = new OcrInput();
input.LoadImage(fileStream); // Stream input directly — no temp file
var ocr = new IronTesseract();
var result = await ocr.ReadAsync(input);
return result.Text;
}
Imports System.IO
Imports System.Threading.Tasks
' IronOCR: native async, concurrent requests permitted on all tiers
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
Using input As New OcrInput()
input.LoadImage(fileStream) ' Stream input directly — no temp file
Dim ocr As New IronTesseract()
Dim result = Await ocr.ReadAsync(input)
Return result.Text
End Using
End Function
IronOCR版本消除了臨時文件寫入、Task.Run包裹和執行緒阻塞行為。 多個並發請求各自建立自己的IronTesseract實例——該類是無狀態的,每個實例是獨立的。 異步OCR指南涵蓋了ReadAsync模式和針對托管服務中的長時間批量操作提供取消令牌支持。
Asprise OCRAPI到IronOCR的映射參考
| Asprise OCR | IronOCR 等效 |
|---|---|
asprise.ocr命名空間 |
IronOcr命名空間 |
Ocr.SetUp() |
不需要 |
new Ocr() |
new IronTesseract() |
ocr.StartEngine("eng", Ocr.SPEED_FAST) |
不需要 |
ocr.StartEngine("eng+fra", speed) |
ocr.Language = OcrLanguage.English + OcrLanguage.French |
ocr.Recognize(path, type, format) |
ocr.Read(input) |
Ocr.RECOGNIZE_TYPE_TEXT |
預設行為 |
Ocr.RECOGNIZE_TYPE_BARCODE |
ocr.Configuration.ReadBarCodes = true |
Ocr.RECOGNIZE_TYPE_ALL |
ocr.Configuration.ReadBarCodes = true |
Ocr.OUTPUT_FORMAT_PLAINTEXT |
result.Text |
Ocr.OUTPUT_FORMAT_XML |
result.Pages / result.Pages[n].Words |
Ocr.OUTPUT_FORMAT_PDF |
result.SaveAsSearchablePdf(path) |
Ocr.SPEED_FASTEST |
ocr.Configuration.TesseractEngineMode調校 |
Ocr.SPEED_FAST |
預設配置 |
Ocr.SPEED_SLOW |
高精度配置設置 |
ocr.StopEngine() |
不需要——IDisposable |
result.StartsWith("ERROR:")檢查 |
標準.NET異常處理(try/catch) |
| 平台原生DLL(aocr_x64.dll) | NuGet運行時包(自動) |
| 流輸入的手動臨時文件 | input.LoadImage(stream)直接 |
| 用於多幀TIFF的外部庫 | input.LoadImageFrames(path) |
| 用於可搜尋PDF的外部庫 | result.SaveAsSearchablePdf(path) |
常見的遷移問題与解決方案
問題1:移除本地二進位後的DllNotFoundException
Asprise OCR: 移除Asprise NuGet包但保留本地二進位引用(在專案文件拷貝規則、Docker COPY指令或部署腳本中)可能會使DllNotFoundException從指向不存在的二進位的過時配置中重新浮出。
解決方案: 搜索部署產物中的任何LD_LIBRARY_PATH設置的引用並移除它們。 IronOCR沒有對應的配置需求。 在Dockerfile中:
# Remove: COPY aocr_x64.dll /app/
# Remove: ENV LD_LIBRARY_PATH=/app
# IronOCR: nothing to add — NuGet handles native runtime packaging
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish
對於跨平台部署,Docker部署指南涵蓋了Linux容器上IronOCR的基本映像要求。
問題2:缺少Ocr.SetUp()移除導致啟動失敗
Asprise OCR: Ocr.SetUp()執行全域原生初始化。 有些程式碼庫在靜態構造函式或Startup.Configure中調用它。 遷移後,移除Asprise命名空間會去除編譯錯誤,但如果SetUp()被包裹在一個try/catch中抑制異常,那麼程式碼可能會在不初始化任何東西的情況下靜默編譯和運行。
解決方案: 搜索所有SetUp()調用並移除整個初始化塊。 用IronOCR授權金鑰分配替換等效的啟動鉤子:
grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();
// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();
// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
問題3:XML輸出解析程式碼沒有直接替換
Asprise OCR: 使用XDocument, OUTPUT_FORMAT_XML字串的程式碼在IronOCR中沒有等效的XML結構。 Asprise產生的XML架構不能直接映射到IronOCR的物件模型。
解決方案: 用OcrResult上的直接屬性存取取代XML解析程式碼。 映射為:
// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
.Descendants("word")
.Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });
//IronOCRobject model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
.SelectMany(p => p.Paragraphs)
.SelectMany(para => para.Words)
.Select(w => new { w.Text, w.X });
// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
.Descendants("word")
.Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });
//IronOCRobject model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
.SelectMany(p => p.Paragraphs)
.SelectMany(para => para.Words)
.Select(w => new { w.Text, w.X });
Imports System.Xml.Linq
Imports IronOcr
' Asprise XML parsing (remove)
Dim words = XDocument.Parse(xmlOutput) _
.Descendants("word") _
.Select(Function(w) New With {Key .Text = CType(w.Attribute("text"), String), Key .X = CType(w.Attribute("x"), Integer)})
' IronOCR object model (replace with)
Dim result = New IronTesseract().Read(imagePath)
Dim words = result.Pages _
.SelectMany(Function(p) p.Paragraphs) _
.SelectMany(Function(para) para.Words) _
.Select(Function(w) New With {w.Text, w.X})
讀取結果指南涵蓋了完整的物件層次結構,包括邊界框的字元級資料。
問題4:Task.Run包裝導致執行緒池耗盡
Asprise OCR:高並發Web應用程式中將Asprise包裹於Task.Run中,在OCR量激增時會耗盡執行緒池。 每個排隊的Task.Run在OCR操作的整個過程中佔有一個執行緒池執行緒。
解決方案: 用IronOCR原生異步調用取代Task.Run(() => { asprise... })模式。 每個IronTesseract實例是獨立的——為每個請求建立一個:
// Remove: await Task.Run(() => { ocr.Recognize(...) });
// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
// Remove: await Task.Run(() => { ocr.Recognize(...) });
// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
Imports IronTesseract
Using input As New OcrInput()
input.LoadImage(stream)
Dim result = Await (New IronTesseract()).ReadAsync(input)
Return result.Text
End Using
問題5:基於字串的語言程式碼驗證
Asprise OCR: 語言程式碼以字串形式傳遞("eng", "fra", "eng+fra")。 在運行時驗證這些字串的應用程式——對哈碼列表進行檢查,從配置中讀取——當字串格式改變為OcrLanguage枚舉時需要進行更新。
解決方案: 用OcrLanguage枚舉值取代字串語言參數。 基於配置的語言選擇干淨地映射到Enum.Parse:
// Asprise string-based (remove)
string language = config["OcrLanguage"]; // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);
//IronOCRenum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]); // e.g. "English"
var result = ocr.Read(input);
// Asprise string-based (remove)
string language = config["OcrLanguage"]; // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);
//IronOCRenum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]); // e.g. "English"
var result = ocr.Read(input);
' Asprise string-based (remove)
Dim language As String = config("OcrLanguage") ' e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST)
' IronOCRenum-based (replace with)
' For single language from config:
Dim ocr As New IronTesseract()
ocr.Language = [Enum].Parse(Of OcrLanguage)(config("OcrLanguage")) ' e.g. "English"
Dim result = ocr.Read(input)
多語言指南列出了所有有效的OcrLanguage枚舉值及其相應的NuGet語言包。
問題6:授權等級檢查邏輯不再需要
Asprise OCR: 某些生產程式碼庫包括運行時檢查,檢測Asprise的授權等級,並在ENTERPRISE等級以下運行時序列化OCR工作。這些防護可以防止違反授權,但增加了複雜性並降低了吞吐量。
解決方案: 移除所有層級檢測和序列化防護。 IronOCR對於任何層級都不攜帶執行緒限制。 ConcurrentQueue, SemaphoreSlim或單執行緒調度程式模式用於序列化Asprise調用在遷移后無需存在:
// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();
// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
var text = new IronTesseract().Read(path).Text;
results[path] = text;
});
// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();
// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
var text = new IronTesseract().Read(path).Text;
results[path] = text;
});
Imports System.Threading.Tasks
' IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, Sub(path)
Dim text = (New IronTesseract()).Read(path).Text
results(path) = text
End Sub)
Asprise OCR遷移清單
遷移前
在編寫任何替代程式碼之前,審計程式碼庫中所有Asprise的使用:
# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .
# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .
# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .
# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .
# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .
# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .
# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .
# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .
# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .
# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .
# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
清點結果:
- 計算導入
asprise.ocr的文件數量——所有這些都需要更新命名空間 - 列出每個
Read調用 - 確認需要物件模型替換的XML輸出解析程式碼——每個塊都需要物件模型替代
- 記錄任何授權等級防護或者序列化包——這些是可移除的
- 找到本地二進位部署腳本和容器配置
程式碼遷移
- 從所有項目中移除
asprise-ocr-apiNuGet包 - 在每個執行OCR的項目中安裝
IronOcrNuGet包 - 在所有文件中用
using asprise.ocr - 在應用程式啟動時新增
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY" - 從所有啟動和初始化程式碼中移除
Ocr.SetUp()調用 - 用
Ocr.StartEngine/Recognize/StopEngine塊 - 用
OUTPUT_FORMAT_XML解析塊 - 用
OUTPUT_FORMAT_PDF解決方案 - 用
input.LoadImageFrames(tiffPath)替換多幀TIFF分割程式碼 - 用
Task.Run包裝器 - 移除
SemaphoreSlim或序列化防護,使Asprise免受並發使用影響 - 從
.csproj文件和Dockerfile中移除本地二進位拷貝指令 - 從環境配置和CI腳本中移除
LD_LIBRARY_PATH設置 - 用
"eng","eng+fra") - 用
result.StartsWith("ERROR:")檢查
遷移後
- 驗證
dotnet build在缺失本地庫的情況下不會達成警告 - 確認在全部目標環境(Windows、Linux、Docker)啟動時不會出現
BadImageFormatException - 在代表性圖像上運行OCR,確認文字輸出與遷移前的基線相匹配
- 測試多幀TIFF處理並驗證所有頁面均返回且頁碼正確
- 生成可搜尋PDF並在PDF檢視器中驗證文字是可選取和可搜尋的
- 向調用OCR的任何API端點發送並發HTTP請求,確認所有請求都能完成且無錯誤
- 驗證異步端點在並發負載下返回結果無死鎖
- 確認結構化資料提取(單詞坐標與置信度)在已知文件上產生正確的輸出
- 檢查應用程式隨時間推移的記憶體使用情況,確認沒有本機記憶體泄露(先前因錯過
StopEngine()調用而導致) - 在Linux或者Docker容器下運行應用程式,確認無需二進位配置的跨平台部署工作正常
遷移至IronOCR的主要好處
部署簡化為單個NuGet引用。 遷移後,每個部署目標——開發工作站、預演伺服器、Linux容器、CI代理——都用同一個命令安裝相同的包。 沒有平台檢測邏輯,沒有特定架構的二進位來源,也無運行時路徑配置。 以前需要手動本地二進位COPY指令的Docker映像現在只需dotnet restore。 Linux部署指南和Azure部署指南提供了適用的環境特定說明。
所有授權層級解鎖伺服器級部署。 $999 Lite授權支持ASP.NET Core Web API、Windows服務、Azure Functions、AWS Lambda及任何其他多執行緒.NET工作負載。 Asprise每層收取$2,000–$5,000+的ENTERPRISE級別執行緒能力在每個IronOCR層級中提供。 從Asprise ENTERPRISE遷移到IronOCR Lite的團隊降低了其OCR授權成本並獲得了ENTERPRISE未提供的功能——原生PDF、結構化輸出、可搜尋PDF生成和125種語言。
結構化的OCR結果取代XML字串解析。 OcrResult物件模型揭示了一個完整的文件層次結構:頁、段落、行、字、字元,每個物件都有像素精確的邊界框坐標和置信分數。 曾經用XDocument或正則表達式解析Asprise XML字串的程式碼成為直接的屬性存取。 OCR結果功能頁面涵蓋了坐標系統以及如何按置信度對結果進行過濾以自動化質量門檻。
內建預處理消除了外部成像依賴。 通過Deskew, DeNoise, Contrast, Binarize, Sharpen, Dilate, Erode, Scale, Invert, 和DeepCleanBackgroundNoise——消除了Asprise整合所需的外部成像庫。移除這一依賴消除了授權顧慮,減少了構建規模,並將預處理配置直接放在OCR配置旁。在相同程式碼文件中。預處理功能頁面和影像質量校正指南涵蓋了何時應用每個過濾器以及在低質量掃描上每個過濾器提供的可測量準確度增益。
原生異步和真正的並行性提高吞吐量。 async/await模式中,無引發執行緒池阻塞。 使用Parallel.ForEach或PLINQ的並行批量處理線性隨可用內核擴展。 Asprise LITE/STANDARD強迫順序運行的文件批次——100個文件每個2秒需要超過3分鐘——在具有IronOCR的8核機械上約需25秒. 多執行緒範例演示並行通過模式,並顯示如何使用ConcurrentBag進行執行緒安全的結果收集。
125+語言無二進位分發。 語言包作為NuGet包安裝——dotnet add package IronOcr.Languages.Arabic, dotnet add package IronOcr.Languages.Japanese——並像其他任何依賴一樣隨應用程式一起部署。 無需填充手動tessdata文件夾,無需定位語言二進位,無需在目標計算機上進行路徑配置。語言索引列出了所有125+可用的語言包。
常見問題
為什麼我應該從Asprise OCR SDK遷移到IronOCR?
常見的驅動因素包括消除COM互操作複雜性、更換基於文件的許可證管理、避免按頁收費、啟用Docker/容器部署,以及採取與標準.NET工具整合的NuGet本地工作流。
從Asprise OCR SDK遷移到IronOCR主要的程式碼變更是什麼?
用IronTesseract實例化替換Asprise OCR初始化序列,移除COM生命週期管理(明確的Create/Load/Close模式),並更新結果屬性名稱。結果是顯著減少樣板程式碼行數。
如何安裝IronOCR以開始遷移?
在套件管理器控制台中運行 'Install-Package IronOcr' 或在CLI中運行 'dotnet add package IronOcr'。語言包是單獨的包:例如 'dotnet add package IronOcr.Languages.French' 安裝法語支持。
IronOCR的OCR準確性是否匹配Asprise OCR SDK對標準商業文件的準確性?
IronOCR在包括發票、合同、收據和鍵入的表單等標準業務內容上達到高準確性。圖像預處理過濾器(糾偏、噪音去除、對比度增強)進一步提高了變質輸入的識別。
IronOCR如何處理Asprise OCR SDK單獨安裝的語言資料?
IronOCR中的語言資料分發為NuGet包。'dotnet add package IronOcr.Languages.German' 安裝德語支持。不涉及手動文件放置或目錄路徑。
從Asprise OCR SDK遷移到IronOCR是否需要更改部署基礎架構?
IronOCR要求的基礎架構更改比Asprise OCR SDK少。沒有SDK二進位路徑、授權檔案放置或授權伺服器配置。NuGet套件包含完整的OCR引擎,授權金鑰是在應用程式程式碼中設定的字串。
遷移後如何配置IronOCR許可證?
在應用啟動程式碼中分配IronOcr.License.LicenseKey = "YOUR-KEY"。在Docker或Kubernetes中,將金鑰儲存為環境變數並在啟動時讀取。在接受流量之前,使用License.IsValidLicense驗證。
IronOCR可以像Asprise OCR一樣處理PDF嗎?
是的。IronOCR能讀取本地和掃描的PDF。實例化IronTesseract,調用ocr.Read(input),其中input是PDF路徑或OcrPdfInput,並迭代OcrResult頁面。不需要單獨的PDF渲染管道。
IronOCR如何處理大批量處理中的多執行緒?
IronTesseract可以安全地在每個執行緒中實例化。在Parallel.ForEach或Task池中為每個執行緒建立一個實例,並發併運行OCR,當完成時處置每個實例。不需要全域狀態或鎖定。
IronOCR在文字提取後支持哪些輸出格式?
IronOCR返回結構化結果,包括文字、單詞坐標、信心分數和頁面結構。導出選項包括純文字、可搜索PDF以及下游處理的結構化結果物件。
IronOCR定價是否比Asprise OCR SDK更可預測,以便在工作負載擴展時使用?
IronOCR使用固定費率的永久性許可證,沒有按頁或按量收費。無論您處理10000頁還是1000萬頁,許可證費用保持不變。團隊和批量許可證選項可在IronOCR定價頁面上找到。
從Asprise OCR SDK遷移到IronOCR後,現有的測試會發生什麼變化?
遷移後,斷言提取的文字內容的測試應繼續通過。需要更新的測試是驗證API調用模式或COM物件生命週期,這需要反映IronOCR較簡單的初始化和結果模型。

