跳至页脚内容
与其他组件比较

OCR API Microsoft Azure Vision 与IronOCR:哪个更擅长处理文档图像?

在读取 Tesseract 的单个 OCR 结果之前,您需要编写一个预处理流程——灰度转换、对比度增强、二值化、噪声去除、倾斜校正、DPI 缩放——大约 180 行图像处理代码,而这些代码与文本识别无关。 这就是 charlesw Tesseract 包装器的真正成本:不是零美元的许可费,而是 20-40 小时的工程工作,以使引擎能够可靠地处理在非理想条件下扫描的文档。 然后你发现你的应用程序接收 PDF 文件,而整个流程需要从头开始,在前端添加一个 PDF 渲染库。

理解超立方体

Tesseract NuGet包(charlesw封装器)是一个P/Invoke桥接器,将本地Tesseract OCR引擎暴露给.NET应用程序。 它封装了 Leptonica 图像处理库和 Tesseract 引擎二进制文件,使 C# 开发人员能够直接访问功能最强大的开源 OCR 引擎之一。

Tesseract 本身是开源世界中 OCR 的支柱。 该引擎最初于 20 世纪 80 年代由惠普公司开发,并于 2005 年由谷歌开源,仅通过 charlesw 包装器就获得了近 800 万次NuGet下载。 这个数字反映的是真正的实用性,而不是某个小众项目。 当图像清晰且格式良好时,Tesseract 只需极少的配置即可达到 95% 以上的准确率。

影响该库所有生产用途的关键架构事实:

-仅图像输入: Tesseract 处理图像。 它没有内置的PDF渲染器。 每个 PDF 工作流程都需要一个单独的库(PdfiumViewer、PDFtoImage、Docnet.Core、GhostScript)将每一页转换为图像,然后 Tesseract 才能对其进行处理。 -需要手动预处理: Tesseract 需要清晰、高分辨率、方向正确的图像。 它不提供任何内置过滤器。 倾斜、噪声、低 DPI 和彩色背景都会降低图像精度,而这种校正完全是开发人员的责任。

  • Tessdata文件管理:语言识别依赖于从GitHub下载并放置在.traineddata文件。 每种语言的文件大小为 15-100 MB。 每个环境——开发环境、CI环境、测试环境、生产环境、Docker环境——都必须在正确的路径下拥有正确的文件。
  • 本地二进制文件部署:封装器提供特定平台的本地库(tesseract50.dll, leptonica-1.82.0.dll在Windows上; .so文件在Linux上)。 这些组件必须与应用程序一起部署,并与目标架构相匹配。
  • 非线程安全引擎:TesseractEngine实例不能跨线程共享。 并行处理需要为每个线程创建一个引擎,这将使引擎初始化的 40-100 MB 内存占用量乘以并行度。
  • Tesseract 版本锁定为 4.1.1: charlesw 封装器跟踪 2019 年发布的 Tesseract 4.1.1 版本。此软件包不提供具有改进的 LSTM 精度的 Tesseract 5.x 版本。

预处理差距

预处理要求并非可省略的配置选项。它决定了实际文档的输出结果是否准确无误,否则将导致输出结果无法使用。 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: 德斯丘 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: 德斯丘 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
    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 image processing steps
    Private Shared Function ConvertToGrayscale(original As Bitmap) As Bitmap
        ' Implementation here
        Return original
    End Function

    Private Shared Function EnhanceContrast(grayscale As Bitmap) As Bitmap
        ' Implementation here
        Return grayscale
    End Function

    Private Shared Function Binarize(enhanced As Bitmap, threshold As Integer) As Bitmap
        ' Implementation here
        Return enhanced
    End Function

    Private Shared Function RemoveNoise(binarized As Bitmap) As Bitmap
        ' Implementation here
        Return binarized
    End Function

    Private Shared Function Deskew(denoised As Bitmap) As Bitmap
        ' Implementation here
        Return denoised
    End Function

    Private Shared Function ScaleToDpi(deskewed As Bitmap, dpi As Integer) As Bitmap
        ' Implementation here
        Return deskewed
    End Function

    Private Shared Function RunTesseract(scaled As Bitmap) As String
        ' Implementation here
        Return String.Empty
    End Function
