从 XImage.OCR 迁移到 IronOCR
本指南面向将现有 XImage.OCR 集成迁移到IronOCR 的.NET开发人员。 它涵盖了软件包整合过程、命名空间和 API 变更,以及针对 XImage.OCR 的碎片化架构造成最大摩擦的具体代码迁移示例。 无需事先阅读对比文章。
为什么要从 XImage.OCR 迁移?
XImage.OCR 是 RasterEdge 提供的商业 Tesseract 封装程序,它通过一系列协调的NuGet包来分发其功能。 该架构在小规模应用时有效,但随着应用规模的增长,维护成本会不断增加。
**每增加一种语言,包的数量就会增加。**添加一种语言意味着添加一个NuGet包。 一个五种语言的应用程序在其.csproj中携带六个包。 一款支持十种语言的应用程序实际上包含十一种语言。 每个软件包都必须与核心版本保持一致——这一限制会导致开发人员仅更新部分软件包时出现静默的运行时故障。 IronOCR提供一套包含 125 多种语言的软件包。
版本同步是一个持续的风险。 dotnet outdated会贪婪地更新包。 当XImage.OCR.Language.French保持在12.4.0时,错误会在运行时出现,而不是在构建时,且消息很少指出版本同步是原因。 运行 CI/CD 流水线的团队会发现,需要为每个 XImage.OCR 包添加显式版本锁定——这种开销除了弥补模型碎片化之外没有任何意义。
由于没有内置预处理功能,实际文档的识别精度受到限制。XImage.OCR直接将图像传递给底层 Tesseract 引擎。即使是 150 DPI、倾斜度为两度的扫描图像,也会原封不动地导入 Tesseract。 无论使用哪个 Tesseract 封装器,此类输入的准确率上限为 60-75%。 IronOCR提供一个预处理流水线——Sharpen()——在识别运行之前修正这些问题。
结构化输出需要手动解析。XImage.OCR返回的是纯文本字符串。 提取单词位置、行边界或每个单词的置信度需要自己解析该字符串。 IronOCR返回一个Words,以及包含像素坐标和置信度评分的每字符数据。
**输出格式仅限于纯文本。**要从 XImage.OCR 结果生成可搜索的 PDF 文件,需要使用 RasterEdge PDF SDK——这需要额外购买商业软件。 IronOCR通过result.SaveAsSearchablePdf()生成可搜索的PDF,无需额外依赖。
不支持跨平台部署。XImage.OCR的目标平台是 Windows。 Linux 容器、macOS 开发环境以及 Azure 或 AWS 上的云原生部署需要不同的库。 IronOCR可在 Windows、Linux、macOS、Docker、Azure 应用服务和 AWS Lambda 上运行,只需一个软件包即可。
基本问题
XImage.OCR 需要为每种语言创建一个NuGet包。 十种语言意味着十一包,所有版本锁定彼此:
<!-- XImage.OCR: 11 packages to support 10 languages — every version must match -->
<PackageReference Include="RasterEdge.XImage.OCR" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.English" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.German" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.French" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Spanish" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Italian" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Portuguese" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.ChineseSimplified" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Japanese" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Korean" Version="12.4.0" />
<PackageReference Include="XImage.OCR.Language.Arabic" Version="12.4.0" />
IronOCR将整个代码块替换为一行:
<!-- IronOCR: One package. 125+ languages. 否 version coordination. -->
<PackageReference Include="IronOcr" Version="2024.x.x" />
IronOCR与 XImage.OCR:功能对比
下表列出了与迁移决策最相关的功能。
| 特征 | XImage.OCR | IronOCR |
|---|---|---|
| 仅限英文的NuGet包 | 2(核心+语言包) | 1 |
| 支持 10 种语言的NuGet包 | 11 | 1 |
| 需要版本同步 | 是的——所有包裹必须匹配 | 否 |
| 可用语言 | 约 15 个,以独立包裹的形式提供 | 125+ 捆绑 |
| 内置预处理 | None | 去斜、降噪、对比度、二值化、锐化、缩放、膨胀、腐蚀、反转 |
| 深度降噪 | None | 是(DeepCleanBackgroundNoise()) |
| 原生 PDF 输入 | 需要 RasterEdge PDF SDK | 是(input.LoadPdf()) |
| 可搜索的 PDF 输出 | 需要 RasterEdge PDF SDK | 是(result.SaveAsSearchablePdf()) |
| 多页 TIFF 输入 | 有限的 | 是(input.LoadImageFrames()) |
| 字节数组输入 | 通过 MemoryStream 手动操作 | 是(input.LoadImage(bytes)) |
| 流输入 | 手册 | 是(input.LoadImage(stream)) |
| 结构化输出 | 普通字符串 | 页、段落、行、单词、字符及其坐标 |
| 逐词置信度得分 | 不可用 | 是 |
| 条形码读取 | 不可用 | 是(ocr.Configuration.ReadBarCodes = true) |
| hOCR导出 | 不可用 | 是 |
| 线程安全 | 不线程安全 | 全螺纹安全 |
| 内存模型(并行) | 每个线程一个处理程序实例 | 单个共享实例 |
| 跨平台 | 主要使用 Windows 系统 | Windows、Linux、macOS、Docker、Azure、AWS |
| .NET兼容性 | .NET Standard 2.0、 .NET Framework 4.5+ | .NET Framework 4.6.2+、. .NET Core、 .NET 5/6/7/8/9 |
| 许可证类型 | 商业版(RasterEdge) | 永久使用(Lite $999,Pro $1,499,Enterprise $2,999) |
| 商业支持 | RasterEdge 支持 | 是的,按许可证分级。 |
快速入门:XImage.OCR 到IronOCR 的迁移
步骤 1:替换 NuGet 软件包
删除所有 XImage.OCR 软件包。 命令数量与您安装的语言包数量一致:
dotnet remove package RasterEdge.XImage.OCR
dotnet remove package XImage.OCR.Language.English
dotnet remove package XImage.OCR.Language.German
dotnet remove package XImage.OCR.Language.French
# Repeat for every language pack in your project
从NuGet安装IronOCR :
步骤 2:更新命名空间
将 RasterEdge 命名空间导入替换为单个IronOCR命名空间:
// Before (XImage.OCR)
using RasterEdge.XImage.OCR;
using RasterEdge.Imaging.Basic;
// After (IronOCR)
using IronOcr;
步骤 3:初始化许可证
在应用程序启动时,在任何 OCR 调用之前,添加一次许可证初始化:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"将密钥存储在环境变量或密钥管理器中,而不是硬编码:
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");Imports System
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")代码迁移示例
多包初始化合并
第一个迁移任务是将 XImage.OCR 初始化块(许可证激活、处理程序创建和基于字符串的语言分配)合并到IronOCR等效项中。
XImage.OCR 方法:
// Requires: RasterEdge.XImage.OCR + one XImage.OCR.Language.* package per language
// Language strings must exactly match installed package names or OCR fails at runtime
RasterEdge.XImage.OCR.License.LicenseManager.SetLicense("your-ximage-license-key");
var ocrHandler = new OCRHandler();
// String codes — typo "enh" instead of "eng" silently fails or throws at runtime
ocrHandler.Languages = new[] { "eng", "deu", "fra", "spa", "ita" };
// Process returns a plain string — no structure, no confidence
string extractedText = ocrHandler.Process("document.png");
Console.WriteLine(extractedText);
IronOCR方法:
// Requires: IronOcr (single package — all languages included)
IronOcr.License.LicenseKey = "YOUR-IRONOCR-LICENSE-KEY";
var ocr = new IronTesseract();
// Type-safe enum — compiler catches typos, no runtime surprises
ocr.Language = OcrLanguage.English + OcrLanguage.German +
OcrLanguage.French + OcrLanguage.Spanish + OcrLanguage.Italian;
using var input = new OcrInput();
input.LoadImage("document.png");
var result = ocr.Read(input);
Console.WriteLine(result.Text);
Console.WriteLine($"Confidence: {result.Confidence}%");
XImage.OCR中的基于字符串的语言代码("deu")在缺少对应的NuGet包或版本错误时,运行时会失败。 IronOCR中的OcrLanguage枚举使得无效的语言组合无法编译。IronTesseract设置指南全面介绍了引擎配置选项,多语言操作指南记录了混合语言文档中主要和次要语言组合的工作情况。
图像格式处理统一
XImage.OCR 根据图像格式的不同,对每种图像源的处理方式也不同。 字节数组、流和文件路径各自需要略有不同的代码路径。 IronOCR通过相同的OcrInput方法接受所有这些。
XImage.OCR 方法:
// XImage.OCR: different handling per image source type
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
// File path — works directly
string resultFromFile = ocrHandler.Process("invoice.jpg");
// Byte array — must write to temp file first, then process
byte[] imageBytes = File.ReadAllBytes("invoice.jpg");
string tempPath = Path.GetTempFileName() + ".jpg";
File.WriteAllBytes(tempPath, imageBytes);
try
{
string resultFromBytes = ocrHandler.Process(tempPath);
Console.WriteLine(resultFromBytes);
}
finally
{
File.Delete(tempPath); // 手册 cleanup — easy to forget
}
// Multi-page TIFF — must split frames manually
// 否 built-in TIFF frame iteration in base XImage.OCR
IronOCR方法:
// IronOCR: unified OcrInput accepts all source types identically
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
// File path
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg");
var result = ocr.Read(input);
Console.WriteLine($"From file: {result.Text}");
}
// Byte array — no temp file needed
byte[] imageBytes = File.ReadAllBytes("invoice.jpg");
using (var input = new OcrInput())
{
input.LoadImage(imageBytes);
var result = ocr.Read(input);
Console.WriteLine($"From bytes: {result.Text}");
}
// Multi-page TIFF — all frames processed in one call
using (var input = new OcrInput())
{
input.LoadImageFrames("scanned-archive.tiff");
var result = ocr.Read(input);
Console.WriteLine($"TIFF pages: {result.Pages.Count}");
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
}
XImage.OCR 中字节数组的临时文件模式是磁盘膨胀和错误路径中文件泄漏的常见来源。 IronOCR的LoadImage(byte[])完全取消了中间文件。 图像输入指南和TIFF/GIF 输入指南涵盖所有支持的源类型,包括流和多帧处理。
输出格式简化
XImage.OCR 返回一个纯字符串。 生成可搜索的 PDF 需要第二个 RasterEdge 产品。 IronOCR无需额外软件包,即可从同一个结果对象生成纯文本、可搜索的 PDF 和结构化数据。
XImage.OCR 方法:
// XImage.OCR: plain text output only
// Searchable PDF requires purchasing the RasterEdge PDF SDK separately
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
string plainText = ocrHandler.Process("scanned-contract.jpg");
// To produce a searchable PDF from this text, you would need:
// 1. Purchase RasterEdge PDF SDK (separate commercial license)
// 2. Create a PDF document programmatically
// 3. Embed the extracted text as invisible text layer over the image
// 4. Manage the PDF document lifecycle manually
// 否 built-in path from OCR result to searchable PDF in XImage.OCR alone
Console.WriteLine(plainText);
IronOCR方法:
// IronOCR: plain text, searchable PDF, and structured data from one result
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("scanned-contract.jpg");
var result = ocr.Read(input);
// Plain text
Console.WriteLine(result.Text);
// Searchable PDF — no extra package required
result.SaveAsSearchablePdf("searchable-contract.pdf");
// Structured data: paragraphs with bounding box coordinates
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Paragraph at ({paragraph.X}, {paragraph.Y}): {paragraph.Text}");
}
}
// Per-word confidence for quality gating
var lowConfidenceWords = result.Pages
.SelectMany(p => p.Words)
.Where(w => w.Confidence < 70)
.ToList();
Console.WriteLine($"Words below 70% confidence: {lowConfidenceWords.Count}");
SaveAsSearchablePdf()调用将识别出的文本作为隐藏层嵌入到原始图像下,使文档在不改变其视觉外观的情况下完全可搜索。 这份可搜索的 PDF 使用指南涵盖了页面范围选项和 DPI 设置。 对于结构化数据提取模式,阅读结果指南记录了完整的OcrResult层次结构,包括单词坐标和置信度访问。 可搜索 PDF 示例提供了一个完整的可运行实现。
批量文档处理
XImage.OCR 不是线程安全的。 每个并发工作线程必须创建自己的OCRHandler实例,乘以线程数增加内存消耗。 IronOCR在所有线程中使用单个共享实例。
XImage.OCR 方法:
// XImage.OCR: one handler per thread — memory multiplies with concurrency
// 4 threads processing English documents: 4 x ~100MB = ~400MB for OCR alone
// 4 threads processing 5 languages: 4 x ~250MB = ~1GB just for OCR handlers
var results = new ConcurrentDictionary<string, string>();
string[] documentPaths = Directory.GetFiles("./incoming", "*.png");
Parallel.ForEach(documentPaths,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
documentPath =>
{
// Each thread must create and dispose its own handler
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
try
{
string text = ocrHandler.Process(documentPath);
results[documentPath] = text;
}
finally
{
// 手册 disposal required — no using statement support shown
ocrHandler.Dispose();
}
});
foreach (var kvp in results)
Console.WriteLine($"{Path.GetFileName(kvp.Key)}: {kvp.Value.Length} chars");
IronOCR方法:
// IronOCR: single IronTesseract instance shared across all threads
// Memory stays flat regardless of thread count
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract(); // Create once outside the parallel loop
var results = new ConcurrentDictionary<string, string>();
string[] documentPaths = Directory.GetFiles("./incoming", "*.png");
Parallel.ForEach(documentPaths, documentPath =>
{
// OcrInput is created per thread — IronTesseract instance is shared
using var input = new OcrInput();
input.LoadImage(documentPath);
input.Deskew(); // Preprocessing runs per-document, not per-thread engine
input.DeNoise();
var result = ocr.Read(input);
results[documentPath] = result.Text;
});
foreach (var kvp in results)
Console.WriteLine($"{Path.GetFileName(kvp.Key)}: {kvp.Value.Length} chars");
XImage.OCR 的线程处理程序模式意味着加载五种语言的四线程批处理作业在处理单个文档之前大约会占用 1GB 的 OCR 处理程序内存。IronOCR的共享实例将内存占用限制在单个实例的范围内,而不管并行度如何。 多线程示例完整地展示了这种模式,速度优化指南涵盖了以吞吐量为中心的批处理工作负载的配置调整。
条形码和文本组合提取
XImage.OCR 不具备条形码读取功能。 同时包含文本和条形码的文档需要两个独立的库和两次独立的处理。 IronOCR可以在一次读取操作中同时提取两者。
XImage.OCR 方法:
// XImage.OCR: text only — barcodes require a separate library and second pass
var ocrHandler = new OCRHandler();
ocrHandler.Language = "eng";
// Pass 1: text extraction with XImage.OCR
string documentText = ocrHandler.Process("warehouse-label.png");
Console.WriteLine($"Text: {documentText}");
// Pass 2: barcode reading requires a completely separate library
// e.g., ZXing.Net, Dynamsoft Barcode Reader, or another commercial SDK
// - Additional NuGet package required
// - Additional license required
// - Additional code for result merging
// 否 combined text + barcode result object exists in XImage.OCR
IronOCR方法:
// IronOCR: text and barcodes from a single Read() call
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
ocr.Configuration.ReadBarCodes = true; // Enable barcode extraction
using var input = new OcrInput();
input.LoadImage("warehouse-label.png");
var result = ocr.Read(input);
// Text and barcodes in one result object
Console.WriteLine($"Document text:\n{result.Text}");
if (result.Barcodes.Any())
{
Console.WriteLine($"\nBarcodes found: {result.Barcodes.Count}");
foreach (var barcode in result.Barcodes)
Console.WriteLine($" [{barcode.BarcodeType}] {barcode.Value}");
}
设置ReadBarCodes = true可在识别过程中添加条码检测,无需第二个库或第二次读取。 条形码读取方法和条形码 OCR 示例涵盖了混合内容文档支持的条形码格式和配置选项。
XImage.OCR API 到IronOCR映射参考
| XImage.OCR | IronOCR当量 |
|---|---|
new OCRHandler() | new IronTesseract() |
RasterEdge.XImage.OCR.License.LicenseManager.SetLicense("key") | IronOcr.License.LicenseKey = "key" |
ocrHandler.Language = "eng" | ocr.Language = OcrLanguage.English |
ocrHandler.Languages = new[] { "eng", "deu" } | ocr.Language = OcrLanguage.English + OcrLanguage.German |
ocrHandler.Process(imagePath) | input.LoadImage(path)之后) |
ocrHandler.Process(image)(来自对象) | input.LoadImage(stream) |
ocrHandler.ProcessRegion(path, rect) | input.LoadImage(path, new CropRectangle(x, y, w, h)) |
ocrHandler.SetVariable("tessedit_char_whitelist", "0-9") | ocr.Configuration.WhiteListCharacters = "0123456789" |
result(纯字符串) | result.Text |
result.MeanConfidence | result.Confidence |
| 没有等效物 | result.Pages / result.Paragraphs / result.Lines |
| 没有等效物 | .Confidence) |
| 没有等效物 | result.SaveAsSearchablePdf("output.pdf") |
| 没有等效物 | input.Deskew() |
| 没有等效物 | input.DeNoise() |
| 没有等效物 | input.Contrast() |
| 没有等效物 | input.Binarize() |
| 没有等效物 | input.Sharpen() |
| 没有等效物 | input.LoadImageFrames("file.tiff")(多帧) |
| 需要 RasterEdge PDF SDK | input.LoadPdf(pdfPath) |
| 需要 RasterEdge PDF SDK | result.SaveAsSearchablePdf("output.pdf") |
| 不可用 | ocr.Configuration.ReadBarCodes = true |
每线程OCRHandler实例 | 单个共享IronTesseract实例 |
常见迁移问题和解决方案
问题 1:部分软件包更新后运行时失败
**XImage.OCR:**运行RasterEdge.XImage.OCR升级到新版本,而语言包却维持在旧版本。 故障发生在运行时的第一次 OCR 调用期间,错误消息没有明确指出版本不匹配是根本原因。 找到这个差异需要手动检查所有PackageReference条目。
**解决方案:**移除 XImage.OCR 软件包并安装IronOCR后,无需维护版本同步。 单个IronOcr包携带着所有内容。 如果需要超出捆绑默认的语言包,请独立安装IronOcr.Languages.*包——它们不需要匹配核心的版本:
问题二:字符串语言代码导致OCR识别无声失败
**XImage.OCR:**语言代码是字符串("fra")。 语言代码中的一个拼写错误——"deu"——会根据XImage.OCR版本不同,悄然回退到默认语言或抛出运行时异常。 这两种结果在编译时都无法被捕获。
**解决方案:**IronOCR使用OcrLanguage枚举。 无效值是编译错误,而不是运行时错误。 将字符串数组迁移到枚举表达式:
// Before (XImage.OCR) — typos compile fine, fail at runtime
ocrHandler.Languages = new[] { "eng", "deu", "fra" };
// After (IronOCR) — typos are compile errors
ocr.Language = OcrLanguage.English + OcrLanguage.German + OcrLanguage.French;
请参阅多语言指南,了解如何在包含混合语言内容的文档中结合主要语言和次要语言。
问题 3:字节阵列处理后磁盘上遗留的临时文件
**XImage.OCR:**从字节数组处理图像需要写入一个临时文件,因为OCRHandler.Process()接受的是文件路径而非缓冲区。 跳过finally块的异常路径会将这些临时文件留在磁盘上。 在高通量应用中,这种现象会迅速积累。
解决方案:byte[]。 未创建临时文件:
// Before (XImage.OCR) — temp file required
string tempPath = Path.GetTempFileName() + ".png";
File.WriteAllBytes(tempPath, imageBytes);
try { text = ocrHandler.Process(tempPath); }
finally { File.Delete(tempPath); }
// After (IronOCR) — direct byte array loading, no disk I/O
using var input = new OcrInput();
input.LoadImage(imageBytes);
var result = ocr.Read(input);
string text = result.Text;
问题 4:并行负载下的内存耗尽
**XImage.OCR:**并行处理需要每个线程一个OCRHandler。 八个线程处理五种语言的文档,分别加载八个独立的引擎实例,每个实例都包含所有五种语言包。 每个语言每个实例大约需要 50MB 内存,8 个线程在文档数据进入之前,仅 OCR 引擎内存就消耗大约 2GB。
**解决方案:**单个IronTesseract实例处理所有线程。 每个文档创建IronTesseract:
// Single instance — shared safely across all threads
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English + OcrLanguage.German +
OcrLanguage.French + OcrLanguage.Spanish + OcrLanguage.Italian;
Parallel.ForEach(documentPaths, path =>
{
using var input = new OcrInput(); // Per-document, lightweight
input.LoadImage(path);
var result = ocr.Read(input); // Thread-safe call on shared instance
ProcessResult(result.Text);
});
问题 5:部分恢复后 CI/CD 流水线中断
**XImage.OCR:**具有预热包缓存的 CI/CD 代理通常会缓存一些旧版本的 XImage.OCR 语言包。 当项目文件中仅更新了核心包时,还原操作成功,但运行时加载了不匹配的程序集。 构建通过; 部署失败。
**解决方案:**迁移到IronOCR后,CI/CD 管道恢复一个软件包。 添加验证步骤,以确认预期版本是否存在:
# In your CI pipeline — verify single package restore
dotnet restore
dotnet list package | grep IronOcr
# 否 version coordination logic needed — only one package to check
问题 6:下游解析缺少结构化数据
**XImage.OCR:**返回一个纯字符串。 需要单词位置、行分组或每个单词置信度的应用程序必须使用空格启发式方法或自定义逻辑来解析字符串。 对于多列布局、表格或旋转文本的文档,这种解析的准确性会降低。
**解决方案:**IronOCR的OcrResult直接公开完整的文档层次结构。 无需字符串解析:
var result = ocr.Read(input);
// Direct access to structured data — no string manipulation
foreach (var page in result.Pages)
{
foreach (var line in page.Lines)
{
// Line text, bounding box, and per-word data all available
Console.WriteLine($"Line [{line.X},{line.Y}]: {line.Text}");
foreach (var word in line.Words)
Console.WriteLine($" Word '{word.Text}' confidence: {word.Confidence}%");
}
}
有关完整的结构化数据 API,请参阅读取结果操作指南和OCR 结果功能页面。
XImage.OCR迁移检查清单
迁移前
在进行任何更改之前,请审核代码库,找出所有与 XImage.OCR 相关的代码点:
# Find all XImage.OCR namespace imports
grep -r "RasterEdge.XImage.OCR\|Yiigo.Image.Ocr\|XImage.OCR" --include="*.cs" .
# Find all OCRHandler usages
grep -r "OCRHandler\|ocrHandler" --include="*.cs" .
# Find all string-based language assignments
grep -r "\.Language\s*=\s*\"" --include="*.cs" .
grep -r "\.Languages\s*=\s*new\[\]" --include="*.cs" .
# Find all XImage.OCR package references in project files
grep -r "RasterEdge.XImage.OCR\|XImage.OCR.Language" --include="*.csproj" .
# Count distinct language packs installed
grep "XImage.OCR.Language" --include="*.csproj" -r . | wc -l
注意正在使用的图像源类型(文件路径、字节数组、流、TIFF),并确定任何使用临时文件进行字节数组处理的位置。 这些是优先清理目标。
代码迁移
- 从每个
XImage.OCR.Language.*包引用 - 添加
dotnet add package IronOcr) - 在所有文件中用
using RasterEdge.XImage.OCR - 在应用程序启动时添加
IronOcr.License.LicenseKey = ...(每个进程一次) - 用
new OCRHandler() - 用
"deu") - 用
input.LoadImage(path)+ocrHandler.Process(path) - 用
input.LoadImage(byte[])替换字节数组到临时文件模式 - 用
input.LoadImageFrames("file.tiff")替换多页TIFF手动帧拆分 - 从
IronTesseract实例 - 在每个
input.DeNoise()) - 用
result.SaveAsSearchablePdf() - 用
ocrHandler.SetVariable("tessedit_char_whitelist", ...) - 更新CI/CD流水线:移除多包还原步骤,移除版本同步逻辑,验证单个
IronOcr包还原
后迁移
- 确认基本文本提取功能能够从已知良好的测试图像中产生正确的输出。
- 验证多语言文档是否返回所有已配置语言的文本
- 测试字节数组输入路径可产生正确输出,且不会在磁盘上创建临时文件。
- 确认多页TIFF文档在
result.Pages中返回正确的页数 - 在负载下运行并行批处理并测量峰值内存使用量——应显著低于 XImage.OCR 基线水平。
- 验证可搜索的 PDF 输出文件是否能在 Adobe Acrobat 或其他 PDF 查看器中正确打开,并且文本可选中。
- 在低质量或倾斜的扫描图像上测试预处理,并将提取的文本准确率与 XImage.OCR 基线进行比较。
- 确认许可证密钥初始化在首次 OCR 调用之前运行,并且不会抛出异常。
- 验证在无缓存包的干净环境中 CI/CD 恢复是否成功
- 检查结构化数据输出(
result.Paragraphs)是否符合预期文档布局
迁移到IronOCR的主要优势
单个包取代整个依赖图。 每个dotnet add package IronOcr命令。 .csproj条目数从十一降到一个。 CI/CD 恢复步骤从具有 11 个独立故障点的多包操作变为单个包恢复。 这种简化带来了诸多好处:需要审核安全漏洞的软件包更少, .NET兼容性更改时需要更新的条目更少,而且在自动更新管道中无需维护版本协调逻辑。 IronOCR产品页面和文档中心提供了完整的功能和部署参考。
预处理精度提升立竿见影。此次迁移并非简单的替换,而是精度的提升。 由于倾斜、噪声或低分辨率导致XImage.OCR处理精度下降的任何文档,现在可以通过input.Contrast()获得直接的改进路径。 没有外部图像处理库,开发团队没有图像处理方面的专业知识,无需单独授权和维护依赖项。 在LoadImage()之后添加三行代码,可以使之前被认为"足够好"的扫描文档的准确性恢复20-35个百分点。图像质量校正指南和预处理功能页面涵盖了不同文档质量场景中每个滤波器的效果。
可搜索的 PDF 和结构化数据无需额外购买 SDK。XImage.OCR用户最常见的两个需求——可搜索的 PDF 输出和带有坐标的词级数据——都需要额外的 RasterEdge 产品,而这些产品会产生单独的商业许可费用。 迁移后,result.Words提供带有边界框和置信度评分的结构化数据。 以前需要两份许可证才能实现的功能,现在一份许可证就能搞定。 完整的输出格式文档位于OCR 结果功能页面上。
并行处理可扩展且不会增加内存开销。XImage.OCR的线程级处理模型使得扩展成本很高。线程数翻倍会导致 OCR 引擎实例消耗的内存也翻倍。IronOCR的共享实例模型意味着无论并行度如何,内存占用始终保持在单个实例的范围内。 服务器以八个并发线程批量处理文档与服务器一次处理一个文档消耗的 OCR 引擎内存相同。这直接转化为更低的托管成本和更高的固定基础设施吞吐量。
跨平台部署无需更改代码即可开启。 相同的IronOcr包和相同的应用程序代码运行于Windows、Linux、macOS、Docker、Azure应用服务和AWS Lambda。 没有平台相关的代码,没有平台特定的软件包变体,没有针对每个环境的 OCR 层部署测试。 使用容器化工作负载、运行 macOS 开发环境或部署到基于 Linux 的云基础设施的团队可立即获得兼容性。 Docker 部署指南、 Azure 部署指南和Linux 部署指南分别记录了每个目标环境的设置。
支持 125 种以上的语言,突破了语言覆盖范围的上限。XImage.OCR的商业软件包最多只支持大约 15 种语言。 标准tessdata分发包含超过100种语言,完全免费。IronOCR捆绑了125+种语言,并通过遵循清洁安装模式而没有版本锁定约束的可选IronOcr.Languages.*包公开。 欧盟 24 种官方语言、所有主要中日韩语言、阿拉伯语、希伯来语和特殊文字均可使用。 语言索引列出了所有受支持的语言及其对应的软件包名称。
