IronOCR与 Iris OCR:工程团队应该选择哪种 OCR 解决方案?
Azure Computer Vision的Read API每1,000次交易费用为$1.00,需要Azure订阅以提供Cognitive Services资源,并强制每次OCR调用通过三步异步过程:将您的文档序列化到AnalyzeAsync,然后遍历嵌套块和行以重建文本。 这是最小可行路径——多页 PDF 中的每一页都算作一次单独的交易。 IronOCR将所有这些操作简化为一个同步方法调用,完全在您的基础设施内运行,并且没有按事务计费。
了解 Azure 计算机视觉
Azure Computer Vision是Microsoft的基于云的认知服务,通过两个主要API暴露OCR:用于图像的Image Analysis API (使用VisualFeatures.Read),以及用于PDF的Azure Form Recognizer的DocumentAnalysisClient。 两者都是在Azure数据中心托管的REST后端服务,分别通过Azure.AI.FormRecognizer.DocumentAnalysis NuGet包进行访问。
主要架构特征:
-云优先,始终如一:每次 OCR 操作都会通过 HTTPS 将文档数据传输到 Microsoft 管理的服务器。 没有本地处理模式。 -订阅前提条件:团队必须先创建 Azure 帐户,预配认知服务资源,获取终结点 URL,并生成 API 密钥,然后才能编写任何一行 OCR 代码。 -按页计费:读取 API 按图像或 PDF 页收费。 一份 50 页的 PDF 文件包含 50 笔交易。 定价从前一百万笔交易每千笔 1.00 美元起,交易量越大,每笔交易价格越低 ...。 -免费套餐上限:每月 5,000 笔交易 - 足以进行原型设计,但不足以满足生产工作负载的需求。
- PDF的分离服务:基本图像OCR使用
ImageAnalysisClient。 完整的PDF处理需要一个单独的服务——Form Recognizer的DocumentAnalysisClient——具有自己的端点和配置。 -仅异步设计:所有读取 API 调用都是异步的。 本地 OCR 可以同步返回结果; 云端往返无法实现。 链中的每个调用方法都必须是async。 -速率限制:S1 等级的上限为每秒 10 笔交易。 大批量处理需要排队逻辑或分层升级。 -错误面:生产代码必须处理 HTTP 429 速率限制响应、5xx Azure 服务错误、网络超时、身份验证失败和终结点可用性——每一种都需要单独的重试逻辑。
异步轮询模式
读取 API 的异步要求会对代码结构产生影响。 使用await; 通过Form Recognizer进行的PDF处理需要使用UpdateStatusAsync进行真正的异步行为的自定义轮询。 然后,要得到结果层次结构,需要通过嵌套循环遍历块、行和单词:
// Azure Computer Vision: image OCR
// Requires: Azure subscription + Cognitive Services resource + endpoint + API key
using Azure;
using Azure.AI.Vision.ImageAnalysis;
public class AzureOcrService
{
private readonly ImageAnalysisClient _client;
public AzureOcrService(string endpoint, string apiKey)
{
// Endpoint and key provisioned in Azure portal
_client = new ImageAnalysisClient(
new Uri(endpoint),
new AzureKeyCredential(apiKey));
}
public async Task<string> ExtractTextAsync(string imagePath)
{
// Document is uploaded to Microsoft Azure
using var stream = File.OpenRead(imagePath);
var imageData = BinaryData.FromStream(stream);
var result = await _client.AnalyzeAsync(
imageData,
VisualFeatures.Read);
var text = new StringBuilder();
foreach (var block in result.Value.Read.Blocks)
{
foreach (var line in block.Lines)
{
text.AppendLine(line.Text);
}
}
return text.ToString();
}
}
// Azure Computer Vision: image OCR
// Requires: Azure subscription + Cognitive Services resource + endpoint + API key
using Azure;
using Azure.AI.Vision.ImageAnalysis;
public class AzureOcrService
{
private readonly ImageAnalysisClient _client;
public AzureOcrService(string endpoint, string apiKey)
{
// Endpoint and key provisioned in Azure portal
_client = new ImageAnalysisClient(
new Uri(endpoint),
new AzureKeyCredential(apiKey));
}
public async Task<string> ExtractTextAsync(string imagePath)
{
// Document is uploaded to Microsoft Azure
using var stream = File.OpenRead(imagePath);
var imageData = BinaryData.FromStream(stream);
var result = await _client.AnalyzeAsync(
imageData,
VisualFeatures.Read);
var text = new StringBuilder();
foreach (var block in result.Value.Read.Blocks)
{
foreach (var line in block.Lines)
{
text.AppendLine(line.Text);
}
}
return text.ToString();
}
}
Imports Azure
Imports Azure.AI.Vision.ImageAnalysis
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
Public Class AzureOcrService
Private ReadOnly _client As ImageAnalysisClient
Public Sub New(endpoint As String, apiKey As String)
' Endpoint and key provisioned in Azure portal
_client = New ImageAnalysisClient(
New Uri(endpoint),
New AzureKeyCredential(apiKey))
End Sub
Public Async Function ExtractTextAsync(imagePath As String) As Task(Of String)
' Document is uploaded to Microsoft Azure
Using stream = File.OpenRead(imagePath)
Dim imageData = BinaryData.FromStream(stream)
Dim result = Await _client.AnalyzeAsync(
imageData,
VisualFeatures.Read)
Dim text = New StringBuilder()
For Each block In result.Value.Read.Blocks
For Each line In block.Lines
text.AppendLine(line.Text)
Next
Next
Return text.ToString()
End Using
End Function
End Class
PDF处理进一步提高了复杂性——一个单独的.Text的不同结果形态。
了解IronOCR
IronOCR是一个面向.NET的商业本地部署 OCR 库,以单个NuGet包的形式提供。 它封装了一个优化的 Tesseract 5 引擎,具有自动预处理、原生 PDF 支持和同步 API,无需云凭证、无需端点配置、无需异步管道。
主要特点:
- 单个NuGet部署:
dotnet add package IronOcr安装了一切——OCR引擎、本地二进制文件以及用于英语的语言数据。 没有 tessdata 文件夹,也没有单独的本地库下载。 - 永久授权:$999 Lite / $1,499 Plus / $2,999 Professional / $5,999 Unlimited ——一次性购买,而不是订阅。 无论文件数量多少,均不收取任何单件费用。 -本地处理:所有 OCR 都在您的进程内运行。 文档永远不会离开您的基础设施。
- 自动预处理:自动应用或通过
OcrInput上的显式滤镜调用进行纠偏、降噪、对比度调整、二值化和分辨率增强。 - 本机PDF支持:
IronTesseract.Read("document.pdf")直接处理PDF,包括受密码保护的文件,无需单独的服务或额外的NuGet包。 - 125+种语言:通过单独的语言NuGet包安装——
IronOcr.Languages.French,IronOcr.Languages.ChineseSimplified等——无需手动tessdata管理。 - 线程安全:
IronTesseract是并发使用安全的。 批处理工作负载可以使用Parallel.ForEach而无需额外的同步。 - 结构化输出:
.Pages,.Paragraphs,.Lines,.Words和.Barcodes集合,包含每个元素的坐标、置信度评分和边界矩形。
功能对比
| 特征 | Azure计算机视觉 | IronOCR |
|---|---|---|
| 加工地点 | 微软 Azure 云 | 本地,现场 |
| 定价模式 | 按交易(联系 Microsoft 获取当前定价) | 永久许可证 ($999+) |
| 需要互联网连接 | 是的,始终 | 否 |
| PDF 支持 | 通过表单识别器(单独) | 内置的、原生的 |
| 设置复杂性 | Azure 帐户 + 资源 + 密钥 | NuGet安装 |
| API模式 | 异步(云 I/O) | 同步(本地) |
| 速率限制 | 10 TPS (S1) | 仅限硬件限制 |
详细功能对比
| 特征 | Azure计算机视觉 | IronOCR |
|---|---|---|
| 设置和部署 | ||
| NuGet安装 | 多个软件包 | dotnet add package IronOcr |
| 凭证配置 | 端点 URL + API 密钥 | 许可证密钥字符串 |
| 需要 Azure 订阅 | 是 | 否 |
| 需要连接互联网 | 是的,每个请求 | 否 |
| 气隙部署 | 不可能 | 完全支持 |
| Docker部署 | 需要出站网络 | 自成一体 |
| OCR功能 | ||
| 图像OCR | 是 (AnalyzeAsync) |
是 (Read()) |
| PDF OCR | 通过表单识别器(额外服务) | 原生、内置 |
| 受密码保护的PDF | 通过表单识别器 | 单个Password:参数 |
| 多页PDF(按页计费) | 是的——每页=1笔交易 | 无每页费用 |
| 可搜索的 PDF 输出 | 手工建造 | SaveAsSearchablePdf() |
| 自动预处理 | 服务器端受限 | 去斜、降噪、对比度、二值化 |
| OCR过程中的条形码读取 | 有限的 | ReadBarCodes = true |
| 基于区域的OCR | 不是直接裁剪(手动裁剪) | OcrInput上 |
| 语言支持 | ||
| 语言数量 | 164+ | 125+ |
| 语言安装 | 服务级别(由云端处理) | NuGet语言包 |
| 多种语言同时进行 | 是 | 是 (AddSecondaryLanguage) |
| 输出和结构 | ||
| 纯文本 | 是 | 是 |
| 逐字边界框 | 基于多边形 | 基于矩形 |
| 逐词置信度得分 | 是 | 是的(0-100 分) |
| 结构化层级 | 方块/线条/文字 | 页数/段落数/行数/字数 |
| hOCR导出 | 否 | 是 (SaveAsHocrFile) |
| 成本和合规性 | ||
| 单份文件成本 | 每页 0.001 美元(表单识别器) | None |
| 符合 HIPAA 标准的部署 | 复合体(BAA + 云) | 简单明了(仅限本地) |
| ITAR适用性 | 不适用于受控数据 | 完全本地部署 |
| FedRAMP 气隙 | 否 | 是 |
| 可靠性 | ||
| 网络故障模式 | 是 | None |
| 速率限制误差 | 是的(429,每秒 10 吨) | None |
| 服务可用性 SLA | 99.9%(Azure) | 您的基础设施 |
成本模型
在批量生产时,Azure 计算机视觉和IronOCR之间的交易定价差距会变得至关重要。 Azure 源文件中的成本计算器可以精确地显示计算过程。
Azure 计算机视觉方法
Azure 按交易量使用分层定价进行收费。 请查阅Azure Computer Vision 定价页面以获取当前费率。 每个PDF页面代表一次交易。 一份10页的PDF文件相当于10次计费通话。 每月可使用 5,000 次交易的免费层。
// Azure bills per transaction — costs grow with every document processed
// Free tier: 5,000 transactions/month
// Volume tiers apply at higher usage levels
// (Every PDF page multiplies the bill)
// Azure bills per transaction — costs grow with every document processed
// Free tier: 5,000 transactions/month
// Volume tiers apply at higher usage levels
// (Every PDF page multiplies the bill)
' Azure bills per transaction — costs grow with every document processed
' Free tier: 5,000 transactions/month
' Volume tiers apply at higher usage levels
' (Every PDF page multiplies the bill)
在中到高文档量下,IronOCR永久许可与持续的Azure交易费用相比很快能收回成本,此后每多处理一个文档就是节省。
IronOCR方法
IronOCR的定价模式是一个单一的数字。 安装NuGet包,设置许可证密钥,即可处理任何卷,而不会出现计数器滴答声:
// Install: dotnet add package IronOcr
// License: one-time, perpetual
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
var ocr = new IronTesseract();
// Process 1 document or 1 million — same cost
foreach (var path in documentPaths)
{
var result = ocr.Read(path);
Console.WriteLine($"Processed: {path}");
}
// Multi-page PDFs — no per-page billing
foreach (var path in pdfPaths)
{
// 1 page or 100 pages, still no extra cost
var result = ocr.Read(path);
Console.WriteLine($"{path}: {result.Pages.Length} pages processed");
}
// Install: dotnet add package IronOcr
// License: one-time, perpetual
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
var ocr = new IronTesseract();
// Process 1 document or 1 million — same cost
foreach (var path in documentPaths)
{
var result = ocr.Read(path);
Console.WriteLine($"Processed: {path}");
}
// Multi-page PDFs — no per-page billing
foreach (var path in pdfPaths)
{
// 1 page or 100 pages, still no extra cost
var result = ocr.Read(path);
Console.WriteLine($"{path}: {result.Pages.Length} pages processed");
}
' Install: dotnet add package IronOcr
' License: one-time, perpetual
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
Dim ocr As New IronTesseract()
' Process 1 document or 1 million — same cost
For Each path In documentPaths
Dim result = ocr.Read(path)
Console.WriteLine($"Processed: {path}")
Next
' Multi-page PDFs — no per-page billing
For Each path In pdfPaths
' 1 page or 100 pages, still no extra cost
Dim result = ocr.Read(path)
Console.WriteLine($"{path}: {result.Pages.Length} pages processed")
Next
无需计量,无需使用情况跟踪,无需预算提醒。 从一开始就能预测成本。 请参阅" 从图像中读取文本"教程,获取完整的入门指南。
数据主权和离线能力
云OCR的合规性问题并非纸上谈兵。 Azure计算机视觉处理的每个文档都会跨越组织边界。 Azure README 文档记录了受影响的具体监管框架:HIPAA 涵盖实体、ITAR 国防承包商、CMMC 认证组织、GDPR 监管的欧洲公司以及在物理隔离网络中的任何操作。
Azure 计算机视觉方法
即使选择了区域端点并签署了业务伙伴协议,数据流也是固定的:
// Azure: data flow for every OCR call
// 1. Your application reads the file
// 2. File is serialized to BinaryData
// 3. HTTPS transmission to Azure data center
// 4. Microsoft infrastructure processes the document
// 5. Result returned over HTTPS
// 6. You parse the result
using var stream = File.OpenRead(imagePath);
var imageData = BinaryData.FromStream(stream); // Document in memory
// This call transmits your document to Azure
var result = await _client.AnalyzeAsync(
imageData, // Document leaves your network here
VisualFeatures.Read);
// Azure: data flow for every OCR call
// 1. Your application reads the file
// 2. File is serialized to BinaryData
// 3. HTTPS transmission to Azure data center
// 4. Microsoft infrastructure processes the document
// 5. Result returned over HTTPS
// 6. You parse the result
using var stream = File.OpenRead(imagePath);
var imageData = BinaryData.FromStream(stream); // Document in memory
// This call transmits your document to Azure
var result = await _client.AnalyzeAsync(
imageData, // Document leaves your network here
VisualFeatures.Read);
Imports System.IO
Imports Azure.AI.FormRecognizer.DocumentAnalysis
' Azure: data flow for every OCR call
' 1. Your application reads the file
' 2. File is serialized to BinaryData
' 3. HTTPS transmission to Azure data center
' 4. Microsoft infrastructure processes the document
' 5. Result returned over HTTPS
' 6. You parse the result
Using stream As FileStream = File.OpenRead(imagePath)
Dim imageData As BinaryData = BinaryData.FromStream(stream) ' Document in memory
' This call transmits your document to Azure
Dim result = Await _client.AnalyzeAsync(
imageData, ' Document leaves your network here
VisualFeatures.Read)
End Using
物理隔离的网络根本无法访问终结点 URL——Azure 计算机视觉没有离线模式。 对于运行 SCIF、军事设施或隔离处理环境的组织而言,无论价格如何,该服务在架构上都是不兼容的。
IronOCR方法
IronOCR在呼叫过程中处理文档。 没有出站连接:
// IronOCR: data never leaves your infrastructure
using IronOcr;
public class OnPremiseOcrService
{
private readonly IronTesseract _ocr = new IronTesseract();
public string ExtractText(string imagePath)
{
// Runs entirely in-process
// 否 network call, no serialization to external endpoint
var result = _ocr.Read(imagePath);
return result.Text;
}
public string ExtractFromPdf(string pdfPath)
{
// PDF processed entirely on-premise, native support
using var input = new OcrInput();
input.LoadPdf(pdfPath);
return _ocr.Read(input).Text;
}
public string ExtractFromEncryptedPdf(string pdfPath, string password)
{
// Encrypted PDFs also stay local
using var input = new OcrInput();
input.LoadPdf(pdfPath, Password: password);
return _ocr.Read(input).Text;
}
}
// IronOCR: data never leaves your infrastructure
using IronOcr;
public class OnPremiseOcrService
{
private readonly IronTesseract _ocr = new IronTesseract();
public string ExtractText(string imagePath)
{
// Runs entirely in-process
// 否 network call, no serialization to external endpoint
var result = _ocr.Read(imagePath);
return result.Text;
}
public string ExtractFromPdf(string pdfPath)
{
// PDF processed entirely on-premise, native support
using var input = new OcrInput();
input.LoadPdf(pdfPath);
return _ocr.Read(input).Text;
}
public string ExtractFromEncryptedPdf(string pdfPath, string password)
{
// Encrypted PDFs also stay local
using var input = new OcrInput();
input.LoadPdf(pdfPath, Password: password);
return _ocr.Read(input).Text;
}
}
Imports IronOcr
Public Class OnPremiseOcrService
Private ReadOnly _ocr As New IronTesseract()
Public Function ExtractText(imagePath As String) As String
' Runs entirely in-process
' 否 network call, no serialization to external endpoint
Dim result = _ocr.Read(imagePath)
Return result.Text
End Function
Public Function ExtractFromPdf(pdfPath As String) As String
' PDF processed entirely on-premise, native support
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Return _ocr.Read(input).Text
End Using
End Function
Public Function ExtractFromEncryptedPdf(pdfPath As String, password As String) As String
' Encrypted PDFs also stay local
Using input As New OcrInput()
input.LoadPdf(pdfPath, Password:=password)
Return _ocr.Read(input).Text
End Using
End Function
End Class
Docker部署完全消除了出站网络需求:
FROM mcr.microsoft.com/dotnet/aspnet:8.0
RUN apt-get update && apt-get install -y libgdiplus
WORKDIR /app
COPY --from=build /app/publish .
ENV IRONOCR_LICENSE=your-key
# 否 Azure endpoint, no API key, no outbound network rules needed
ENTRYPOINT ["dotnet", "YourApp.dll"]
对于受 HIPAA 保护的实体、ITAR 合规性或 FedRAMP 隔离场景, IronOCR可以消除第三方数据处理者风险的整个类别。 请参阅Azure 部署指南,了解如何在 Azure 基础架构中运行IronOCR ,同时将文档保留在计算实例本地;并参阅Docker 部署指南,了解容器配置。
同步与异步 API 设计
Azure 读取 API 是异步的,因为它不能是同步的——云 I/O 存在网络延迟。 IronOCR在本地处理并可以同步返回,这简化了调用代码,消除了通过调用堆栈的async传播,并消除了网络I/O中固有的故障模式。
Azure 计算机视觉方法
每个Azure OCR调用需要await。 生产代码为 429 速率限制错误和 5xx 服务错误添加了重试逻辑。 一个最基本的生产环境实现如下所示:
public async Task<string> RobustExtractAsync(string imagePath)
{
const int maxRetries = 3;
int attempt = 0;
while (attempt < maxRetries)
{
try
{
using var stream = File.OpenRead(imagePath);
var imageData = BinaryData.FromStream(stream);
var result = await _client.AnalyzeAsync(
imageData,
VisualFeatures.Read);
return string.Join("\n",
result.Value.Read.Blocks
.SelectMany(b => b.Lines)
.Select(l => l.Text));
}
catch (RequestFailedException ex) when (ex.Status == 429)
{
// Rate limited — Azure caps S1 at 10 TPS
attempt++;
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
}
catch (RequestFailedException ex) when (ex.Status >= 500)
{
// Azure service error
attempt++;
await Task.Delay(TimeSpan.FromSeconds(1));
}
catch (RequestFailedException ex)
{
// Client error — bad credential, invalid endpoint
throw new Exception($"Azure OCR failed: {ex.Message}", ex);
}
}
throw new Exception("Max retries exceeded for Azure OCR");
}
public async Task<string> RobustExtractAsync(string imagePath)
{
const int maxRetries = 3;
int attempt = 0;
while (attempt < maxRetries)
{
try
{
using var stream = File.OpenRead(imagePath);
var imageData = BinaryData.FromStream(stream);
var result = await _client.AnalyzeAsync(
imageData,
VisualFeatures.Read);
return string.Join("\n",
result.Value.Read.Blocks
.SelectMany(b => b.Lines)
.Select(l => l.Text));
}
catch (RequestFailedException ex) when (ex.Status == 429)
{
// Rate limited — Azure caps S1 at 10 TPS
attempt++;
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
}
catch (RequestFailedException ex) when (ex.Status >= 500)
{
// Azure service error
attempt++;
await Task.Delay(TimeSpan.FromSeconds(1));
}
catch (RequestFailedException ex)
{
// Client error — bad credential, invalid endpoint
throw new Exception($"Azure OCR failed: {ex.Message}", ex);
}
}
throw new Exception("Max retries exceeded for Azure OCR");
}
Imports System.IO
Imports System.Threading.Tasks
Public Async Function RobustExtractAsync(imagePath As String) As Task(Of String)
Const maxRetries As Integer = 3
Dim attempt As Integer = 0
While attempt < maxRetries
Try
Using stream = File.OpenRead(imagePath)
Dim imageData = BinaryData.FromStream(stream)
Dim result = Await _client.AnalyzeAsync(
imageData,
VisualFeatures.Read)
Return String.Join(vbCrLf,
result.Value.Read.Blocks _
.SelectMany(Function(b) b.Lines) _
.Select(Function(l) l.Text))
End Using
Catch ex As RequestFailedException When ex.Status = 429
' Rate limited — Azure caps S1 at 10 TPS
attempt += 1
Await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)))
Catch ex As RequestFailedException When ex.Status >= 500
' Azure service error
attempt += 1
Await Task.Delay(TimeSpan.FromSeconds(1))
Catch ex As RequestFailedException
' Client error — bad credential, invalid endpoint
Throw New Exception($"Azure OCR failed: {ex.Message}", ex)
End Try
End While
Throw New Exception("Max retries exceeded for Azure OCR")
End Function
这并非过度防御性设计——这是生产环境中任何 Azure API 调用所需的最低限度。 速率限制、服务中断和瞬态错误是任何 Azure 用户都会遇到的实际情况。
IronOCR方法
本地处理消除了网络故障面。 错误处理范围缩小到文件系统和输入验证:
// 否 async required — local processing returns synchronously
public string ExtractText(string imagePath)
{
var result = new IronTesseract().Read(imagePath);
return result.Text;
}
// One line for simple cases
public string OneLineOcr(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
// Confidence-aware extraction
public (string Text, double Confidence) ExtractWithConfidence(string imagePath)
{
var result = new IronTesseract().Read(imagePath);
return (result.Text, result.Confidence);
}
// 否 async required — local processing returns synchronously
public string ExtractText(string imagePath)
{
var result = new IronTesseract().Read(imagePath);
return result.Text;
}
// One line for simple cases
public string OneLineOcr(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
// Confidence-aware extraction
public (string Text, double Confidence) ExtractWithConfidence(string imagePath)
{
var result = new IronTesseract().Read(imagePath);
return (result.Text, result.Confidence);
}
' 否 async required — local processing returns synchronously
Public Function ExtractText(imagePath As String) As String
Dim result = New IronTesseract().Read(imagePath)
Return result.Text
End Function
' One line for simple cases
Public Function OneLineOcr(imagePath As String) As String
Return New IronTesseract().Read(imagePath).Text
End Function
' Confidence-aware extraction
Public Function ExtractWithConfidence(imagePath As String) As (Text As String, Confidence As Double)
Dim result = New IronTesseract().Read(imagePath)
Return (result.Text, result.Confidence)
End Function
没有Task.WhenAll协调。 如果您需要异步以与异步控制器管道集成,Task.Run(() => ocr.Read(path))包装同步调用,而不对OCR逻辑本身进行结构上的更改。 IronTesseract API 参考文档涵盖了完整的同步接口。 对于真正需要异步模式的工作负载, IronOCR还提供了专门的异步 OCR 指南。
凭证和端点配置
Azure 计算机视觉需要在首次测试前预置基础架构。IronOCR 需要安装IronOCRNuGet,并且可选地需要许可证密钥字符串。
Azure 计算机视觉方法
在编写任何 OCR 代码之前,请执行以下 Azure 设置步骤:
- 如果 Azure 帐户不存在,请创建一个。
- 导航到 Azure 门户并创建认知服务资源(或 Azure AI 服务资源)。
- 选择价格等级和地区。
- 复制端点URL(格式:
https://your-resource.cognitiveservices.azure.com/)。 - 复制两个 API 密钥中的一个。
- 安全地存储两个值——在环境变量、Azure Key Vault或
appsettings.json(仅用于非生产环境)中。 - 通过NuGet安装
Azure.AI.Vision.ImageAnalysis。 - 使用端点和凭据初始化
ImageAnalysisClient。
对于PDF处理,请为Form Recognizer资源使用不同的NuGet包(DocumentAnalysisClient),重复步骤2-8。
appsettings.json存储端点和密钥:
{
"Azure": {
"ComputerVision": {
"Endpoint": "https://your-resource.cognitiveservices.azure.com/",
"ApiKey": "your-api-key"
}
}
}
轮换 API 密钥、处理凭证过期以及跨环境(开发、测试、生产)管理端点 URL 是持续的运维任务,在本地处理中没有等效项。
IronOCR方法
IronTesseract 设置指南将设置过程简化为两个步骤:
dotnet add package IronOcr
// Set once at application startup — environment variable recommended
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// Then use immediately — no endpoint, no credential rotation, no portal setup
var text = new IronTesseract().Read("document.jpg").Text;
// Set once at application startup — environment variable recommended
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// Then use immediately — no endpoint, no credential rotation, no portal setup
var text = new IronTesseract().Read("document.jpg").Text;
Imports System
' Set once at application startup — environment variable recommended
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
' Then use immediately — no endpoint, no credential rotation, no portal setup
Dim text As String = (New IronTesseract()).Read("document.jpg").Text
许可证密钥是一个静态字符串。 它不会因请求而过期,不需要轮换,激活后也不会回服务器进行验证。 部署环境无需任何出站防火墙规则即可使 OCR 功能正常运行。
API 映射参考
| Azure计算机视觉 | IronOCR当量 |
|---|---|
ImageAnalysisClient |
IronTesseract |
new AzureKeyCredential(apiKey) |
IronOcr.License.LicenseKey = key |
client.AnalyzeAsync(data, VisualFeatures.Read) |
ocr.Read(imagePath) |
BinaryData.FromStream(stream) |
input.LoadImage(stream) |
result.Value.Read.Blocks |
result.Paragraphs |
block.Lines |
result.Lines |
line.Text |
line.Text |
line.Words |
result.Words |
word.Confidence |
word.Confidence (0-100比例 vs Azure的0-1) |
word.BoundingPolygon |
word.X, word.Y, word.Width, word.Height |
DocumentAnalysisClient |
IronTesseract + OcrInput |
AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-read", stream) |
input.LoadPdf(path) |
operation.Value.Pages |
result.Pages |
page.Lines / line.Content |
result.Lines / line.Text |
RequestFailedException (429 重试) |
不适用——无费率限制 |
RequestFailedException (500 重试) |
不适用——无服务错误 |
当团队考虑从 Azure 计算机视觉迁移到IronOCR
合规性要求阻止云处理
一家医疗保健独立软件开发商在构建文档管理系统时,首先选择 Azure 计算机视觉平台,因为它集成速度快。 然后,第一位Enterprise客户出现了——一家医院系统,其 HIPAA 安全官提出了两个问题:"我们的 PHI(受保护的健康信息)会去哪里?"以及"你们能出示涵盖该第三方的业务伙伴协议 (BAA) 吗?" Azure 确实有 BAA,但第一个问题的答案——"微软数据中心"——引发了一场漫长的安全审查,要求提供微软的审计报告,以及一系列合规时间表,导致合同延期。 改用IronOCR就完全解决了这个问题。 PHI(个人健康信息)永远不会离开客户环境。 合规范围仅限于客户自身的组织内部。
交易量增长使得按交易量定价难以为继
运营团队启动了一个每月处理 5,000 份文档的发票处理流程——完全在 Azure 免费套餐的范围内。 随着量的增长,每次交易的成本随着每个处理的文档累积。IronOCRProfessional ($2,999) 是一次性购买,无需每文档费用。 即使业务量增长幅度不大,团队也能很快达到盈亏平衡点,之后每增加一份文件都能带来节省。
网络延迟影响处理服务级别协议
文档处理服务的目标是实现 2 秒的端到端服务级别协议 (SLA)。 Azure 计算机视觉在 OCR 计算本身之前,对于同一区域的调用会增加 200-800 毫秒的网络延迟,对于跨区域部署会增加 500-2000 毫秒的网络延迟。 在负载较高的情况下,S1 的 10 TPS 速率限制会强制排队,从而进一步增加延迟。 IronOCR在普通服务器硬件上处理一张 300 DPI 的图像仅需 100-400 毫秒,无需排队、没有速率限制,也无需网络跳转。由于服务级别协议 (SLA) 仅取决于硬件,而不取决于 Azure 服务运行状况或网络状况,因此 SLA 具有可预测性。
物理隔离基础设施要求
国防承包商、情报机构和关键基础设施运营商在设计上就无需连接互联网的网络上运行工作负载。 Azure 计算机视觉在技术上与这些环境不兼容——无法访问端点。 这些领域的团队需要一个能够以独立二进制文件形式部署、无需任何出站连接即可运行,并通过明确禁止云数据传输的安全审查的库。IronOCR的Linux 部署和 Docker 支持使其无需修改即可部署在受限环境中。
简化多环境部署
管理 SaaS 应用程序的开发、测试和生产环境的团队拥有三个 Azure 认知服务资源、三组 API 密钥和三个终结点 URL——每个资源都需要安全存储、轮换策略和特定于环境的配置。 每个部署环境都需要对 Azure 进行出站网络访问。 IronOCR将每个环境的配置简化为一个环境变量(IRONOCR_LICENSE),消除了网络访问需求,并消除了跨环境管理凭据的运营开销。
常见迁移注意事项
异步到同步模式
Azure消费者代码出于必要是async。 IronOCR不需要异步操作,但转换过程是机械的。 用Task.Run中包装IronOCR调用:
// Before: Azure async chain
public async Task<string> ReadTextAsync(string imagePath)
{
using var stream = File.OpenRead(imagePath);
var data = BinaryData.FromStream(stream);
var result = await _client.AnalyzeAsync(data, VisualFeatures.Read);
return string.Join("\n", result.Value.Read.Blocks
.SelectMany(b => b.Lines)
.Select(l => l.Text));
}
// After:IronOCRsynchronous
public string ReadText(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
// If async signature must be preserved for interface compatibility
public Task<string> ReadTextAsync(string imagePath)
{
return Task.Run(() => new IronTesseract().Read(imagePath).Text);
}
// Before: Azure async chain
public async Task<string> ReadTextAsync(string imagePath)
{
using var stream = File.OpenRead(imagePath);
var data = BinaryData.FromStream(stream);
var result = await _client.AnalyzeAsync(data, VisualFeatures.Read);
return string.Join("\n", result.Value.Read.Blocks
.SelectMany(b => b.Lines)
.Select(l => l.Text));
}
// After:IronOCRsynchronous
public string ReadText(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
// If async signature must be preserved for interface compatibility
public Task<string> ReadTextAsync(string imagePath)
{
return Task.Run(() => new IronTesseract().Read(imagePath).Text);
}
Imports System.IO
Imports System.Threading.Tasks
Imports IronOcr
' Before: Azure async chain
Public Async Function ReadTextAsync(imagePath As String) As Task(Of String)
Using stream = File.OpenRead(imagePath)
Dim data = BinaryData.FromStream(stream)
Dim result = Await _client.AnalyzeAsync(data, VisualFeatures.Read)
Return String.Join(vbLf, result.Value.Read.Blocks _
.SelectMany(Function(b) b.Lines) _
.Select(Function(l) l.Text))
End Using
End Function
' After: IronOCR synchronous
Public Function ReadText(imagePath As String) As String
Return New IronTesseract().Read(imagePath).Text
End Function
' If async signature must be preserved for interface compatibility
Public Function ReadTextAsync(imagePath As String) As Task(Of String)
Return Task.Run(Function() New IronTesseract().Read(imagePath).Text)
End Function
置信度标度归一化
Azure Computer Vision以0到1之间的double返回置信度。 任何基于 Azure 置信度值设置阈值的代码都需要进行调整:
// Azure: confidence is 0.0 - 1.0
foreach (var word in line.Words)
{
if (word.Confidence > 0.85f) { /* high confidence */ }
}
// IronOCR: confidence is 0 - 100
var result = new IronTesseract().Read(imagePath);
foreach (var word in result.Words)
{
if (word.Confidence > 85.0) { /* equivalent threshold */ }
}
Console.WriteLine($"Overall: {result.Confidence}%");
// Azure: confidence is 0.0 - 1.0
foreach (var word in line.Words)
{
if (word.Confidence > 0.85f) { /* high confidence */ }
}
// IronOCR: confidence is 0 - 100
var result = new IronTesseract().Read(imagePath);
foreach (var word in result.Words)
{
if (word.Confidence > 85.0) { /* equivalent threshold */ }
}
Console.WriteLine($"Overall: {result.Confidence}%");
Imports IronOcr
' Azure: confidence is 0.0 - 1.0
For Each word In line.Words
If word.Confidence > 0.85F Then
' high confidence
End If
Next
' IronOCR: confidence is 0 - 100
Dim result = New IronTesseract().Read(imagePath)
For Each word In result.Words
If word.Confidence > 85.0 Then
' equivalent threshold
End If
Next
Console.WriteLine($"Overall: {result.Confidence}%")
OcrResult API 参考文档记录了所有结果属性,包括置信度等级。 置信度评分操作指南涵盖阈值选择和逐个元素的解释。
PDF处理服务整合
Azure 将图像 OCR 和PDF OCR分开到两个独立的服务中,这些服务具有独立的客户端、 NuGet包和终结点配置。 迁移意味着将两条路径整合到一个IronTesseract实例中。 Password参数——无需第二个客户端:
// Before: Two separate Azure clients for images vs PDFs
// Image: ImageAnalysisClient + AnalyzeAsync
// PDF: DocumentAnalysisClient + AnalyzeDocumentAsync(WaitUntil.Completed, ...)
// After: One IronTesseract instance handles both
var ocr = new IronTesseract();
// Image
var imageResult = ocr.Read("document.jpg");
// PDF (same client, same Read method)
using var pdfInput = new OcrInput();
pdfInput.LoadPdf("document.pdf");
var pdfResult = ocr.Read(pdfInput);
// Password-protected PDF
using var encInput = new OcrInput();
encInput.LoadPdf("secured.pdf", Password: "secret");
var encResult = ocr.Read(encInput);
// 可搜索的 PDF 输出 — no manual construction
pdfResult.SaveAsSearchablePdf("searchable-output.pdf");
// Before: Two separate Azure clients for images vs PDFs
// Image: ImageAnalysisClient + AnalyzeAsync
// PDF: DocumentAnalysisClient + AnalyzeDocumentAsync(WaitUntil.Completed, ...)
// After: One IronTesseract instance handles both
var ocr = new IronTesseract();
// Image
var imageResult = ocr.Read("document.jpg");
// PDF (same client, same Read method)
using var pdfInput = new OcrInput();
pdfInput.LoadPdf("document.pdf");
var pdfResult = ocr.Read(pdfInput);
// Password-protected PDF
using var encInput = new OcrInput();
encInput.LoadPdf("secured.pdf", Password: "secret");
var encResult = ocr.Read(encInput);
// 可搜索的 PDF 输出 — no manual construction
pdfResult.SaveAsSearchablePdf("searchable-output.pdf");
IRON VB CONVERTER ERROR developers@ironsoftware.com
无需表单识别器的结构化数据提取
使用Form Recognizer的预构建模型(发票、收据、身份证件)进行字段提取的团队需要在IronOCR中使用基于区域的OCR与CropRectangle来复制该提取逻辑。 位置提取是显式的,而不是基于模型的:
// Form Recognizer extracted named fields automatically
// IronOCR: define extraction zones for known document layouts
var ocr = new IronTesseract();
// Define regions matching the document template
var vendorZone = new CropRectangle(0, 0, 300, 100);
var invoiceDate = new CropRectangle(400, 0, 200, 50);
var totalAmount = new CropRectangle(400, 500, 200, 100);
string vendor, date, total;
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg", vendorZone);
vendor = ocr.Read(input).Text.Trim();
}
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg", invoiceDate);
date = ocr.Read(input).Text.Trim();
}
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg", totalAmount);
total = ocr.Read(input).Text.Trim();
}
// Form Recognizer extracted named fields automatically
// IronOCR: define extraction zones for known document layouts
var ocr = new IronTesseract();
// Define regions matching the document template
var vendorZone = new CropRectangle(0, 0, 300, 100);
var invoiceDate = new CropRectangle(400, 0, 200, 50);
var totalAmount = new CropRectangle(400, 500, 200, 100);
string vendor, date, total;
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg", vendorZone);
vendor = ocr.Read(input).Text.Trim();
}
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg", invoiceDate);
date = ocr.Read(input).Text.Trim();
}
using (var input = new OcrInput())
{
input.LoadImage("invoice.jpg", totalAmount);
total = ocr.Read(input).Text.Trim();
}
Imports IronOcr
' Form Recognizer extracted named fields automatically
' IronOCR: define extraction zones for known document layouts
Dim ocr As New IronTesseract()
' Define regions matching the document template
Dim vendorZone As New CropRectangle(0, 0, 300, 100)
Dim invoiceDate As New CropRectangle(400, 0, 200, 50)
Dim totalAmount As New CropRectangle(400, 500, 200, 100)
Dim vendor As String
Dim [date] As String
Dim total As String
Using input As New OcrInput()
input.LoadImage("invoice.jpg", vendorZone)
vendor = ocr.Read(input).Text.Trim()
End Using
Using input As New OcrInput()
input.LoadImage("invoice.jpg", invoiceDate)
[date] = ocr.Read(input).Text.Trim()
End Using
Using input As New OcrInput()
input.LoadImage("invoice.jpg", totalAmount)
total = ocr.Read(input).Text.Trim()
End Using
基于区域的OCR指南详细介绍了CropRectangle的用法。 针对发票特定工作流程,发票 OCR 教程演示了完整的提取模式。
其他IronOCR功能
除了上述比较点之外, IronOCR还提供了 Azure 计算机视觉标准 OCR API 没有公开的功能:
-扫描文档处理:在 OCR 引擎看到图像之前,应用完整的预处理流程——校正倾斜、去噪、对比度、二值化、锐化,从而提高云 API 返回空结果或低置信度结果的扫描的准确性。 -长文档的进度跟踪:订阅多页 PDF 处理期间的进度事件——对于需要 UI 反馈的长时间运行的批处理作业非常有用。 -计算机视觉预处理:基于深度学习的预处理,用于处理具有挑战性的文档,例如以一定角度或在不一致的光照条件下拍摄的照片。
.NET兼容性和未来准备情况
IronOCR可通过单个NuGet包支持.NET 8、 .NET 9、 .NET Standard 2.0 和.NET Framework 4.6.2 至 4.8。 它支持 Windows x64、Windows x86、Linux x64、macOS(Intel 和 Apple Silicon)以及 ARM64——涵盖了现代.NET部署目标的全部范围,包括 Azure 应用服务、AWS Lambda、Docker 容器和本地 Linux 服务器。 Azure Computer Vision的.NET SDK (Azure.AI.Vision.ImageAnalysis) 也保留了现代.NET兼容性,但云架构意味着与语言运行时的兼容性逊于与Azure端点的兼容性,而后者是独立于SDK版本更新的。 IronOCR通过NuGet提供语言和引擎更新,使更新模型与.NET生态系统的其他部分保持一致。
结论
Azure 计算机视觉是一项功能强大的 OCR 服务,适用于已经在 Azure 生态系统中运营的团队,其文档在云传输方面没有监管限制,并且其数量符合免费层或低容量付费层的要求。 异步 API 功能齐全,标准文档的准确性可靠,表单识别器预构建模型减少了发票和收据等结构化文档类型的开发工作量。
然而,这种成本模型无法扩展。IronOCRLite每月处理 50,000 份文档,只需不到两个月节省 Azure 交易费用即可收回成本。 多页PDF按页计费会加剧成本。每超过盈亏平衡点一年,微软就少赚一笔钱。 对于任何预计每月文档处理量超过 10,000 份的团队来说,从长远来看,永久本地部署许可证更划算。
数据主权论点更为绝对。 如果 PHI、ITAR 控制的数据、律师-客户特权通信或任何在法律上或合同上不能跨越组织边界的文档类别流经您的 OCR 管道,则 Azure 计算机视觉将被排除在设计之外——不是处于劣势,而是被排除在外。IronOCR的本地处理模型能够处理这些工作负载,而不会对架构造成任何妥协。
异步轮询的复杂性确实会带来额外的开销。 重试逻辑、速率限制处理、网络故障模式,以及图像和PDF之间的DocumentAnalysisClient的划分,增加了对OCR没有价值的代码——这是云集成代码。 IronOCR的同步Read()方法以相同的代码处理图像和PDF,无需异步传播,也不需要重试逻辑。 对于那些希望将工程精力投入到应用程序而不是云 API 底层架构的团队来说,这种简单性在项目的整个生命周期中具有累积价值。
常见问题解答
什么是 Azure 计算机视觉 OCR?
Azure 计算机视觉 OCR 是一款 OCR 解决方案,开发人员和企业可以使用它从图像和文档中提取文本。它是与 IronOCR 一起评估的几种用于 .NET 应用程序开发的 OCR 选项之一。
对于 .NET 开发人员而言,IronOCR 与 Azure 计算机视觉 OCR 相比有何不同?
IronOCR 是一个基于 NuGet 的 .NET OCR 库,它使用 IronTesseract 作为核心引擎。与 Azure 计算机视觉 OCR 相比,它提供更简单的部署(无需 SDK 安装程序)、统一的定价模式以及简洁的 C# API,无需 COM 互操作或云依赖。
IronOCR 比 Azure 计算机视觉 OCR 更容易设置吗?
IronOCR 通过单个 NuGet 包进行安装。无需 SDK 安装程序、复制许可证文件、注册 COM 组件或管理单独的运行时二进制文件。整个 OCR 引擎都打包在包中。
Azure计算机视觉OCR和IronOCR在准确率方面存在哪些差异?
IronOCR 对标准商务文档、发票、收据和扫描表格的识别准确率很高。对于严重损坏的文档或不常见的文字,识别准确率会因源文件质量而异。IronOCR 包含图像预处理滤镜,可提高低质量输入文件的识别率。
IronOCR是否支持PDF文本提取?
是的。IronOCR只需一次调用即可从原生PDF和扫描的PDF图像中提取文本。它还支持多页TIFF文件、图像和流。对于扫描的PDF,OCR逐页进行处理,并为每个页面生成一个结果对象。
Azure计算机视觉OCR的许可方式与IronOCR相比有何不同?
IronOCR采用永久统一费率许可,不按页或扫描次数收费。处理大量文档的机构无论处理量多少,都只需支付相同的许可费用。详情及批量定价请访问IronOCR许可页面。
IronOCR支持哪些语言?
IronOCR 通过独立的 NuGet 语言包支持 127 种语言。添加语言只需一条命令“dotnet add package IronOcr.Languages.{Language}”。无需手动放置文件或配置路径。
如何在.NET项目中安装IronOCR ?
通过 NuGet 安装:在程序包管理器控制台中运行“Install-Package IronOcr”命令,或在命令行界面 (CLI) 中运行“dotnet add package IronOcr”命令。其他语言包的安装方式相同。无需使用原生 SDK 安装程序。
与 Azure 计算机视觉不同,IronOCR 是否适用于 Docker 和容器化部署?
是的。IronOCR 通过 NuGet 包在 Docker 容器中运行。许可证密钥通过环境变量设置。OCR 引擎本身不需要任何许可证文件、SDK 路径或卷挂载。
我可以在购买前试用 IronOCR,并将其与 Azure 计算机视觉进行比较吗?
是的。IronOCR 试用模式可以处理文档,并在输出结果上添加水印,从而生成 OCR 结果。您可以在购买许可证之前,先在自己的文档上验证其准确性。
IronOCR是否支持条形码读取和文本提取?
IronOCR专注于文本提取和OCR识别。对于条形码读取,Iron Software提供了配套库IronBarcode。两者都可单独购买,也可作为Iron Suite套装的一部分购买。
从 Azure 计算机视觉 OCR 迁移到 IronOCR 容易吗?
从 Azure 计算机视觉 OCR 迁移到 IronOCR 通常涉及将初始化序列替换为 IronTesseract 实例化、移除 COM 生命周期管理以及更新 API 调用。大多数迁移都能显著降低代码复杂度。