End Class
$vbLabelText   $csharpLabel

嵌套的using结构不是样板——每一步都是实际实现:用于灰度化的颜色矩阵,用于对比度的像素迭代,用于二值化的另一个像素迭代,用于去噪的中值滤波器,替代霍夫变换的去偏斜。 image-preprocessing-tesseract.cs源代码直接指出:"简化的去偏斜——实际实现需要霍夫变换。 这通常需要 OpenCV 或类似的库。

总共大约读了 180 行,才读到一个字。 同一文件中的准确率表显示了为什么这项投资是必要的——未经预处理的 Tesseract 对倾斜 5 度的文档的准确率为 60-70%,而经过适当预处理的输入可达到 90% 以上。

了解IronOCR

IronOCR是一个商业的.NET OCR 库,它嵌入了一个优化的 Tesseract 5 LSTM 引擎,以及一个内置的预处理管道、原生 PDF 支持和一个无需原生二进制管理的托管 API。 该库以单个NuGet包的形式安装,没有 tessdata 文件夹,没有特定于平台的 DLL 部署步骤,也没有额外的 PDF 渲染库。

IronOCR设计的关键特征:

  • 自动预处理:去偏斜、去噪、对比度、二值化和增强分辨率都是对OcrInput的一行方法调用。 该引擎默认还会在 OCR 开始之前应用智能自动预处理。
  • 本地PDF输入:input.LoadPdf()接受扫描PDF、数字PDF和混合PDF,无需外部依赖。 受密码保护的 PDF 文件需要一个额外的参数。
  • 通过NuGet提供的125+种语言:语言包作为标准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 Unlimited——一次性购买,无单页收费。

功能对比

特征 超立方体(charlesw) IronOCR
许可 Apache 2.0(免费) 商业($999+永久)
PDF 输入 无 — 需要外部库 原生内置
图像预处理 手动编写——100多行代码 自动+一行方法
语言管理 手动下载 tessdata 文件 NuGet包安装
线程安全 非线程安全(每个线程独立的引擎) 线程安全的单实例
部署 本地 DLL + tessdata 文件夹 单个 NuGet 软件包
Tesseract 版本 4.1.1 (2019) 5.x 版本优化

详细功能对比

类别/功能 超立方体(charlesw) IronOCR
安装和设置
NuGet安装 Install-Package Tesseract Install-Package IronOcr
其他设置步骤 tessdata 下载 + 路径配置 None
原生二进制部署 要求 捆绑式
多克设置 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-100MB 共享池
产出和结果
纯文本 page.GetText() result.Text
词级边界框 ResultIterator循环 result.WordsLINQ
置信度得分 page.GetMeanConfidence() result.Confidence
可搜索的PDF 不支持 result.SaveAsSearchablePdf()
hOCR导出 page.GetHOCRText() result.SaveAsHocrFile()
条形码检测 不支持 ocr.Configuration.ReadBarCodes = true
平台支持
视窗
Linux 需要编译/apt-get
MacOS 需要手动设置
多克 多步骤设置 开箱即用

预处理差距

预处理要求是造成预计耗时 20-40 小时的原因。 这绝非夸张。 使用 Tesseract 从头开始​​构建可靠的预处理流程意味着要实现IronOCR内置的每一个转换。

超立方体方法

image-preprocessing-tesseract.cs中显示的完整预处理流程需要System.Drawing.Common(仅限Windows)或一个额外的跨平台库如ImageSharp。仅去偏斜实现就表明它是简化的——生产级偏斜检测算法需要霍夫线变换,这通常意味着引入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
$vbLabelText   $csharpLabel

这是来自源文件的真实代码——并非人为设定的最坏情况。 像素迭代法用于对比度和噪声去除,对每个像素的计算复杂度为 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
$vbLabelText   $csharpLabel

没有临时文件。 无需像素迭代。 不依赖 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
$vbLabelText   $csharpLabel

