
TesseractOCRからIronOCRへの移行|IronOCR
このガイドでは、.NET開発者がTesseractOCR NuGetパッケージ(Sicos1977/Kees van Speldeのフォーク)からIronOCRへ完全に移行する手順を解説します。 これには、外部の前処理依存関係の削除、ネイティブPDF入力および検索可能なPDF出力の有効化、名前空間とAPI呼び出しの更新、移行後の統合の検証など、完全な置換プロセスが含まれます。 比較記事を事前に読む必要はありません。
TesseractOCRからの移行理由
TesseractOCRは、最新 for .NETを対象とし、Tesseract 5のネイティブライブラリをバンドルした、活発にメンテナンスされているコミュニティ製ラッパーです。 古いラッパーからこれへアップグレードすることで、フレームワークの互換性問題が解決されます。 これは、ラッパー層の下にあるアーキテクチャ上のギャップを解決するものではありません。 本番環境でそうした課題が表面化すると、移行の検討が始まります。
前処理はライブラリの外部で完全に行われます。TesseractOCRは、提供されたピクセルに対して engine.Process(image) を呼び出します。 斜めにスキャンされた画像、コントラストの低いファックス、レシートをスマホで撮影した写真――これらすべてが、Tesseractエンジンにそのまま入力されます。 使用可能な出力を回復するには、SixLabors.ImageSharp、SkiaSharp、または類似のイメージライブラリを追加し、ドキュメントタイプごとに調整されたパラメータで手動フィルターチェーンを作成し、TesseractOCR.Pix.Image がファイルパスを期待するため、前処理された画像を一時ファイルでルーティングする必要があります。 標準的な .NET Standard 画像処理ライブラリには、スキュー補正機能は一切含まれていません。これを実現するには、ハフ変換による角度検出アルゴリズムをゼロから実装する必要があり、通常、50~100行の追加コードが必要となります。 これは1回限りの初期費用ではなく、新しいドキュメントタイプがパイプラインに追加されるたびに発生する費用です。
PDFの入力には、別のライブラリと一時ファイルのパイプラインが必要です。TesseractOCRはPDFではなく画像を処理します。 どのPDFワークフローでも、PDFページをBGRAバイト配列としてレンダリングするための追加パッケージ(Docnet.Core、PdfiumViewerなど)、それらのバイトをTesseractOCRが読み取れる形式に変換するヘルパーメソッド、そしてループ全体を囲む一時ファイルの作成およびクリーンアップロジックが必要となります。その結果、PDF OCR操作のたびに約100行のインフラストラクチャコードが生成されることになります。 パスワード保護されたPDFには、処理前に単に復号するためだけにサードライブラリ(AGPLライセンスのiText、またはPDFSharp)が必要です。
検索可能なPDF出力にはパスがありません。スキャンした文書から機械可読なPDFを作成する必要があるチーム(文書管理、アーカイブ、コンプライアンスワークフローでは一般的な要件です)は、TesseractOCRにはそのための仕組みがないことに気づきます。 SaveAsSearchablePdf() はなく、hOCR-to-PDF パイプラインもなく、抽出されたテキスト以外の出力形式もありません。 この機能を追加するには、別のPDFライブラリを導入するか、TesseractOCRを完全に廃止する必要があります。
TIFFのマルチフレーム文書には、手動でのページループが必要です。FAXワークフローやドキュメントスキャナーで一般的な複数ページのTIFFファイルについては、TesseractOCRにはネイティブなマルチフレーム処理機能がありません。 すべてのフレームを抽出するには、外部ライブラリを使用してTIFFを読み込み、フレームを順次処理し、それぞれを一時ファイルに保存し、各一時ファイルを個別にOCRエンジンに通す必要があります。
コミュニティの規模により、実用的なサポートには限界があります。TesseractOCRのNuGetダウンロード数は約20万件です。 .NET Tesseract ラッパーに関する Stack Overflow、ブログ投稿、GitHub の問題スレッドは、圧倒的に charlesw API - TesseractEngine, Pix.LoadFromFile - を参照しています。 Sicos1977 API ではありません。 TesseractOCR特有の問題に対する実用的なトラブルシューティングは、すぐにこの壁にぶつかります。
基本的な問題
TesseractOCRには前処理機能がなく、PDFにも対応していません。 本番環境のドキュメント処理ワークフローでは、OCRを実行できる段階に至るだけでも、結局は外部ライブラリが必要となります:
// TesseractOCR: three packages, a temp file, and manual byte conversion
// just to OCR one PDF page — before any preprocessing
// dotnet add package TesseractOCR
// dotnet add package Docnet.Core
// dotnet add package SixLabors.ImageSharp (preprocessing)
using var library = DocLib.Instance;
using var docReader = library.GetDocReader(pdfPath, new PageDimensions(200, 200));
using var pageReader = docReader.GetPageReader(0);
var bytes = pageReader.GetImage(); // BGRA — not a format Pix.Image accepts directly
string tempPath = Path.GetTempFileName() + ".png";
SaveBgraAsPng(bytes, pageReader.GetPageWidth(), pageReader.GetPageHeight(), tempPath);
// ^ 30+ line helper method needed here
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var image = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(image);
string text = page.Text;
File.Delete(tempPath); // hope this succeeds' TesseractOCR: three packages, a temp file, and manual byte conversion
' just to OCR one PDF page — before any preprocessing
' dotnet add package TesseractOCR
' dotnet add package Docnet.Core
' dotnet add package SixLabors.ImageSharp (preprocessing)
Using library = DocLib.Instance
Using docReader = library.GetDocReader(pdfPath, New PageDimensions(200, 200))
Using pageReader = docReader.GetPageReader(0)
Dim bytes = pageReader.GetImage() ' BGRA — not a format Pix.Image accepts directly
Dim tempPath As String = Path.GetTempFileName() & ".png"
SaveBgraAsPng(bytes, pageReader.GetPageWidth(), pageReader.GetPageHeight(), tempPath)
' ^ 30+ line helper method needed here
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using image = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(image)
Dim text As String = page.Text
File.Delete(tempPath) ' hope this succeeds
End Using
End Using
End Using
End Using
End Using
End Using' TesseractOCR: three packages, a temp file, and manual byte conversion
' just to OCR one PDF page — before any preprocessing
' dotnet add package TesseractOCR
' dotnet add package Docnet.Core
' dotnet add package SixLabors.ImageSharp (preprocessing)
Using library = DocLib.Instance
Using docReader = library.GetDocReader(pdfPath, New PageDimensions(200, 200))
Using pageReader = docReader.GetPageReader(0)
Dim bytes = pageReader.GetImage() ' BGRA — not a format Pix.Image accepts directly
Dim tempPath As String = Path.GetTempFileName() & ".png"
SaveBgraAsPng(bytes, pageReader.GetPageWidth(), pageReader.GetPageHeight(), tempPath)
' ^ 30+ line helper method needed here
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using image = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(image)
Dim text As String = page.Text
File.Delete(tempPath) ' hope this succeeds
End Using
End Using
End Using
End Using
End Using
End Using// IronOCR: one package, three lines, preprocessing automatic
// dotnet add package IronOcr
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(pdfPath);
string text = ocr.Read(input).Text;// IronOCR: one package, three lines, preprocessing automatic
// dotnet add package IronOcr
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(pdfPath);
string text = ocr.Read(input).Text;' IronOCR: one package, three lines, preprocessing automatic
' dotnet add package IronOcr
Dim ocr As New IronTesseract()
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Dim text As String = ocr.Read(input).Text
End Using' IronOCR: one package, three lines, preprocessing automatic
' dotnet add package IronOcr
Dim ocr As New IronTesseract()
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Dim text As String = ocr.Read(input).Text
End UsingIronOCR 対 TesseractOCR:機能比較
以下の表は、移行の評価において最も重要な機能をまとめたものです。
| フィーチャー | TesseractOCR | IronOCR |
|---|---|---|
| NuGetパッケージ | TesseractOCR | IronOcr |
| .NET互換性 | .NET 6.0、7.0、8.0 | .NET Framework 4.6.2 以降、.NET Core、.NET 5/6/7/8/9 |
| ライセンス | アパッチ2.0(無料) | 商用(永続、$999から) |
| Tessdata管理 | 必須(GitHubからの手動ダウンロード) | 不要(内部で同梱済み) |
| 組み込みの前処理 | None | 傾き補正、ノイズ除去、コントラスト補正、二値化、シャープ化、拡大縮小、膨張、収縮、反転 |
| 深い背景ノイズの除去 | なし | はい (DeepCleanBackgroundNoise()) |
| ネイティブPDF入力 | いいえ(Docnet.Core または類似のライブラリが必要です) | はい (input.LoadPdf()) |
| パスワードで保護されたPDF | いいえ(復号化にはサードパーティ製ライブラリが必要です) | はい(単一の Password パラメータ) |
| 検索可能なPDF出力 | なし | はい (result.SaveAsSearchablePdf()) |
| マルチフレームTIFF入力 | いいえ(外部フレームの抽出が必要) | はい (input.LoadImageFrames()) |
| ストリームとバイト配列の入力 | いいえ(一時ファイルによる仲介が必要) | はい(直接 LoadImage(bytes)) |
| スレッドセーフティ | いいえ(スレッドごとに1つのエンジンインスタンス) | はい(スレッド間で共有される単一の IronTesseract) |
| 地域ベースのOCR | なし | はい (CropRectangle) |
| OCR中のバーコード読み取り | なし | はい (ocr.Configuration.ReadBarCodes = true) |
| 構造化された出力(ページ数、WORD数、座標) | なし(プレーンテキストのみ) | はい (Words、X/Y付き) |
| 信頼度スコア | ドキュメントレベルの浮動小数点数 (0.0–1.0) | 文書およびWORDレベルの二重チェック (0–100) |
| hOCRエクスポート | なし | はい |
| 125以上の言語に対応したNuGetパッケージ | なし | はい |
| クロスプラットフォーム展開 | Windows、Linux、macOS | Windows、Linux、macOS、Docker、Azure、AWS |
| 商用サポート | いいえ(単一のボランティアメンテナー) | はい(メール、SLAオプション) |
クイックスタート:TesseractOCR から IronOCR への移行
ステップ 1: NuGet パッケージを置き換える
TesseractOCRおよびそれをサポートするために追加されたライブラリを削除してください:
dotnet remove package TesseractOCR
dotnet remove package Docnet.Core
dotnet remove package SixLabors.ImageSharp
NuGetからIronOCRをインストールしてください。
ステップ 2: 名前空間の更新
すべてのTesseractOCR名前空間インポートをIronOCRに置き換えます:
// Before (TesseractOCR)
using TesseractOCR;
using TesseractOCR.Enums;
// After (IronOCR)
using IronOcr;// Before (TesseractOCR)
using TesseractOCR;
using TesseractOCR.Enums;
// After (IronOCR)
using IronOcr;' Before (TesseractOCR)
Imports TesseractOCR
Imports TesseractOCR.Enums
' After (IronOCR)
Imports IronOcr' Before (TesseractOCR)
Imports TesseractOCR
Imports TesseractOCR.Enums
' After (IronOCR)
Imports IronOcrステップ 3: ライセンスの初期化
アプリケーションの起動時、OCR呼び出しの前に、ライセンスの初期化を一度実行してください:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"IronOCRのライセンスページから、評価用の無料トライアルライセンスを入手できます。
コード移行の例
外部前処理パイプラインの置き換え
TesseractOCRは、ドキュメントの品質を向上させるために、外部の画像処理ライブラリを必要とします。 以下のコードは、ドキュメントの品質が一定でない場合にチームが記述するパターンを示しています。具体的には、グレースケール変換、コントラスト調整、ノイズ除去、そしてOCRを実行する前に一時ファイルへの書き込みが行われます。 スキュー補正(スキャン画像の傾き補正)は、標準的な .NET Standard 画像処理ライブラリでは利用できず、別途アルゴリズムが必要です。
TesseractOCRのアプローチ:
// Requires: dotnet add package SixLabors.ImageSharp
// Manual preprocessing — parameters must be tuned per document type
// Deskew is NOT in ImageSharp — requires custom Hough transform (~50-100 lines)
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromLowQualityScan(string imagePath)
{
using var image = Image.Load(imagePath);
image.Mutate(x => x.Grayscale());
image.Mutate(x => x.Contrast(1.5f)); // manual tuning required
image.Mutate(x => x.GaussianBlur(0.5f)); // noise reduction approximation
image.Mutate(x => x.BinaryThreshold(0.5f)); // threshold requires per-doc adjustment
// Deskew omitted — no built-in support, ~80 lines of additional code
string tempPath = Path.GetTempFileName() + ".png";
try
{
image.Save(tempPath);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
return page.Text;
}
finally
{
File.Delete(tempPath);
}
}// Requires: dotnet add package SixLabors.ImageSharp
// Manual preprocessing — parameters must be tuned per document type
// Deskew is NOT in ImageSharp — requires custom Hough transform (~50-100 lines)
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromLowQualityScan(string imagePath)
{
using var image = Image.Load(imagePath);
image.Mutate(x => x.Grayscale());
image.Mutate(x => x.Contrast(1.5f)); // manual tuning required
image.Mutate(x => x.GaussianBlur(0.5f)); // noise reduction approximation
image.Mutate(x => x.BinaryThreshold(0.5f)); // threshold requires per-doc adjustment
// Deskew omitted — no built-in support, ~80 lines of additional code
string tempPath = Path.GetTempFileName() + ".png";
try
{
image.Save(tempPath);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
return page.Text;
}
finally
{
File.Delete(tempPath);
}
}Imports SixLabors.ImageSharp
Imports SixLabors.ImageSharp.Processing
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Function ExtractFromLowQualityScan(imagePath As String) As String
Using image = Image.Load(imagePath)
image.Mutate(Sub(x) x.Grayscale())
image.Mutate(Sub(x) x.Contrast(1.5F)) ' manual tuning required
image.Mutate(Sub(x) x.GaussianBlur(0.5F)) ' noise reduction approximation
image.Mutate(Sub(x) x.BinaryThreshold(0.5F)) ' threshold requires per-doc adjustment
' Deskew omitted — no built-in support, ~80 lines of additional code
Dim tempPath As String = Path.GetTempFileName() & ".png"
Try
image.Save(tempPath)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(pix)
Return page.Text
End Using
End Using
End Using
Finally
File.Delete(tempPath)
End Try
End Using
End FunctionImports SixLabors.ImageSharp
Imports SixLabors.ImageSharp.Processing
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Function ExtractFromLowQualityScan(imagePath As String) As String
Using image = Image.Load(imagePath)
image.Mutate(Sub(x) x.Grayscale())
image.Mutate(Sub(x) x.Contrast(1.5F)) ' manual tuning required
image.Mutate(Sub(x) x.GaussianBlur(0.5F)) ' noise reduction approximation
image.Mutate(Sub(x) x.BinaryThreshold(0.5F)) ' threshold requires per-doc adjustment
' Deskew omitted — no built-in support, ~80 lines of additional code
Dim tempPath As String = Path.GetTempFileName() & ".png"
Try
image.Save(tempPath)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(pix)
Return page.Text
End Using
End Using
End Using
Finally
File.Delete(tempPath)
End Try
End Using
End FunctionIronOCRのアプローチ:
// なし external imaging library
// なし temp file — OcrInput accepts a path, stream, or byte array directly
// Deskew is built in — automatic angle detection and correction
using IronOcr;
public string ExtractFromLowQualityScan(string imagePath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
input.Deskew(); // automatic angle correction
input.DeNoise(); // intelligent noise removal
input.Contrast(); // automatic contrast enhancement
input.Binarize(); // clean black-and-white conversion
var ocr = new IronTesseract();
return ocr.Read(input).Text;
}// なし external imaging library
// なし temp file — OcrInput accepts a path, stream, or byte array directly
// Deskew is built in — automatic angle detection and correction
using IronOcr;
public string ExtractFromLowQualityScan(string imagePath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
input.Deskew(); // automatic angle correction
input.DeNoise(); // intelligent noise removal
input.Contrast(); // automatic contrast enhancement
input.Binarize(); // clean black-and-white conversion
var ocr = new IronTesseract();
return ocr.Read(input).Text;
}Imports IronOcr
Public Function ExtractFromLowQualityScan(ByVal imagePath As String) As String
Using input As New OcrInput()
input.LoadImage(imagePath)
input.Deskew() ' automatic angle correction
input.DeNoise() ' intelligent noise removal
input.Contrast() ' automatic contrast enhancement
input.Binarize() ' clean black-and-white conversion
Dim ocr As New IronTesseract()
Return ocr.Read(input).Text
End Using
End FunctionImports IronOcr
Public Function ExtractFromLowQualityScan(ByVal imagePath As String) As String
Using input As New OcrInput()
input.LoadImage(imagePath)
input.Deskew() ' automatic angle correction
input.DeNoise() ' intelligent noise removal
input.Contrast() ' automatic contrast enhancement
input.Binarize() ' clean black-and-white conversion
Dim ocr As New IronTesseract()
Return ocr.Read(input).Text
End Using
End FunctionImageSharpへの依存関係を排除することで、チューニングのサイクルを完全に排除できます。 OcrInput の前処理パイプラインは、文書 OCR 用に調整されたアルゴリズムを適用します - コントラストの乗数やぼかし半径の推測はありません。 画像フィルターのチュートリアルと画質補正ガイドでは、デフォルト設定の調整が必要な場合に備え、利用可能なすべてのフィルターとパラメーターオプションを網羅しています。
マルチフレーム TIFF 処理の置き換え
FAX文書、ドキュメントスキャナーの出力、およびアーカイブファイルは、多くの場合、複数ページのTIFFファイルとして届きます。 TesseractOCRにはマルチフレーム対応機能がありません。各フレームは外部ライブラリを使用して抽出し、ディスクに保存した後、1つずつエンジンに読み込む必要があります。一方、IronOCRは1回の呼び出しでTIFFファイル全体を読み込みます。
TesseractOCRのアプローチ:
// Requires: dotnet add package SixLabors.ImageSharp
// Manual frame extraction — every frame becomes a temp file on disk
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Tiff;
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromMultiPageTiff(string tiffPath)
{
var allText = new System.Text.StringBuilder();
var tempFiles = new List<string>();
try
{
using var image = Image.Load(tiffPath);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
for (int frameIndex = 0; frameIndex < image.Frames.Count; frameIndex++)
{
// Clone frame and save to temp file — no in-memory path
using var frameImage = image.Frames.CloneFrame(frameIndex);
string tempPath = Path.GetTempFileName() + ".png";
tempFiles.Add(tempPath);
frameImage.SaveAsPng(tempPath);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
allText.AppendLine($"=== Frame {frameIndex + 1} ===");
allText.AppendLine(page.Text);
}
}
finally
{
foreach (var f in tempFiles)
try { File.Delete(f); } catch { }
}
return allText.ToString();
}// Requires: dotnet add package SixLabors.ImageSharp
// Manual frame extraction — every frame becomes a temp file on disk
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Tiff;
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromMultiPageTiff(string tiffPath)
{
var allText = new System.Text.StringBuilder();
var tempFiles = new List<string>();
try
{
using var image = Image.Load(tiffPath);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
for (int frameIndex = 0; frameIndex < image.Frames.Count; frameIndex++)
{
// Clone frame and save to temp file — no in-memory path
using var frameImage = image.Frames.CloneFrame(frameIndex);
string tempPath = Path.GetTempFileName() + ".png";
tempFiles.Add(tempPath);
frameImage.SaveAsPng(tempPath);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
allText.AppendLine($"=== Frame {frameIndex + 1} ===");
allText.AppendLine(page.Text);
}
}
finally
{
foreach (var f in tempFiles)
try { File.Delete(f); } catch { }
}
return allText.ToString();
}Imports SixLabors.ImageSharp
Imports SixLabors.ImageSharp.Formats.Tiff
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Function ExtractFromMultiPageTiff(tiffPath As String) As String
Dim allText = New System.Text.StringBuilder()
Dim tempFiles = New List(Of String)()
Try
Using image = Image.Load(tiffPath)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
For frameIndex As Integer = 0 To image.Frames.Count - 1
' Clone frame and save to temp file — no in-memory path
Using frameImage = image.Frames.CloneFrame(frameIndex)
Dim tempPath As String = Path.GetTempFileName() & ".png"
tempFiles.Add(tempPath)
frameImage.SaveAsPng(tempPath)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(pix)
allText.AppendLine($"=== Frame {frameIndex + 1} ===")
allText.AppendLine(page.Text)
End Using
End Using
End Using
Next
End Using
End Using
Finally
For Each f In tempFiles
Try
File.Delete(f)
Catch
End Try
Next
End Try
Return allText.ToString()
End FunctionImports SixLabors.ImageSharp
Imports SixLabors.ImageSharp.Formats.Tiff
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Function ExtractFromMultiPageTiff(tiffPath As String) As String
Dim allText = New System.Text.StringBuilder()
Dim tempFiles = New List(Of String)()
Try
Using image = Image.Load(tiffPath)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
For frameIndex As Integer = 0 To image.Frames.Count - 1
' Clone frame and save to temp file — no in-memory path
Using frameImage = image.Frames.CloneFrame(frameIndex)
Dim tempPath As String = Path.GetTempFileName() & ".png"
tempFiles.Add(tempPath)
frameImage.SaveAsPng(tempPath)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(pix)
allText.AppendLine($"=== Frame {frameIndex + 1} ===")
allText.AppendLine(page.Text)
End Using
End Using
End Using
Next
End Using
End Using
Finally
For Each f In tempFiles
Try
File.Delete(f)
Catch
End Try
Next
End Try
Return allText.ToString()
End FunctionIronOCRのアプローチ:
// なし external library for frame extraction
// All frames processed in one Read() call — no manual loop required
using IronOcr;
public string ExtractFromMultiPageTiff(string tiffPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // loads all frames automatically
var result = ocr.Read(input);
// Access per-page text if needed
foreach (var page in result.Pages)
Console.WriteLine($"Frame {page.PageNumber}: {page.Text}");
return result.Text;
}// なし external library for frame extraction
// All frames processed in one Read() call — no manual loop required
using IronOcr;
public string ExtractFromMultiPageTiff(string tiffPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // loads all frames automatically
var result = ocr.Read(input);
// Access per-page text if needed
foreach (var page in result.Pages)
Console.WriteLine($"Frame {page.PageNumber}: {page.Text}");
return result.Text;
}Imports IronOcr
Public Function ExtractFromMultiPageTiff(tiffPath As String) As String
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImageFrames(tiffPath) ' loads all frames automatically
Dim result = ocr.Read(input)
' Access per-page text if needed
For Each page In result.Pages
Console.WriteLine($"Frame {page.PageNumber}: {page.Text}")
Next
Return result.Text
End Using
End FunctionImports IronOcr
Public Function ExtractFromMultiPageTiff(tiffPath As String) As String
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImageFrames(tiffPath) ' loads all frames automatically
Dim result = ocr.Read(input)
' Access per-page text if needed
For Each page In result.Pages
Console.WriteLine($"Frame {page.PageNumber}: {page.Text}")
Next
Return result.Text
End Using
End Functionフレーム抽出ループ、一時ファイルリスト、finally のクリーンアップブロック - それらはすべてなくなります。 20ページのFAX TIFFの場合、これにより約40行が6行に置き換えられます。TIFFおよびGIFの入力ガイドでは、特定のフレーム範囲を含むマルチフレーム読み込みオプションについて解説しています。
検索可能なPDF出力の生成
このシナリオには、TesseractOCR における移行パスは存在しません。つまり、実現不可能です。 スキャンされたPDFを、機械可読かつテキスト選択可能なドキュメント(検索インデックス作成、アクセシビリティ、またはアーカイブ用)に変換するには、検索可能なPDFを出力する必要があります。 TesseractOCRは、抽出されたテキストのみを生成します。 IronOCRは、検索可能なPDFを直接生成します。
TesseractOCRのアプローチ:
// なし path available —TesseractOCRcannot produce any PDF output.
// The closest workaround requires a separate PDF library (iTextSharp AGPL,
// or similar) to overlay extracted text onto the original PDF manually.
// This is 150-300 lines of additional code and introduces AGPL license concerns.
// The best available output from TesseractOCR:
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile("scanned-page.png");
using var page = engine.Process(pix);
string extractedText = page.Text; // flat string — no PDF output possible
File.WriteAllText("output.txt", extractedText);
// Cannot produce a searchable PDF — no API exists for this// なし path available —TesseractOCRcannot produce any PDF output.
// The closest workaround requires a separate PDF library (iTextSharp AGPL,
// or similar) to overlay extracted text onto the original PDF manually.
// This is 150-300 lines of additional code and introduces AGPL license concerns.
// The best available output from TesseractOCR:
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile("scanned-page.png");
using var page = engine.Process(pix);
string extractedText = page.Text; // flat string — no PDF output possible
File.WriteAllText("output.txt", extractedText);
// Cannot produce a searchable PDF — no API exists for this' なし path available —TesseractOCRcannot produce any PDF output.
' The closest workaround requires a separate PDF library (iTextSharp AGPL,
' or similar) to overlay extracted text onto the original PDF manually.
' This is 150-300 lines of additional code and introduces AGPL license concerns.
' The best available output from TesseractOCR:
Using engine As New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix As TesseractOCR.Pix.Image = TesseractOCR.Pix.Image.LoadFromFile("scanned-page.png")
Using page As engine.Process(pix)
Dim extractedText As String = page.Text ' flat string — no PDF output possible
File.WriteAllText("output.txt", extractedText)
End Using
End Using
End Using
' Cannot produce a searchable PDF — no API exists for this' なし path available —TesseractOCRcannot produce any PDF output.
' The closest workaround requires a separate PDF library (iTextSharp AGPL,
' or similar) to overlay extracted text onto the original PDF manually.
' This is 150-300 lines of additional code and introduces AGPL license concerns.
' The best available output from TesseractOCR:
Using engine As New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix As TesseractOCR.Pix.Image = TesseractOCR.Pix.Image.LoadFromFile("scanned-page.png")
Using page As engine.Process(pix)
Dim extractedText As String = page.Text ' flat string — no PDF output possible
File.WriteAllText("output.txt", extractedText)
End Using
End Using
End Using
' Cannot produce a searchable PDF — no API exists for thisIronOCRのアプローチ:
// Native searchable PDF output — no additional library required
// Input can be a scanned image, a scanned PDF, or a multi-page TIFF
using IronOcr;
public void CreateSearchablePdf(string scannedPdfPath, string outputPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(scannedPdfPath);
input.Deskew(); // improve accuracy before generating the output
input.DeNoise();
var result = ocr.Read(input);
result.SaveAsSearchablePdf(outputPath); // searchable, text-selectable PDF
}// Native searchable PDF output — no additional library required
// Input can be a scanned image, a scanned PDF, or a multi-page TIFF
using IronOcr;
public void CreateSearchablePdf(string scannedPdfPath, string outputPath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(scannedPdfPath);
input.Deskew(); // improve accuracy before generating the output
input.DeNoise();
var result = ocr.Read(input);
result.SaveAsSearchablePdf(outputPath); // searchable, text-selectable PDF
}' Native searchable PDF output — no additional library required
' Input can be a scanned image, a scanned PDF, or a multi-page TIFF
Imports IronOcr
Public Sub CreateSearchablePdf(scannedPdfPath As String, outputPath As String)
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadPdf(scannedPdfPath)
input.Deskew() ' improve accuracy before generating the output
input.DeNoise()
Dim result = ocr.Read(input)
result.SaveAsSearchablePdf(outputPath) ' searchable, text-selectable PDF
End Using
End Sub' Native searchable PDF output — no additional library required
' Input can be a scanned image, a scanned PDF, or a multi-page TIFF
Imports IronOcr
Public Sub CreateSearchablePdf(scannedPdfPath As String, outputPath As String)
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadPdf(scannedPdfPath)
input.Deskew() ' improve accuracy before generating the output
input.DeNoise()
Dim result = ocr.Read(input)
result.SaveAsSearchablePdf(outputPath) ' searchable, text-selectable PDF
End Using
End SubSaveAsSearchablePdf() の呼び出しは、OCRテキストを元のスキャン画像の背後にある不可視のレイヤーとしてPDFに埋め込みます。 ドキュメントの外観はそのままに、全文検索、選択、インデックス作成が可能になります。 検索可能なPDFガイドにはAPIの全容が記載されており、検索可能なPDFサンプルでは完全な動作パターンを示しています。
バイト配列入力の置き換えと一時ファイルの排除
TesseractOCR の Pix.Image API はファイルパスを受け入れます。 画像データがデータベース、HTTPマルチパートアップロード、メモリキャッシュなどからバイト配列として到着した場合、TesseractOCRは処理の前に一時ファイルへの書き込みを強制します。 IronOCR の OcrInput は、直接バイト配列とストリームを受け入れ、一時ファイルのステップを完全に排除します。
TesseractOCRのアプローチ:
// TesseractOCR.Pix.Image has no byte[] or Stream overload
// Every in-memory image must be written to disk before processing
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromBytes(byte[] imageBytes)
{
// Force a disk write just to satisfy the file-path API
string tempPath = Path.GetTempFileName() + ".png";
try
{
File.WriteAllBytes(tempPath, imageBytes);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
return page.Text;
}
finally
{
// Risk: if an exception fires between WriteAllBytes and Delete,
// temp files accumulate on the server disk
if (File.Exists(tempPath))
File.Delete(tempPath);
}
}// TesseractOCR.Pix.Image has no byte[] or Stream overload
// Every in-memory image must be written to disk before processing
using TesseractOCR;
using TesseractOCR.Enums;
public string ExtractFromBytes(byte[] imageBytes)
{
// Force a disk write just to satisfy the file-path API
string tempPath = Path.GetTempFileName() + ".png";
try
{
File.WriteAllBytes(tempPath, imageBytes);
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath);
using var page = engine.Process(pix);
return page.Text;
}
finally
{
// Risk: if an exception fires between WriteAllBytes and Delete,
// temp files accumulate on the server disk
if (File.Exists(tempPath))
File.Delete(tempPath);
}
}' TesseractOCR.Pix.Image has no byte[] or Stream overload
' Every in-memory image must be written to disk before processing
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Function ExtractFromBytes(imageBytes As Byte()) As String
' Force a disk write just to satisfy the file-path API
Dim tempPath As String = Path.GetTempFileName() & ".png"
Try
File.WriteAllBytes(tempPath, imageBytes)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(pix)
Return page.Text
End Using
End Using
End Using
Finally
' Risk: if an exception fires between WriteAllBytes and Delete,
' temp files accumulate on the server disk
If File.Exists(tempPath) Then
File.Delete(tempPath)
End If
End Try
End Function' TesseractOCR.Pix.Image has no byte[] or Stream overload
' Every in-memory image must be written to disk before processing
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Function ExtractFromBytes(imageBytes As Byte()) As String
' Force a disk write just to satisfy the file-path API
Dim tempPath As String = Path.GetTempFileName() & ".png"
Try
File.WriteAllBytes(tempPath, imageBytes)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(tempPath)
Using page = engine.Process(pix)
Return page.Text
End Using
End Using
End Using
Finally
' Risk: if an exception fires between WriteAllBytes and Delete,
' temp files accumulate on the server disk
If File.Exists(tempPath) Then
File.Delete(tempPath)
End If
End Try
End FunctionIronOCRのアプローチ:
// OcrInput accepts byte arrays and streams natively
// なし disk write, no temp file cleanup, no cleanup failure risk
using IronOcr;
public string ExtractFromBytes(byte[] imageBytes)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imageBytes); // direct byte array — no temp file
return ocr.Read(input).Text;
}
public string ExtractFromStream(Stream imageStream)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imageStream); // direct stream — no intermediate buffer
return ocr.Read(input).Text;
}// OcrInput accepts byte arrays and streams natively
// なし disk write, no temp file cleanup, no cleanup failure risk
using IronOcr;
public string ExtractFromBytes(byte[] imageBytes)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imageBytes); // direct byte array — no temp file
return ocr.Read(input).Text;
}
public string ExtractFromStream(Stream imageStream)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imageStream); // direct stream — no intermediate buffer
return ocr.Read(input).Text;
}Imports IronOcr
Public Function ExtractFromBytes(imageBytes As Byte()) As String
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImage(imageBytes) ' direct byte array — no temp file
Return ocr.Read(input).Text
End Using
End Function
Public Function ExtractFromStream(imageStream As Stream) As String
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImage(imageStream) ' direct stream — no intermediate buffer
Return ocr.Read(input).Text
End Using
End FunctionImports IronOcr
Public Function ExtractFromBytes(imageBytes As Byte()) As String
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImage(imageBytes) ' direct byte array — no temp file
Return ocr.Read(input).Text
End Using
End Function
Public Function ExtractFromStream(imageStream As Stream) As String
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImage(imageStream) ' direct stream — no intermediate buffer
Return ocr.Read(input).Text
End Using
End Functionアップロードされたドキュメントを処理するWebアプリケーションにおいて、temp-fileパターンは負荷がかかるとディスク使用量を増加させ、クリーンアップコードが例外をスローした場合にレースコンディションを引き起こします。 ストリーム入力ガイド と 画像入力ガイド では、Bitmap 、ファイルパスを含むすべてのサポートされる入力形式をカバーしています。
構造化データを用いたWORDレベルの信頼度フィルタリング
TesseractOCR は1つのドキュメントレベルの信頼スコア(page.MeanConfidence、0.0から1.0の浮動小数点数)とフラットなテキスト文字列を返します。 単語ごとの信頼度、単語の位置情報、構造的な階層関係はありません。 不明確な単語にフラグを立てたり、特定の領域を抽出したり、テキストをドキュメントの座標にマッピングしたりするワークフローを構築するには、根本的に異なる出力モデルへの切り替えが必要です。
TesseractOCRのアプローチ:
// Only document-level confidence available
// なし word coordinates, no structural hierarchy
using TesseractOCR;
using TesseractOCR.Enums;
public void ProcessWithConfidence(string imagePath)
{
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(imagePath);
using var page = engine.Process(pix);
float docConfidence = page.MeanConfidence; // 0.0 to 1.0 for the whole document
if (docConfidence >= 0.7f)
Console.WriteLine($"Accepted ({docConfidence:P0}): {page.Text}");
else
Console.WriteLine($"Rejected ({docConfidence:P0}): document needs preprocessing");
// なし way to identify WHICH words are uncertain
// なし word coordinates available
}// Only document-level confidence available
// なし word coordinates, no structural hierarchy
using TesseractOCR;
using TesseractOCR.Enums;
public void ProcessWithConfidence(string imagePath)
{
using var engine = new Engine(@"./tessdata", Language.English, EngineMode.Default);
using var pix = TesseractOCR.Pix.Image.LoadFromFile(imagePath);
using var page = engine.Process(pix);
float docConfidence = page.MeanConfidence; // 0.0 to 1.0 for the whole document
if (docConfidence >= 0.7f)
Console.WriteLine($"Accepted ({docConfidence:P0}): {page.Text}");
else
Console.WriteLine($"Rejected ({docConfidence:P0}): document needs preprocessing");
// なし way to identify WHICH words are uncertain
// なし word coordinates available
}' Only document-level confidence available
' なし word coordinates, no structural hierarchy
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Sub ProcessWithConfidence(ByVal imagePath As String)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(imagePath)
Using page = engine.Process(pix)
Dim docConfidence As Single = page.MeanConfidence ' 0.0 to 1.0 for the whole document
If docConfidence >= 0.7F Then
Console.WriteLine($"Accepted ({docConfidence:P0}): {page.Text}")
Else
Console.WriteLine($"Rejected ({docConfidence:P0}): document needs preprocessing")
End If
End Using
End Using
End Using
' なし way to identify WHICH words are uncertain
' なし word coordinates available
End Sub' Only document-level confidence available
' なし word coordinates, no structural hierarchy
Imports TesseractOCR
Imports TesseractOCR.Enums
Public Sub ProcessWithConfidence(ByVal imagePath As String)
Using engine = New Engine("./tessdata", Language.English, EngineMode.Default)
Using pix = TesseractOCR.Pix.Image.LoadFromFile(imagePath)
Using page = engine.Process(pix)
Dim docConfidence As Single = page.MeanConfidence ' 0.0 to 1.0 for the whole document
If docConfidence >= 0.7F Then
Console.WriteLine($"Accepted ({docConfidence:P0}): {page.Text}")
Else
Console.WriteLine($"Rejected ({docConfidence:P0}): document needs preprocessing")
End If
End Using
End Using
End Using
' なし way to identify WHICH words are uncertain
' なし word coordinates available
End SubIronOCRのアプローチ:
// Per-word confidence and coordinate data
// Filter individual uncertain words without discarding the whole document
using IronOcr;
public void ProcessWithWordLevelConfidence(string imagePath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = ocr.Read(input);
Console.WriteLine($"Document confidence: {result.Confidence}%");
// Iterate words and flag those below threshold
foreach (var page in result.Pages)
{
foreach (var word in page.Words)
{
if (word.Confidence < 70)
{
// Low-confidence word — log position for review
Console.WriteLine(
$"Low confidence word '{word.Text}' ({word.Confidence}%) " +
$"at X:{word.X} Y:{word.Y}");
}
}
}
// Extract only high-confidence text
var reliableWords = result.Pages
.SelectMany(p => p.Words)
.Where(w => w.Confidence >= 70)
.Select(w => w.Text);
Console.WriteLine(string.Join(" ", reliableWords));
}// Per-word confidence and coordinate data
// Filter individual uncertain words without discarding the whole document
using IronOcr;
public void ProcessWithWordLevelConfidence(string imagePath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imagePath);
var result = ocr.Read(input);
Console.WriteLine($"Document confidence: {result.Confidence}%");
// Iterate words and flag those below threshold
foreach (var page in result.Pages)
{
foreach (var word in page.Words)
{
if (word.Confidence < 70)
{
// Low-confidence word — log position for review
Console.WriteLine(
$"Low confidence word '{word.Text}' ({word.Confidence}%) " +
$"at X:{word.X} Y:{word.Y}");
}
}
}
// Extract only high-confidence text
var reliableWords = result.Pages
.SelectMany(p => p.Words)
.Where(w => w.Confidence >= 70)
.Select(w => w.Text);
Console.WriteLine(string.Join(" ", reliableWords));
}' Per-word confidence and coordinate data
' Filter individual uncertain words without discarding the whole document
Imports IronOcr
Public Sub ProcessWithWordLevelConfidence(imagePath As String)
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImage(imagePath)
Dim result = ocr.Read(input)
Console.WriteLine($"Document confidence: {result.Confidence}%")
' Iterate words and flag those below threshold
For Each page In result.Pages
For Each word In page.Words
If word.Confidence < 70 Then
' Low-confidence word — log position for review
Console.WriteLine(
$"Low confidence word '{word.Text}' ({word.Confidence}%) " +
$"at X:{word.X} Y:{word.Y}")
End If
Next
Next
' Extract only high-confidence text
Dim reliableWords = result.Pages.
SelectMany(Function(p) p.Words).
Where(Function(w) w.Confidence >= 70).
Select(Function(w) w.Text)
Console.WriteLine(String.Join(" ", reliableWords))
End Using
End Sub' Per-word confidence and coordinate data
' Filter individual uncertain words without discarding the whole document
Imports IronOcr
Public Sub ProcessWithWordLevelConfidence(imagePath As String)
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadImage(imagePath)
Dim result = ocr.Read(input)
Console.WriteLine($"Document confidence: {result.Confidence}%")
' Iterate words and flag those below threshold
For Each page In result.Pages
For Each word In page.Words
If word.Confidence < 70 Then
' Low-confidence word — log position for review
Console.WriteLine(
$"Low confidence word '{word.Text}' ({word.Confidence}%) " +
$"at X:{word.X} Y:{word.Y}")
End If
Next
Next
' Extract only high-confidence text
Dim reliableWords = result.Pages.
SelectMany(Function(p) p.Words).
Where(Function(w) w.Confidence >= 70).
Select(Function(w) w.Text)
Console.WriteLine(String.Join(" ", reliableWords))
End Using
End SubWORD単位の信頼度フィルタリングは、請求書処理、フォーム抽出、および不確実なテキストに対して処理を実行するよりもレビュー用にフラグを立てる方が望ましいあらゆるワークフローにおいて不可欠です。 信頼度スコアのガイドではスコアリングモデル全体を解説し、読み取り結果のガイドでは構造化された出力階層の全体像を記載しています。
##TesseractOCRAPI から IronOCR へのマッピングリファレンス
| TesseractOCR | IronOCR | ノート |
|---|---|---|
new Engine(tessDataPath, Language.English, EngineMode.Default) | new IronTesseract() | tessdataパスなし; EngineModeの選択は不要 |
TesseractOCR.Pix.Image.LoadFromFile(path) | input.LoadImage(path) | また byte[] と Stream を受け入れます |
engine.Process(pixImage) | ocr.Read(input) | OcrResult を返し、Pageを返しません |
page.Text | result.Text | 同一の意味 |
page.MeanConfidence (0.0–1.0 float) | result.Confidence (0–100 double) | スケールが異なる - 更新閾値の比較 |
Language.English | Language.French | OcrLanguage.English + OcrLanguage.French | 加算演算子(ビット単位のORではない) |
EngineMode.Default | 該当なし | IronOCRは内部でモードを選択します |
EngineMode.LstmOnly | 該当なし | 自動翻訳 |
TesseractOCR.Exceptions.TesseractException | IronOcr.Exceptions.OcrException | 処理すべき例外の種類が少なくなる |
DllNotFoundException (native missing) | 該当なし | IronOCRは、ネイティブな依存関係をバンドルしています |
BadImageFormatException (arch mismatch) | 該当なし | 社内で対応済み |
外部 Image.Mutate(x => x.Grayscale()) | input.Binarize() | 組み込み機能、外部ライブラリ不要 |
外部 Image.Mutate(x => x.Contrast(...)) | input.Contrast() | 自動キャリブレーション |
| 外部ホフ変換による歪み補正 | input.Deskew() | 組み込み、1回のメソッド呼び出し |
外部 GaussianBlur ノイズフィルタ | input.DeNoise() | インテリジェントなノイズ除去 |
DocLib.GetDocReader(pdfPath, ...) | input.LoadPdf(pdfPath) | Docnet.Coreは不要です |
docReader.GetPageReader(i).GetImage() + 一時ファイル | input.LoadPdf(pdfPath) | ループ全体を置換 |
input.LoadPdf(encrypted, Password: "...") | 単一のパラメータ - 他のライブラリは不要 | |
| 該当なし(PDF出力なし) | result.SaveAsSearchablePdf(outputPath) | TesseractOCRには同等の機能はありません |
| 該当なし(フレーム非対応) | input.LoadImageFrames(tiffPath) | 1回の呼び出しでマルチフレームTIFFを生成 |
| 該当なし(ファイルパスのみ) | input.LoadImage(stream) / input.LoadImage(bytes) | 一時ファイルのパターンを削除します |
スレッドごとの Engine インスタンス | スレッド間で共有される単一の IronTesseract | スレッドセーフ設計 |
page.MeanConfidence (document only) | 単語ごとの word.Confidence | 単語単位のスコア表示が可能 |
一般的な移行の問題と解決策
課題 1: 移行後に信頼度閾値が破損する
TesseractOCR: page.MeanConfidence は 0.0 から 1.0 の範囲の浮動小数点を返します。 コードは一般的に if (confidence >= 0.7f) をチェックして結果を受け入れます。
解決策:IronOCRは、0~100のスケールで信頼度を"ダブル"として報告します。 すべての既存の閾値を100倍します。 0.7f の閾値は 70.0 になります。 ドキュメントレベルの信頼性は result.Confidence にあります; 単語レベルの信頼性は result.Pages[n].Words 内の word.Confidence にあります。
// Before (TesseractOCR): page.MeanConfidence >= 0.7f
// After (IronOCR):
var result = new IronTesseract().Read("document.png");
if (result.Confidence >= 70.0)
{
Console.WriteLine(result.Text);
}// Before (TesseractOCR): page.MeanConfidence >= 0.7f
// After (IronOCR):
var result = new IronTesseract().Read("document.png");
if (result.Confidence >= 70.0)
{
Console.WriteLine(result.Text);
}Dim Result = New IronTesseract().Read("document.png")
If Result.Confidence >= 70.0 Then
Console.WriteLine(Result.Text)
End IfDim Result = New IronTesseract().Read("document.png")
If Result.Confidence >= 70.0 Then
Console.WriteLine(Result.Text)
End If課題 2: 移行の試行後に一時ディレクトリが満杯になる
TesseractOCR: Pix.Image.LoadFromFile() 制約の周りに書かれたコードは、よく一時ファイルを作成し、finally ブロックでこれをクリーンアップします。 もし finally ブロック自身が例外をスローした場合、またはアプリケーションが強制終了されると、一時ファイルが蓄積します。
ソリューション: すべての File.WriteAllBytes(tempPath, bytes) + Pix.Image.LoadFromFile(tempPath) パターンを input.LoadImage(bytes) または input.LoadImage(stream) に置き換えます。 コードが一時ファイルを作成しなくなったため、クリーンアップロジックおよび一時保存用のディレクトリ作成処理は完全に削除できます。 すべての発生を見つけるために GetTempPath、および SaveBgraAsPng を検索します。
grep -rn "GetTempFileName\|GetTempPath\|SaveBgraAsPng" --include="*.cs" .
// Before: byte[] → temp file → Pix.Image.LoadFromFile
// After: byte[] → OcrInput directly
using var input = new OcrInput();
input.LoadImage(imageBytes); // no disk write
var result = ocr.Read(input);// Before: byte[] → temp file → Pix.Image.LoadFromFile
// After: byte[] → OcrInput directly
using var input = new OcrInput();
input.LoadImage(imageBytes); // no disk write
var result = ocr.Read(input);Dim input As New OcrInput()
input.LoadImage(imageBytes) ' no disk write
Dim result = ocr.Read(input)Dim input As New OcrInput()
input.LoadImage(imageBytes) ' no disk write
Dim result = ocr.Read(input)サポートされているすべての入力形式については、画像入力ガイドを参照してください。
問題 3: 言語演算子の変更によりコンパイラエラーが発生する
TesseractOCR: 多言語OCRは、フラグ列挙型に対してビット単位のOR演算を使用します: Language.English | 言語:フランス語 これは [Flags]` 列挙パターンです。
ソリューション: IronOCR は加算演算子を使用します: OcrLanguage.English + OcrLanguage.French。 これらは似ていますが、異なる演算子です。 言語式内の to+は、ケースの大部分を処理します。|言語式内の to + は、ケースの大部分を処理します。 ランタイムで構築された言語の組み合わせも + を使用していることを確認します。
// Before (TesseractOCR):
var engine = new Engine(@"./tessdata",
Language.English | Language.French | Language.German,
EngineMode.Default);
// After (IronOCR):
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;// Before (TesseractOCR):
var engine = new Engine(@"./tessdata",
Language.English | Language.French | Language.German,
EngineMode.Default);
// After (IronOCR):
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;' Before (TesseractOCR):
Dim engine = New Engine("./tessdata", Language.English Or Language.French Or Language.German, EngineMode.Default)
' After (IronOCR):
Dim ocr = New IronTesseract()
ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German' Before (TesseractOCR):
Dim engine = New Engine("./tessdata", Language.English Or Language.French Or Language.German, EngineMode.Default)
' After (IronOCR):
Dim ocr = New IronTesseract()
ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German課題 4: アンインストール後も Docnet および ImageSharp パッケージが参照されたままになっている
TesseractOCR: PDFワークフローにTesseractOCRを使用するプロジェクトでは、通常、Docnet.Coreを直接の依存関係として持ち、前処理にはSixLabors.ImageSharpまたはSkiaSharpを使用します。 IronOCR に切り替えた後、using ステートメントが完全に削除されていないため、これらのパッケージは頻繁に .csproj に残ります。
ソリューション: .csproj からパッケージを削除した後、全ての using SixLabors.ImageSharp、および関連する名前空間の参照を検索します。 もし using ステートメントが依存関係ツリーに存在しなくなった名前空間を参照している場合、コンパイラーはそれらをフラグします - ただし、dotnet remove package コマンドが実際に実行された場合のみです。
grep -rn "using Docnet\|using SixLabors\|using SkiaSharp" --include="*.cs" .
認識されたファイル参照を削除し、古いパイプラインに役立った前処理ヘルパーメソッド (SaveBgraAsPng, ApplyGrayscale, ApplyThreshold, および類似) を削除します。
課題 5: 移行後に Docker イメージのサイズが増加する
TesseractOCR: 一部の Docker 構成は、システムパッケージとして apt-get install tesseract-ocr tesseract-ocr-eng 経由で Tesseract をインストールし、それらのシステムバイナリを参照します。 これにより、言語パックに応じて画像サイズが約30~80MB増加します。
解決策:IronOCRは、NuGetパッケージ内に独自のTesseractバイナリを同梱しています。 Dockerfile の apt-get install tesseract-ocr 行はもはや必要なく、削除する必要があります。 言語パックは apt-get install tesseract-ocr-fra からではなく、NuGet からも取得されます。 Docker デプロイメントガイドでは、IronOCR をコンテナ内で実行するために必要な、検証済みのベースイメージ構成と正確なパッケージが提供されています。
# Remove these lines after migration:
# RUN apt-get install -y tesseract-ocr tesseract-ocr-eng tesseract-ocr-fra
# COPY ./tessdata /app/tessdata
問題 6: TesseractException と DllNotFoundException キャッチブロックが到達不能になる
TesseractOCR: 本番のTesseractOCR統合は、DllNotFoundException(ネイティブバイナリ欠落)および BadImageFormatException(アーキテクチャの不一致)をキャッチします。 これらの例外タイプは、tessdataおよびネイティブバイナリのデプロイメントの不安定性に対する予防的な対応です。
解決策:IronOCRはネイティブ依存関係をバンドルし、初期化を内部で管理します。 DllNotFoundException および BadImageFormatException は適用されません。 それらのキャッチブロックを削除してください。 例外の範囲は、OCRの失敗による IronOcr.Exceptions.OcrException と、ファイルアクセスの問題による標準の IOException に縮小されます。
// Before: five exception types to handle
catch (TesseractOCR.Exceptions.TesseractException ex) { ... }
catch (DllNotFoundException ex) { ... }
catch (BadImageFormatException ex) { ... }
catch (OutOfMemoryException ex) { ... }
// After: two exception types
catch (IronOcr.Exceptions.OcrException ex) { ... }
catch (IOException ex) { ... }// Before: five exception types to handle
catch (TesseractOCR.Exceptions.TesseractException ex) { ... }
catch (DllNotFoundException ex) { ... }
catch (BadImageFormatException ex) { ... }
catch (OutOfMemoryException ex) { ... }
// After: two exception types
catch (IronOcr.Exceptions.OcrException ex) { ... }
catch (IOException ex) { ... }' Before: five exception types to handle
Catch ex As TesseractOCR.Exceptions.TesseractException
...
Catch ex As DllNotFoundException
...
Catch ex As BadImageFormatException
...
Catch ex As OutOfMemoryException
...
' After: two exception types
Catch ex As IronOcr.Exceptions.OcrException
...
Catch ex As IOException
...' Before: five exception types to handle
Catch ex As TesseractOCR.Exceptions.TesseractException
...
Catch ex As DllNotFoundException
...
Catch ex As BadImageFormatException
...
Catch ex As OutOfMemoryException
...
' After: two exception types
Catch ex As IronOcr.Exceptions.OcrException
...
Catch ex As IOException
...##TesseractOCR移行チェックリスト
移行前
コードベース内のTesseractOCRの使用箇所をすべて監査してください:
grep -rn "using TesseractOCR" --include="*.cs" .
grep -rn "new Engine(" --include="*.cs" .
grep -rn "Pix\.Image\.LoadFromFile\|engine\.Process\|page\.Text\|MeanConfidence" --include="*.cs" .
grep -rn "Language\." --include="*.cs" .
削除されるすべてのサポートインフラストラクチャを特定してください:
grep -rn "using Docnet\|using SixLabors\|GetTempFileName\|SaveBgraAsPng" --include="*.cs" .
grep -rn "tessdata" --include="*.cs" .
grep -rn "tessdata" --include="*.csproj" .
grep -rn "tessdata" Dockerfile 2>/dev/null || true
移行前に代表的なドキュメントサンプルを用いて現在の正確性の基準を記録し、移行後の品質を検証できるようにしてください。
コードの移行
dotnet remove package TesseractOCRを実行するdotnet remove package Docnet.Coreを実行する(存在する場合)- 前処理のために追加した場合は
dotnet remove package SixLabors.ImageSharpを実行する dotnet add package IronOcrを実行する- アプリケーション起動時に
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"を追加する using TesseractOCRおよびusing TesseractOCR.Enumsをusing IronOcrに置き換えるnew Engine(tessDataPath, Language.English, EngineMode.Default)をnew IronTesseract()に置き換えるTesseractOCR.Pix.Image.LoadFromFile(path)をinput.LoadImage(path)にOcrInputインスタンスで置き換えるengine.Process(pixImage)をocr.Read(input)に置き換えるpage.Textをresult.Textに置き換える- 信頼度閾値の比較を更新 - IronOCRの0~100スケールに合わせて、0.0~1.0のすべての値に100を乗算する
Language.Xを置き換える | Language.YwithOcrLanguage.X + OcrLanguage.Y`- すべての前処理ヘルパーメソッド (
SaveBgraAsPng, 手動フィルターチェーン、一時ファイルロジック ) を削除します - Docnet PDF レンダリングループを
input.LoadPdf(path)またはinput.LoadPdfPages(path, start, end)に置き換える - マルチフレーム TIFF ループを
input.LoadImageFrames(tiffPath)に置き換える File.WriteAllBytes(tempPath, bytes)+LoadFromFile(tempPath)をinput.LoadImage(bytes)に置き換える- キャッチブロックを更新する -
TesseractException,DllNotFoundException,BadImageFormatExceptionを削除する - プロジェクトの出力ディレクトリ設定およびDockerイメージからtessdataフォルダを削除する
移行後
dotnet buildがコンパイラーエラーゼロ、到達不能なキャッチ警告ゼロを生成するのを確認する- 移行前の精度ベースラインサンプルに対してOCRを実行し、結果を比較する
- 複数ページの TIFF ファイルから、正しいページ数が抽出されることを確認する
- 検索可能なPDF出力ファイルが、テキストを選択可能なPDFビューアで開くことを確認してください
- アプリケーションの実際のデータソースからのバイト配列およびストリーム入力パスをテストする
- WORD レベルの信頼度値が 0~100 の範囲内にあることを確認してください(0.0~1.0 ではありません)。
- 並列処理テストを実行し、スレッドごとのエンジン割り当てに関する警告が発生しないことを確認する
- ターゲット環境(Docker、Azure、Linux)にデプロイし、IronOCR が
DllNotFoundExceptionなしで初期化することを確認する - デプロイメントスクリプトのどこにも tessdata フォルダや
.traineddataファイルが参照されていないことを確認する
IronOCRへの移行の主なメリット
前処理は、100行の依存関係ではなく、1行の構成になります。 移行後、input.DeNoise()、および input.Contrast() は、外部イメージングライブラリ、手動パラメータ調整、およびそれらを結びつけている一時ファイルの書き込みに取って代わります。 スマートフォンで撮影した写真、歪んだスキャン画像、コントラストの低いファックスなど、以前は専任の前処理エンジニアを必要としていた種類のドキュメントでも、組み込みのパイプラインから信頼性の高い出力が得られます。前処理機能のページには、利用可能なすべてのフィルターが一覧表示されています。
PDFは第一級の入力および出力形式です。Docnet依存関係、BGRAからPNGへの変換ヘルパー、一時ファイル管理ループ、パスワード保護されたファイル用のサードパーティ製ライブラリ——これらすべてが不要になります。 システムに到着したあらゆる PDF は、input.LoadPdf() に直接入ります。 検索可能性を必要とするあらゆるスキャンされた文書は、result.SaveAsSearchablePdf() を通じて出ていきます。 TesseractOCRでは100行以上を要していたPDF処理の全プロセスが、わずか数回のメソッド呼び出しで済むようになります。 サポートされているPDFワークフローの全範囲については、PDF OCRのユースケースページをご覧ください。
構造化出力がフラットなテキスト文字列に取って代わります。 result.Lines、および result.Words は、要素ごとの座標と単語ごとの信頼スコアと共に文書の構造を公開します。 これまで、請求書番号、日付、金額などの特定のフィールドを見つけるためにヒューリスティックな解析を必要としていたワークフローでも、代わりにWORDレベルの座標と信頼度フィルタリングを使用できるようになります。 これは、IronOCRのOCR結果機能を活用して、信頼性の高いフォーム抽出およびドキュメント処理パイプラインを構築するための基盤となります。
デプロイメントが tessdata オーケストレーションを必要としなくなります。 tessdata フォルダー、curl ダウンロードスクリプト、Docker COPY ./tessdata レイヤー、.traineddata ファイルのための CI/CD キャッシュ設定 - それらはすべて消えます。 これらのライブラリは NuGet パッケージとして提供され、バージョン管理され、プロジェクトの他の依存関係と共に復元され、ターゲットが開発者のワークステーション、Docker コンテナ、Azure App Service、または AWS Lambda のいずれであっても、同一の方法でデプロイされます。 Azure 展開ガイドおよび Linux 展開ガイドには、本番環境向けの検証済み構成が記載されています。
ライセンスモデルは明確です。TesseractOCR自体は無料ですが、その運用に必要なインフラにはコストがかかります。具体的には、前処理の実装、PDFライブラリの評価、tessdataのデプロイスクリプト作成、および外部依存関係チェーンの継続的なメンテナンスにかかる開発者の工数です。 IronOCR の永続ライセンス ($999 Lite、$1,499 Professional、$2,999 Enterprise) は、一度きりの費用で、数週間のインフラ作業に取って代わり、継続的な保守作業を排除します。 単一のボランティアメンテナーによるGitHubのイシューキューへの依存に代わり、確実な対応が保証された商用サポートが提供されます。
関連する記事