对于干净、高分辨率的输入,这不会产生任何成本。 在 72 DPI 的手机照片上,引擎会先进行缩放、增强和归一化处理,然后再识别文本。

PDF差距

PDF是商业文档的标准交付格式。 合同、发票、银行对账单、医疗记录——它们都是以 PDF 格式发送的。 Tesseract 无法打开 PDF 文件。 构建这座桥梁需要另一个库、另一个本地依赖项以及 50-150 行粘合代码。

超立方体方法

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
$vbLabelText   $csharpLabel

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")
$vbLabelText   $csharpLabel

没有PDF渲染库。 没有临时文件。 无需考虑AGPL许可协议。 PDF 输入操作指南涵盖了所有 PDF 输入方式。 这份可搜索的 PDF 操作指南解释了文本层输出。 对于构建文档处理管道的团队而言, PDF OCR 用例页面提供了生产架构模式。

预处理方法对PDF输入完全相同,允许在扫描PDF上进行相同的input.Deskew(), input.DeNoise(), input.EnhanceResolution()调用,而无需中间转换步骤。

Tessdata 管理

每次Tesseract部署都会遇到tessdata文件夹问题。 该文件夹必须存在,包含正确的TesseractEngine初始化中指定的路径上是可访问的。 这会导致部署复杂性随着规模的扩大而加剧。

超立方体方法

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
$vbLabelText   $csharpLabel

防御性的文件存在检查不是多余的——缺少TesseractException: Failed to initialise tesseract engine,其消息不总是明确标识缺少哪个文件。 BadImageFormatException表示32/64位不匹配。

在多克部署中,必须将 tessdata 文件复制到容器镜像中。 对于三个语言,每个15 MB,加上每个50-100 MB的best模型,容器图像膨胀了几百兆字节。 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")
$vbLabelText   $csharpLabel

语言数据嵌入在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%。 现在,团队面临着实施之前被推迟的预处理流程,他们发现灰度转换和对比度增强是可以控制的,但是去斜需要霍夫变换,去噪需要中值滤波器,而这两项都不是两个小时就能完成的任务。 到这个里程碑的团队——在预处理债务成为冲刺积压项的地方——经常评估 IronOCR,因为许可证费用比两周的图像处理工作要便宜,这些工作并不是他们被聘来做的。

PDF要求出现

文档处理应用程序几乎最终都需要PDF支持。 第一个回应通常是"添加 PdfiumViewer"——它有完善的文档,可以很好地处理很多情况。 在生产环境中出现问题:本地.so文件,密码保护的PDF需要一个单独的解密库,并自带许可证。 团队在四个环境(Windows、Linux、Docker、CI)中管理三个独立的依赖链——Tesseract 原生库、Leptonica 和 pdfium——会达到维护的临界点,此时评估单包替代方案就变得值得了。

大规模并行处理

批量处理 500 张发票的 OCR 作业可以受益于并行处理。 使用 charlesw 包装器,安全的并行处理模式会为每个线程创建一个引擎实例,每个实例加载 40-100 MB 的语言模型数据。 在八个线程的情况下,加载任何文档之前,引擎内存将占用 320-800 MB。 团队在分析其 OCR 服务时发现,内存压力集中在引擎初始化阶段,而不是文档内容阶段。IronOCR 的线程安全单实例模型直接解决了根本原因。 多线程示例展示了这种模式。

部署环境倍增

一个最初在视窗系统上开发的项目,添加了一个Linux容器用于云部署。 Dockerfile 现在需要原生库安装步骤,必须将 tessdata 文件复制到容器中,并且必须正确设置 tessdata 路径环境变量。 随后,一名MacOS开发人员加入了团队。 然后有人想要部署到 AWS Lambda。 每个平台都会增加一个额外的配置界面,而这些界面可能会静默失败——在生产容器中运行时缺少本地库比NuGet包成本略高要糟糕得多。IronOCR 的Docker 部署指南就对比了这一点:没有系统包,没有 tessdata 复制步骤,也没有环境变量。

Tesseract 版本货币问题

Tesseract 5.x 版本对 LSTM 的准确率进行了改进,在某些文档类型上可以明显感受到改进效果。charlesw 封装器的目标版本是 Tesseract 4.1.1。对于那些将 OCR 在复杂文档上的准确率作为产品质量指标的团队来说,版本差异是一个需要考虑的重要因素——尤其是在可以选择使用与当前引擎版本同步的商业维护软件包的情况下。

常见迁移注意事项

Tessdata 文件夹删除

迁移到IronOCR后的第一个清理步骤是删除tessdata文件夹并从项目文件中移除相应的Directory.Exists(TessDataPath)保护程序——也一并去除。 TesseractEngine, Pix, using IronOcr;, IronTesseract, OcrInput, OcrResult

PDF库移除

任何仅为支持 Tesseract PDF 处理而添加的 PDF 渲染库(例如 PdfiumViewer、PDFtoImage、Docnet.Core)都可以移除。 这些包所需的本地二进制依赖项(pdfium.dll, GhostScript二进制文件)也都消失。 不再需要那些依赖项的Dockerfile COPYapt-get行。 IronOCR PDF 输入指南涵盖了这些库处理的所有 PDF 输入变体,包括页面范围选择和密码保护文档。 整个渲染然后OCR块——通常跨越三个库50-80行——简化为Read()调用。

预处理代码替换

现有预处理方法——ConvertToGrayscale, EnhanceContrast, Binarize, RemoveNoise, Deskew, ScaleToDpi——直接映射到IronOCR过滤器方法。 临时文件保存和加载模式完全消失了。 有关颜色校正,请参考图像颜色校正指南;有关分辨率管理,请参考DPI 设置指南

线程模型变更

IronTesseract,并在所有线程之间共享它。 这是一个正确性变更,而不仅仅是重构:旧的模式是围绕线程不安全的 API 进行防御性编程; 这种新模式是线程安全 API 的预期用法。 由于IronOCR维护了一个共享的内部池,而不是为每个引擎实例加载完整的模型状态,因此每个线程的引擎初始化开销(每个线程 40-100 MB 的语言模型数据)随着这一变化而消失。

其他IronOCR功能

除了预处理和 PDF 支持之外, IronOCR还包含远超核心比对功能的其他功能:

-基于区域的 OCR:从定义的裁剪矩形中提取文本,而无需处理整个图像。 区域 OCR 指南裁剪示例涵盖发票抬头提取和表单字段隔离。

  • 基于置信度的质量路由:result.Confidence提供文档级别的准确性估计,使低置信度结果能够被路由到人工审核队列而无需重复运行OCR。请参阅置信度评分指南。 -异步 OCR:异步 OCR 指南涵盖了ASP.NET Core应用程序的非阻塞 OCR,其​​中阻塞 CPU 密集型操作的请求线程是不可接受的。 -特殊文档类型:护照读取MICR/支票读取车牌读取可作为目标功能提供,无需定制训练模型。 -速度配置:速度优化指南速度调整示例文档配置选项,适用于高吞吐量批量处理,其中每个文档的延迟都很重要。

.NET兼容性和未来准备情况

IronOCR 的目标平台为.NET 6、 .NET 7、 .NET 8 和.NET 9,并将在 2026 年.NET 10 发布时积极提供支持。 该库还支持.NET Standard 2.0,适用于尚未迁移到现代.NET 的项目。 charlesw Tesseract 包装器面向.NET Standard 2.0,并且自 2019 年起就锁定到 Tesseract 引擎版本 4.1.1,目前还没有公布通过该软件包支持 Tesseract 5.x 的路线图。 对于新建项目和计划多年维护窗口的团队来说,引擎版本差距和封装程序维护节奏的放缓是值得与零成本许可一起权衡的因素。

结论

Tesseract 通过 charlesw NuGet封装器是一个真正的 OCR 引擎,而不是玩具。 800万次的下载量反映了其在实际应用中的真实使用情况,并且在干净、格式良好的图像上达到了足以证明其受欢迎程度的准确度。 客观的比较并非关乎 OCR 的质量,而是关乎在生产条件下实现该质量所需的工程工作量。

预处理方面的差距是关键的权衡因素。 大约 180 行图像处理代码就能区分真实世界文档的准确率高低,这可不是什么小麻烦。 这是一项工程任务,需要图像处理知识、额外的依赖项,并且随着新文档类型的出现,还需要持续维护。 PDF 的缺失又增加了一层:第二个库、第二组本地二进制文件、另一个部署表面,以及与 GhostScript 或 iText 的潜在许可纠纷。 这两个差距加起来,就造成了原型系统与生产系统之间 20-40 小时的设置时间估算差异。

IronOCR直接解决了这两个问题:预处理只需一行方法调用,PDF 是一种原生输入格式,整个解决方案可以部署为单个NuGet包。 $999永久许可证的费用是节省两周在图像处理代码和依赖链管理上的时间。 对于开发者时间成本高于许可证价格的团队来说,数学是简单明了的。 对于有开源许可证要求或预算为零的团队来说,Tesseract 仍然是前进的方向——但同时也要清楚地认识到随之而来的工程投入。

该决定与文档类型和操作环境完全吻合:在单一环境部署中,干净、受控的图像更适合 Tesseract 的免费许可。 真实世界的扫描、PDF 工作流程、多环境部署和大规模并行处理,每一项都增加了摩擦,使得IronOCR更具优势。 大多数生产文档处理系统至少会遇到其中两种情况。

请注意Ghostscript、PDFium、PDFSharp、Tesseract 和 iText 是各自所有者的注册商标。 本网站与 Artifex Software、Chromium Project、Google、empira Software GmbH 或 iText Group 无关,也未获得其认可或赞助。所有产品名称、徽标和商标均为其各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。

常见问题解答

什么是 Tesseract OCR?

Tesseract OCR 是一款 OCR 解决方案,开发者和企业使用它从图像和文档中提取文本。它是与 IronOCR 一起评估的几种用于 .NET 应用程序开发的 OCR 方案之一。

对于 .NET 开发人员来说,IronOCR 与 Tesseract OCR 相比如何?

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 安装:在程序包管理器控制台中运行“Install-Package IronOcr”命令,或在命令行界面 (CLI) 中运行“dotnet add package IronOcr”命令。其他语言包的安装方式相同。无需使用原生 SDK 安装程序。

与 Tesseract OCR 不同,IronOCR 是否适用于 Docker 和容器化部署?

是的。IronOCR 通过 NuGet 包在 Docker 容器中运行。许可证密钥通过环境变量设置。OCR 引擎本身不需要任何许可证文件、SDK 路径或卷挂载。

我可以在购买前试用 IronOCR,并将其与 Tesseract OCR 进行比较吗?

是的。IronOCR 试用模式可以处理文档,并在输出结果上添加水印,从而生成 OCR 结果。您可以在购买许可证之前,先在自己的文档上验证其准确性。

IronOCR是否支持条形码读取和文本提取?

IronOCR专注于文本提取和OCR识别。对于条形码读取,Iron Software提供了配套库IronBarcode。两者都可单独购买,也可作为Iron Suite套装的一部分购买。

从 Tesseract OCR 迁移到 IronOCR 容易吗?

从 Tesseract OCR 迁移到 IronOCR 通常涉及将初始化序列替换为 IronTesseract 实例化、移除 COM 生命周期管理以及更新 API 调用。大多数迁移都能显著降低代码复杂度。

Kannaopat Udonpant
软件工程师
在成为软件工程师之前,Kannapat 在日本北海道大学完成了环境资源博士学位。在攻读学位期间,Kannapat 还成为了车辆机器人实验室的成员,隶属于生物生产工程系。2022 年,他利用自己的 C# 技能加入 Iron Software 的工程团队,专注于 IronPDF。Kannapat 珍视他的工作,因为他可以直接从编写大多数 IronPDF 代码的开发者那里学习。除了同行学习外,Kannapat 还喜欢在 Iron Software 工作的社交方面。不撰写代码或文档时,Kannapat 通常可以在他的 PS5 上玩游戏或重温《最后生还者》。

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我