Asprise OCRからIronOCRへの移行
このガイドでは、 .NET開発者がAsprise OCRをIronOCRに置き換えるためのすべての手順を説明します。 本書では、機械的なパッケージの入れ替え、名前空間の変更、および本番環境 for .NETアプリケーションにおけるAspriseの使用例の大部分を占める4つのコード移行パターンについて解説します。 既に移行を決定しており、具体的な行動計画を必要としている開発者が、本書の対象読者です。
Asprise OCRから移行する理由
Asprise OCRは、当初Java製品として設計されました.NET版はJava由来のネイティブエンジンをラップしたものであり、そ for Java由来の特性が、デプロイメントからAPI設計、ライセンス制約に至るまで、 .NETにおけるライブラリの動作のあらゆる側面に影響を与えています。
JREおよびネイティブバイナリ依存関係。Asprise OCRfor .NETは、プラットフォーム固有のネイティブバイナリ(libaocr.dylib) がアプリケーションが実行されるすべてのマシンに存在する必要があります。 各バイナリは、ターゲットプラットフォームおよびプロセスアーキテクチャと完全に一致する必要があります。 32ビットDLLで構築された64ビットDockerコンテナは、実行時にBadImageFormatExceptionをスローします。 DllNotFoundExceptionをスローします。 どちらのエラーもビルド時には発生しません。新しいデプロイ対象(新しいサーバー、新しいコンテナイメージ、CIエージェントなど)ごとに、手動でバイナリを調達する必要が生じます。
Javaの伝統を受け継いだ文字列定数API。 Aspriseは、認識タイプと出力形式に対する整数定数を公開しており、Ocr.OUTPUT_FORMAT_XMLが含まれます。 これらの定数は、Java SDKの整数ベースのAPIに直接対応しています。 .NET開発者は、有効な定数値に関するIntelliSenseガイダンス、引数の組み合わせに関するコンパイル時の安全性、および厳密に型付けされた結果オブジェクトを受け取ることができません。 構造化された出力を抽出するには、XML文字列を手動で解析する必要があります。
回避策なしでは非同期処理はサポートされていません。Aspriseはネイティブの非同期APIを提供していません。 同期Asprise呼び出しをTask.RunでラッピングしてASP.NETスレッドをブロックしないようにすることは、スレッドプールに圧力をかけ、LITEとSTANDARDティアでの同時実行を禁止するライセンス制約を解決しません。 現代 for .NETアプリケーションにおける非同期パターン(バックグラウンドサービス、最小限のAPIエンドポイント、Azure Functionsなど)には、Aspriseに相当する簡潔なソリューションが存在しない。
複数フレームのTIFFファイル処理には手動分割が必要です。Aspriseは単一画像ファイルのみを処理します。 複数ページのTIFFファイルを処理するには、フレームを個々のファイルに分割し、各ファイルをループ処理するための外部コードが必要です。フレームのメタデータやページ番号は出力には引き継がれません。
スレッド制限により、本番環境への展開が妨げられます。LITE (約299ドル)およびSTANDARD(約699ドル)ライセンスでは、契約上、実行が単一のスレッドおよび単一のプロセスに制限されます。 ASP.NET Coreは、すべてのHTTPリクエストをスレッドプール上で処理します。 これらのティアでAspriseを呼び出すすべてのWeb APIエンドポイントは、最初の同時リクエストからライセンス違反となりますEnterpriseにアップグレードするとこの制限は解除されますが、営業担当者への問い合わせが必要となり、価格は公表されていません。導入規模に応じて、2,000ドルから5,000ドル以上と見積もられています。
出力形式の処理には文字列解析が必要です。 OUTPUT_FORMAT_XMLが指定されている場合、Aspriseは生のXML文字列を返します。 アプリケーションは、その文字列を逆シリアル化し、その構造を検証し、単語とその座標を抽出する役割を担います。 単語ごとの信頼度スコアは、XML属性に埋め込まれています。 オブジェクトモデルは存在せず、文字列操作のみが存在する。
基本的な問題
Aspriseでは、最初のOCR呼び出しを実行する前に、JREに隣接するネイティブバイナリ構成が必要です。 IronOCRはNuGetパッケージ以外に何も必要としません。
// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp(); // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST); // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine(); // Must call or native memory leaks
// Asprise: native binary must exist in PATH or application directory
// aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp(); // Static init — touches native binary
Ocr ocr = new Ocr();
ocr.StartEngine("eng", Ocr.SPEED_FAST); // Allocates native engine memory
string text = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
ocr.StopEngine(); // Must call or native memory leaks
' Asprise: native binary must exist in PATH or application directory
' aocr_x64.dll missing → DllNotFoundException at runtime, not at build
Ocr.SetUp() ' Static init — touches native binary
Dim ocr As New Ocr()
ocr.StartEngine("eng", Ocr.SPEED_FAST) ' Allocates native engine memory
Dim text As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
ocr.StopEngine() ' Must call or native memory leaks
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
// IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
string text = new IronTesseract().Read(imagePath).Text;
' IronOCR: dotnet add package IronOcr — no binary sourcing, no lifecycle calls
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim text As String = New IronTesseract().Read(imagePath).Text
IronOCRとAsprise OCR:機能比較
以下の表は、この移行を評価する開発者にとって最も関連性の高い機能についてまとめたものです。
| フィーチャー | Asprise OCR | IronOCR |
|---|---|---|
| 主要プラットフォーム | Java(レガシー) | .NETネイティブ |
| NuGetのインストール | ラッパー+プラットフォームネイティブDLL | シングルパッケージ(IronOcr) |
| 実行時にネイティブバイナリが必要 | はい(プラットフォームごとのDLL) | なし |
| .NET API スタイル | 整数定数、文字列の戻り値 | 厳密に型指定されたクラスと列挙型 |
IDisposable / using パターン |
未実装 | はい(OcrInput) |
| 非同期OCR | ネイティブサポートなし | はい(ReadAsync) |
| マルチスレッド処理 — Lite/STANDARD ティア | ライセンスにより禁止されています | 許可されています |
| マルチスレッド処理 - 全階層 | Enterprise版のみ | 全ティア |
| ASP.NET Core Web API のサポート | Enterpriseが必要です | どのティアでも |
| Azure Functions / AWS Lambda | Enterpriseが必要です | どのティアでも |
| ネイティブPDF入力 | なし | はい |
| マルチフレームTIFF入力 | いいえ(手動フレーム分割) | はい(LoadImageFrames) |
| バイト配列とストリーム入力 | 制限的 | はい |
| 内蔵画像前処理機能 | なし | はい(9個以上のフィルター) |
| 検索可能なPDF出力 | なし | はい(SaveAsSearchablePdf) |
| 構造化結果オブジェクトモデル | いいえ(XML文字列のみ) | はい(ページ数、段落数、単語数、文字数) |
| 単語ごとの信頼度スコア | いいえ(XML属性の解析) | はい(result.Confidence) |
| 単語のピクセル座標 | XML属性の解析 | 厳密に型付けされたプロパティ |
| 言語数 | 20歳以上 | 125+ |
| 厳密な型付けによる言語選択 | いいえ(文字列コード) | はい(OcrLanguage enum) |
| バーコード読み取り | はい(別個の認識タイプ) | はい(設定フラグ) |
| hOCRエクスポート | なし | はい |
| クロスプラットフォーム展開 | プラットフォームごとの手動バイナリ | NuGetはすべてのプラットフォームに対応しています |
| Docker / Linux / macOS | 手動LD_LIBRARY_PATH設定 |
すぐに使える |
| .NET互換性 | 限定(ジャワ橋) | .NET Framework 4.6.2以降、 .NET 5~9 |
| サーバー利用のエントリー料金 | Enterprise(約2,000ドル以上) | $999(Lite、すべての機能) |
| ライセンスの種類 | ティアごとに、Enterpriseの営業担当者にお問い合わせください。 | 永久ライセンス(一括購入) |
クイックスタート:Asprise OCRからIronOCRへの移行
ステップ 1: NuGet パッケージを置き換える
Asprise OCRを削除する:
dotnet remove package asprise-ocr-api
dotnet remove package asprise-ocr-api
NuGetパッケージページからIronOCRをインストールしてください。
dotnet add package IronOcr
ステップ 2: 名前空間の更新
Aspriseの名前空間をIronOCRの名前空間に置き換えます:
// Before (Asprise)
using asprise.ocr;
// After (IronOCR)
using IronOcr;
// Before (Asprise)
using asprise.ocr;
// After (IronOCR)
using IronOcr;
Imports IronOcr
ステップ 3: ライセンスの初期化
アプリケーション起動時にライセンスキーの割り当てを行います。OCR呼び出しの前にStartup.Configureで、あるいは静的コンストラクター内で行います:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
IronOCRのライセンスページから無料トライアルキーを入手できます。 開発および評価期間中、 IronOCRはキーを使用せずに実行され、出力には試用版の透かしが刻印されます。
コード移行の例
JREパス構成とエンジン初期化の削除
LinuxまたはmacOS上で動作するAspriseアプリケーションには、通常、OCR処理を開始する前にJREパスを設定したり、ネイティブバイナリの存在を検証したりする起動コードが含まれています。 IronOCRには、このインフラストラクチャに相当するものはありません。
Asprise OCRアプローチ:
// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
// Validate native library is reachable before first use
string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
: RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/usr/lib/libaocr.so"
: "/usr/local/lib/libaocr.dylib";
if (!File.Exists(nativePath))
throw new FileNotFoundException(
$"Asprise native binary not found: {nativePath}. " +
"Deploy the correct platform binary before starting.");
// Static global init — must run before any Ocr instance is created
Ocr.SetUp();
}
// AppStartup.cs — native binary validation before accepting any requests
public static void InitializeOcr()
{
// Validate native library is reachable before first use
string nativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll")
: RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
? "/usr/lib/libaocr.so"
: "/usr/local/lib/libaocr.dylib";
if (!File.Exists(nativePath))
throw new FileNotFoundException(
$"Asprise native binary not found: {nativePath}. " +
"Deploy the correct platform binary before starting.");
// Static global init — must run before any Ocr instance is created
Ocr.SetUp();
}
Imports System
Imports System.IO
Imports System.Runtime.InteropServices
' AppStartup.vb — native binary validation before accepting any requests
Public Module AppStartup
Public Sub InitializeOcr()
' Validate native library is reachable before first use
Dim nativePath As String = If(RuntimeInformation.IsOSPlatform(OSPlatform.Windows),
Path.Combine(AppContext.BaseDirectory, "aocr_x64.dll"),
If(RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
"/usr/lib/libaocr.so",
"/usr/local/lib/libaocr.dylib"))
If Not File.Exists(nativePath) Then
Throw New FileNotFoundException($"Asprise native binary not found: {nativePath}. " &
"Deploy the correct platform binary before starting.")
End If
' Static global init — must run before any Ocr instance is created
Ocr.SetUp()
End Sub
End Module
IronOCRのアプローチ:
// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// That is it. なし binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
// Program.cs — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// That is it. なし binary validation, no path configuration, no SetUp() call.
// NuGet resolved the correct native runtime during package restore.
' Program.vb — license key assignment is the entire initialization
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
' That is it. なし binary validation, no path configuration, no SetUp() call.
' NuGet resolved the correct native runtime during package restore.
Aspriseパターンは通常、複数のファイルにわたって15〜30行で、起動時のバリデーター、プラットフォームスイッチ、デプロイメントメッセージ付きの例外、及びSetUp()呼び出しを含みます。 IronOCRはそれらすべてを単一の課題に置き換えます。 IronTesseractのセットアップガイドでは、カスタムのtessdataパスやオフライン操作が必要な環境向けのデプロイメント構成オプションについて説明しています。
XML出力フォーマットを構造化結果オブジェクトに置き換える
Aspriseは、OUTPUT_FORMAT_XMLが指定されている場合、構造化された出力を生のXML文字列として生成します。 その文字列から単語テキスト、座標、信頼度を抽出するには、XML解析コードが必要です。 IronOCRは型付きオブジェクトグラフを返します。
Asprise OCRアプローチ:
// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
string xmlOutput = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_XML); // Returns raw XML, not an object
// Parse the XML manually to extract words and coordinates
var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
var words = doc.Descendants("word")
.Select(w => new
{
Text = (string)w.Attribute("text"),
Confidence = (float)w.Attribute("confidence"),
X = (int)w.Attribute("x"),
Y = (int)w.Attribute("y"),
})
.ToList();
foreach (var word in words)
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
ocr.StopEngine();
}
// Asprise: structured output is an XML string — must parse manually
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
string xmlOutput = ocr.Recognize(
imagePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_XML); // Returns raw XML, not an object
// Parse the XML manually to extract words and coordinates
var doc = System.Xml.Linq.XDocument.Parse(xmlOutput);
var words = doc.Descendants("word")
.Select(w => new
{
Text = (string)w.Attribute("text"),
Confidence = (float)w.Attribute("confidence"),
X = (int)w.Attribute("x"),
Y = (int)w.Attribute("y"),
})
.ToList();
foreach (var word in words)
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}");
}
finally
{
ocr.StopEngine();
}
Imports System.Xml.Linq
' Asprise: structured output is an XML string — must parse manually
Ocr.SetUp()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
Dim xmlOutput As String = ocr.Recognize(imagePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_XML) ' Returns raw XML, not an object
' Parse the XML manually to extract words and coordinates
Dim doc As XDocument = XDocument.Parse(xmlOutput)
Dim words = doc.Descendants("word") _
.Select(Function(w) New With {
.Text = CStr(w.Attribute("text")),
.Confidence = CSng(w.Attribute("confidence")),
.X = CInt(w.Attribute("x")),
.Y = CInt(w.Attribute("y"))
}) _
.ToList()
For Each word In words
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence}")
Next
Finally
ocr.StopEngine()
End Try
IronOCRのアプローチ:
// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
foreach (var word in paragraph.Words)
{
Console.WriteLine(
$"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
}
}
}
// IronOCR: structured result is a typed object — no XML parsing
var result = new IronTesseract().Read(imagePath);
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
foreach (var word in paragraph.Words)
{
Console.WriteLine(
$"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%");
}
}
}
Imports IronOcr
' IronOCR: structured result is a typed object — no XML parsing
Dim result = New IronTesseract().Read(imagePath)
For Each page In result.Pages
For Each paragraph In page.Paragraphs
For Each word In paragraph.Words
Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf={word.Confidence:F1}%")
Next
Next
Next
XMLの逆シリアル化も、属性の型変換も、スキーマの仮定も一切行いません。 OcrResultオブジェクトモデルは、ページ、段落、行、単語、文字を型付きのプロパティで公開します。 結果読み取りガイドでは、階層構造と座標系全体について説明しており、自動化されたワークフローにおける信頼度閾値によるフィルタリング方法も含まれています。
マルチフレームTIFF処理
Aspriseは単一の画像ファイルを受け付けます。 文書スキャンワークフローでよく見られるマルチフレームTIFFファイルは、Aspriseで処理する前に個々のフレームファイルに分割する必要があります。 IronOCRはマルチフレームTIFFをLoadImageFramesで直接受け入れます。
Asprise OCRアプローチ:
// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
for (int i = 0; i < frameCount; i++)
{
tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
string framePath = $"frame_{i}.png";
tiff.Save(framePath);
frameFiles.Add(framePath);
}
}
// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
foreach (var framePath in frameFiles)
{
string pageText = ocr.Recognize(
framePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
allText.AppendLine(pageText);
}
}
finally
{
ocr.StopEngine();
// Clean up temporary frame files
foreach (var f in frameFiles)
File.Delete(f);
}
Console.WriteLine(allText.ToString());
// Asprise: no multi-frame TIFF support — split frames externally first
// Using an external imaging library (e.g., System.Drawing or Magick.NET)
var frameFiles = new List<string>();
using (var tiff = System.Drawing.Image.FromFile("scanned-batch.tiff"))
{
int frameCount = tiff.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
for (int i = 0; i < frameCount; i++)
{
tiff.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
string framePath = $"frame_{i}.png";
tiff.Save(framePath);
frameFiles.Add(framePath);
}
}
// Now process each frame individually — sequential on LITE/STANDARD
var allText = new System.Text.StringBuilder();
Ocr.SetUp();
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
foreach (var framePath in frameFiles)
{
string pageText = ocr.Recognize(
framePath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
allText.AppendLine(pageText);
}
}
finally
{
ocr.StopEngine();
// Clean up temporary frame files
foreach (var f in frameFiles)
File.Delete(f);
}
Console.WriteLine(allText.ToString());
Imports System.Drawing
Imports System.Text
Imports System.IO
' Asprise: no multi-frame TIFF support — split frames externally first
' Using an external imaging library (e.g., System.Drawing or Magick.NET)
Dim frameFiles As New List(Of String)()
Using tiff As Image = Image.FromFile("scanned-batch.tiff")
Dim frameCount As Integer = tiff.GetFrameCount(Imaging.FrameDimension.Page)
For i As Integer = 0 To frameCount - 1
tiff.SelectActiveFrame(Imaging.FrameDimension.Page, i)
Dim framePath As String = $"frame_{i}.png"
tiff.Save(framePath)
frameFiles.Add(framePath)
Next
End Using
' Now process each frame individually — sequential on LITE/STANDARD
Dim allText As New StringBuilder()
Ocr.SetUp()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
For Each framePath As String In frameFiles
Dim pageText As String = ocr.Recognize(framePath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
allText.AppendLine(pageText)
Next
Finally
ocr.StopEngine()
' Clean up temporary frame files
For Each f As String In frameFiles
File.Delete(f)
Next
End Try
Console.WriteLine(allText.ToString())
IronOCRのアプローチ:
// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff"); // All frames, one call
var result = new IronTesseract().Read(input);
// Access each page independently with its page number
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
// IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
using var input = new OcrInput();
input.LoadImageFrames("scanned-batch.tiff"); // All frames, one call
var result = new IronTesseract().Read(input);
// Access each page independently with its page number
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
Imports IronOcr
' IronOCR: multi-frame TIFF loads directly — no frame splitting, no temp files
Using input As New OcrInput()
input.LoadImageFrames("scanned-batch.tiff") ' All frames, one call
Dim result = New IronTesseract().Read(input)
' Access each page independently with its page number
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
Next
End Using
Asprise方式では、外部イメージングへの依存、一時ファイルの管理、手動によるクリーンアップ、およびフレームごとの逐次処理が必要となる。 IronOCRは、すべてのフレームを一度に処理します。 TIFFおよびGIF入力ガイドでは、特定のページのみが必要な場合の、大きなTIFFファイルのフレーム範囲の選択方法について説明しています。
検索可能なPDF生成
Aspriseは、どのライセンスレベルにおいても、検索可能なPDF出力機能を提供していません。 スキャンした文書からOCRテキストを埋め込んだPDFを作成するには、外部のPDFライブラリ、テキストの位置を取得するための別のOCR処理、および手動によるオーバーレイ構築が必要です。 IronOCRは、認識結果から直接検索可能なPDFを生成します。
Asprise OCRアプローチ:
// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
recognizedText = ocr.Recognize(
"scanned-contract.jpg",
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT); // Only plain text — no position data
}
finally
{
ocr.StopEngine();
}
// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
// Asprise: no searchable PDF output — external PDF library required
// Step 1: OCR the document to get text
Ocr.SetUp();
Ocr ocr = new Ocr();
string recognizedText;
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
recognizedText = ocr.Recognize(
"scanned-contract.jpg",
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT); // Only plain text — no position data
}
finally
{
ocr.StopEngine();
}
// Step 2: Use an external PDF library to embed text over the image
// (iTextSharp, PdfSharp, or similar — adds another dependency and license)
// Text positioning requires coordinate data Asprise cannot provide in plain text mode
// ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone");
' Asprise: no searchable PDF output — external PDF library required
' Step 1: OCR the document to get text
Ocr.SetUp()
Dim ocr As New Ocr()
Dim recognizedText As String
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
recognizedText = ocr.Recognize( _
"scanned-contract.jpg", _
Ocr.RECOGNIZE_TYPE_TEXT, _
Ocr.OUTPUT_FORMAT_PLAINTEXT) ' Only plain text — no position data
Finally
ocr.StopEngine()
End Try
' Step 2: Use an external PDF library to embed text over the image
' (iTextSharp, PdfSharp, or similar — adds another dependency and license)
' Text positioning requires coordinate data Asprise cannot provide in plain text mode
' ... 40-80 lines of PDF construction code
Console.WriteLine("Searchable PDF: not achievable with Asprise alone")
IronOCRのアプローチ:
// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");
// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
var batchResult = new IronTesseract().Read(imagePath);
string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
batchResult.SaveAsSearchablePdf(outputPath);
Console.WriteLine($"Converted: {outputPath}");
}
// IronOCR: searchable PDF in two lines — no external PDF library
var result = new IronTesseract().Read("scanned-contract.jpg");
result.SaveAsSearchablePdf("searchable-contract.pdf");
// Batch: convert a folder of scanned images to searchable PDFs
foreach (var imagePath in Directory.GetFiles("scans", "*.jpg"))
{
var batchResult = new IronTesseract().Read(imagePath);
string outputPath = Path.ChangeExtension(imagePath, ".searchable.pdf");
batchResult.SaveAsSearchablePdf(outputPath);
Console.WriteLine($"Converted: {outputPath}");
}
Imports System.IO
Imports IronOcr
' IronOCR: searchable PDF in two lines — no external PDF library
Dim result = New IronTesseract().Read("scanned-contract.jpg")
result.SaveAsSearchablePdf("searchable-contract.pdf")
' Batch: convert a folder of scanned images to searchable PDFs
For Each imagePath In Directory.GetFiles("scans", "*.jpg")
Dim batchResult = New IronTesseract().Read(imagePath)
Dim outputPath As String = Path.ChangeExtension(imagePath, ".searchable.pdf")
batchResult.SaveAsSearchablePdf(outputPath)
Console.WriteLine($"Converted: {outputPath}")
Next
検索可能なPDFファイルには、元の画像が視覚レイヤーとして含まれており、その上にOCRで読み取られたテキストが正しい座標に重ねて表示されています。これは、アーカイブやコンプライアンス関連のワークフローにおける標準フォーマットです。 長期保存用のPDF/A出力などのオプションについては、検索可能なPDFの操作ガイドと検索可能なPDFの例を参照してください。
Webアプリケーションにおける非同期OCR
Aspriseには非同期APIがありません。 開発者は、非同期.NETアプリケーションにこれを統合し、同期呼び出しをTask.Runでラッピングし、スレッドプールスレッドを使用しますが、ブロッキングを排除しません。 IronOCRはネイティブの非同期パスを提供します。
Asprise OCRアプローチ:
// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
string tempPath = Path.GetTempFileName();
await using (var fs = new FileStream(tempPath, FileMode.Create))
await fileStream.CopyToAsync(fs);
// Task.Run wraps synchronous Asprise — occupies a thread pool thread
// Two concurrent requests still violate LITE/STANDARD license
return await Task.Run(() =>
{
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
return ocr.Recognize(
tempPath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
}
finally
{
ocr.StopEngine();
File.Delete(tempPath);
}
});
}
// Asprise: no async API — must offload to Task.Run
// This blocks a thread pool thread during the entire OCR operation
// On LITE/STANDARD, concurrent Task.Run calls = license violation
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
string tempPath = Path.GetTempFileName();
await using (var fs = new FileStream(tempPath, FileMode.Create))
await fileStream.CopyToAsync(fs);
// Task.Run wraps synchronous Asprise — occupies a thread pool thread
// Two concurrent requests still violate LITE/STANDARD license
return await Task.Run(() =>
{
Ocr ocr = new Ocr();
try
{
ocr.StartEngine("eng", Ocr.SPEED_FAST);
return ocr.Recognize(
tempPath,
Ocr.RECOGNIZE_TYPE_TEXT,
Ocr.OUTPUT_FORMAT_PLAINTEXT);
}
finally
{
ocr.StopEngine();
File.Delete(tempPath);
}
});
}
Imports System.IO
Imports System.Threading.Tasks
' Asprise: no async API — must offload to Task.Run
' This blocks a thread pool thread during the entire OCR operation
' On LITE/STANDARD, concurrent Task.Run calls = license violation
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
Dim tempPath As String = Path.GetTempFileName()
Await Using fs As New FileStream(tempPath, FileMode.Create)
Await fileStream.CopyToAsync(fs)
End Using
' Task.Run wraps synchronous Asprise — occupies a thread pool thread
' Two concurrent requests still violate LITE/STANDARD license
Return Await Task.Run(Function()
Dim ocr As New Ocr()
Try
ocr.StartEngine("eng", Ocr.SPEED_FAST)
Return ocr.Recognize(tempPath, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT)
Finally
ocr.StopEngine()
File.Delete(tempPath)
End Try
End Function)
End Function
IronOCRのアプローチ:
// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
using var input = new OcrInput();
input.LoadImage(fileStream); // Stream input directly — no temp file
var ocr = new IronTesseract();
var result = await ocr.ReadAsync(input);
return result.Text;
}
// IronOCR: native async, concurrent requests permitted on all tiers
public async Task<string> ProcessUploadAsync(Stream fileStream, string fileName)
{
using var input = new OcrInput();
input.LoadImage(fileStream); // Stream input directly — no temp file
var ocr = new IronTesseract();
var result = await ocr.ReadAsync(input);
return result.Text;
}
Imports System.IO
Imports System.Threading.Tasks
' IronOCR: native async, concurrent requests permitted on all tiers
Public Async Function ProcessUploadAsync(fileStream As Stream, fileName As String) As Task(Of String)
Using input As New OcrInput()
input.LoadImage(fileStream) ' Stream input directly — no temp file
Dim ocr As New IronTesseract()
Dim result = Await ocr.ReadAsync(input)
Return result.Text
End Using
End Function
IronOCRバージョンは、一時ファイル書き込み、Task.Runラッパー、およびスレッドブロッキング動作を排除します。 複数の同時要求はそれぞれ自分のIronTesseractインスタンスを作成します。クラスはステートレスであり、各インスタンスは独立しています。 非同期OCRガイドは、ReadAsyncパターンとホスト型サービスでの長時間のバッチ操作のためのキャンセレーショントークンサポートについて説明します。
Asprise OCRAPI からIronOCRへのマッピングリファレンス
| Asprise OCR | IronOCR相当値 |
|---|---|
asprise.ocr 名前空間 |
IronOcr 名前空間 |
Ocr.SetUp() |
不要 |
new Ocr() |
new IronTesseract() |
ocr.StartEngine("eng", Ocr.SPEED_FAST) |
不要 |
ocr.StartEngine("eng+fra", speed) |
ocr.Language = OcrLanguage.English + OcrLanguage.French |
ocr.Recognize(path, type, format) |
ocr.Read(path) または ocr.Read(input) |
Ocr.RECOGNIZE_TYPE_TEXT |
デフォルトの動作 |
Ocr.RECOGNIZE_TYPE_BARCODE |
ocr.Configuration.ReadBarCodes = true |
Ocr.RECOGNIZE_TYPE_ALL |
ocr.Configuration.ReadBarCodes = true |
Ocr.OUTPUT_FORMAT_PLAINTEXT |
result.Text |
Ocr.OUTPUT_FORMAT_XML |
result.Pages / result.Pages[n].Words |
Ocr.OUTPUT_FORMAT_PDF |
result.SaveAsSearchablePdf(path) |
Ocr.SPEED_FASTEST |
ocr.Configuration.TesseractEngineMode チューニング |
Ocr.SPEED_FAST |
デフォルト設定 |
Ocr.SPEED_SLOW |
より高精度な設定 |
ocr.StopEngine() |
不要です。OcrInput は IDisposable |
result.StartsWith("ERROR:") チェック |
標準.NETの例外処理(try/catch) |
| プラットフォームネイティブDLL(aocr_x64.dll) | NuGetランタイムパッケージ(自動) |
| ストリーム入力用の手動一時ファイル | input.LoadImage(stream) 直接 |
| マルチフレームTIFF用の外部ライブラリ | input.LoadImageFrames(path) |
| 検索可能なPDF用の外部ライブラリ | result.SaveAsSearchablePdf(path) |
一般的な移行の問題と解決策
問題1:ネイティブバイナリを削除した後にDllNotFoundExceptionが発生する
Asprise OCR: Asprise NuGetパッケージを削除するが、プロジェクトファイルのコピー規則、Docker COPYインストラクション、またはデプロイメントスクリプト内にネイティブバイナリ参照を残しておくと、存在しないバイナリを指す過去の設定からDllNotFoundExceptionが再発する可能性があります。
解決策: デプロイメントアーティファクトを検索して、LD_LIBRARY_PATH設定が参照されている箇所を見つけ、それらを削除します。 IronOCRには、対応する設定要件はありません。 Dockerfile内:
# Remove: COPY aocr_x64.dll /app/
# Remove: ENV LD_LIBRARY_PATH=/app
# IronOCR: nothing to add — NuGet handles native runtime packaging
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish
クロスプラットフォーム展開の場合、 Docker展開ガイドでは、 Linuxコンテナ上のIronOCRの基本イメージ要件について説明しています。
課題2:Ocr.SetUp()の削除が失敗し、起動が失敗する
Asprise OCR: Ocr.SetUp()はグローバルなネイティブ初期化を実行します。 一部のコードベースでは、静的コンストラクタまたはStartup.Configureで呼び出されます。 移行後、Asprise名前空間を削除するとコンパイルエラーがなくなりますが、SetUp()が例外を抑制するtry/catchでラップされている場合、コードは何も初期化しないまま静かにコンパイルおよび実行される可能性があります。
解決策: すべてのSetUp()呼び出しをgrepし、初期化ブロック全体を削除します。 同等の起動フックをIronOCRライセンスキーの割り当てに置き換えてください。
grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
grep -rn "Ocr.SetUp\|StartEngine\|StopEngine" --include="*.cs" .
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();
// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
// Remove all occurrences of the engine lifecycle pattern:
// Ocr.SetUp();
// ocr.StartEngine(...);
// ocr.StopEngine();
// Replace application startup initialization with:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
問題3:XML出力解析コードには直接的な代替手段がない
Asprise OCR: XmlReader、または正規表現パターンを使用して解析するコードには、IronOCRの同等のXML構造がありません。 Aspriseが生成するXMLスキーマは、IronOCRのオブジェクトモデルに直接対応していません。
解決策: XML解析コードをOcrResultの直接プロパティアクセスに置き換えます。 マッピングは以下のとおりです。
// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
.Descendants("word")
.Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });
// IronOCR object model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
.SelectMany(p => p.Paragraphs)
.SelectMany(para => para.Words)
.Select(w => new { w.Text, w.X });
// Asprise XML parsing (remove)
var words = XDocument.Parse(xmlOutput)
.Descendants("word")
.Select(w => new { Text = (string)w.Attribute("text"), X = (int)w.Attribute("x") });
// IronOCR object model (replace with)
var result = new IronTesseract().Read(imagePath);
var words = result.Pages
.SelectMany(p => p.Paragraphs)
.SelectMany(para => para.Words)
.Select(w => new { w.Text, w.X });
Imports System.Xml.Linq
Imports IronOcr
' Asprise XML parsing (remove)
Dim words = XDocument.Parse(xmlOutput) _
.Descendants("word") _
.Select(Function(w) New With {Key .Text = CType(w.Attribute("text"), String), Key .X = CType(w.Attribute("x"), Integer)})
' IronOCR object model (replace with)
Dim result = New IronTesseract().Read(imagePath)
Dim words = result.Pages _
.SelectMany(Function(p) p.Paragraphs) _
.SelectMany(Function(para) para.Words) _
.Select(Function(w) New With {w.Text, w.X})
読み取り結果ガイドでは、バウンディングボックス付きの文字レベルデータを含む、オブジェクト階層全体を網羅しています。
問題4:Task.Runラッパーがスレッドプール枯渇を引き起こす
Asprise OCR: AspriseをTask.Runでラッピングした高並列性Webアプリケーションは、OCR負荷が急増した場合、スレッドプールを枯渇させる可能性があります。 キューに入れられたTask.Runごとに、OCR操作の全期間にわたってスレッドプールスレッドを保持します。
解決策: Task.Run(() => { asprise... を置き換えます。 })パターンは、ネイティブIronOCR の非同期呼び出しで使用されます。IronTesseract`インスタンスごとに独立しています。リクエストごとに1つ作成します:
// Remove: await Task.Run(() => { ocr.Recognize(...) });
// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
// Remove: await Task.Run(() => { ocr.Recognize(...) });
// Replace with:
using var input = new OcrInput();
input.LoadImage(stream);
var result = await new IronTesseract().ReadAsync(input);
return result.Text;
Imports IronTesseract
Using input As New OcrInput()
input.LoadImage(stream)
Dim result = Await (New IronTesseract()).ReadAsync(input)
Return result.Text
End Using
第5号:文字列ベースの言語コード検証
Asprise OCR: 言語コードは文字列として渡されます("eng+fra")。 これらの文字列を実行時に検証し、ハードコーディングされたリストに対してチェックし、設定から読み取るアプリケーションは、文字列形式がOcrLanguage enumに変わるときに更新が必要です。
解決策: 文字列言語パラメータをOcrLanguage enum値に置き換えます。 設定駆動の言語選択がEnum.Parseにきれいにマップされる:
// Asprise string-based (remove)
string language = config["OcrLanguage"]; // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);
// IronOCR enum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]); // e.g. "English"
var result = ocr.Read(input);
// Asprise string-based (remove)
string language = config["OcrLanguage"]; // e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST);
// IronOCR enum-based (replace with)
// For single language from config:
var ocr = new IronTesseract();
ocr.Language = Enum.Parse<OcrLanguage>(config["OcrLanguage"]); // e.g. "English"
var result = ocr.Read(input);
' Asprise string-based (remove)
Dim language As String = config("OcrLanguage") ' e.g. "eng+fra"
ocr.StartEngine(language, Ocr.SPEED_FAST)
' IronOCR enum-based (replace with)
' For single language from config:
Dim ocr As New IronTesseract()
ocr.Language = [Enum].Parse(Of OcrLanguage)(config("OcrLanguage")) ' e.g. "English"
Dim result = ocr.Read(input)
多言語ガイドには、すべての有効なOcrLanguage enum値とそれに対応するNuGet言語パックパッケージがリストされています。
問題6:ライセンス階層チェックロジックは不要になりました
Asprise OCR:一部の製品版コードベースには、Aspriseライセンスレベルを検出し、 Enterprise未満のレベルで実行されている場合にOCR処理をシリアル化するランタイムチェックが含まれています。これらの対策はライセンス違反を防ぎますが、複雑さが増し、スループットが低下します。
解決策:階層検出およびシリアル化ガードをすべて削除します。 IronOCRは、どのティアにおいてもスレッドに関する制限を設けていません。 Asprise呼び出しを直列化するために使用されるSemaphoreSlim、またはシングルスレッドディスパッチャパターンは、移行後には必要ありません:
// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();
// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
var text = new IronTesseract().Read(path).Text;
results[path] = text;
});
// Remove: SemaphoreSlim _ocrLock = new SemaphoreSlim(1, 1);
// Remove: await _ocrLock.WaitAsync(); ... _ocrLock.Release();
// IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, path =>
{
var text = new IronTesseract().Read(path).Text;
results[path] = text;
});
Imports System.Threading.Tasks
' IronOCR: direct concurrent access, no guards needed
Parallel.ForEach(documentPaths, Sub(path)
Dim text = (New IronTesseract()).Read(path).Text
results(path) = text
End Sub)
Asprise OCR移行チェックリスト
移行前
代替コードを作成する前に、コードベース全体を監査して、Aspriseの使用状況をすべて確認してください。
# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .
# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .
# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .
# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .
# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .
# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
# Find all files importing asprise namespace
grep -rn "using asprise" --include="*.cs" .
# Find all engine lifecycle calls
grep -rn "SetUp\|StartEngine\|StopEngine" --include="*.cs" .
# Find all integer constant references
grep -rn "RECOGNIZE_TYPE\|OUTPUT_FORMAT\|SPEED_FAST\|SPEED_SLOW" --include="*.cs" .
# Find native binary references in project files and deployment scripts
grep -rn "aocr\|libaocr" --include="*.csproj" --include="Dockerfile" --include="*.yml" .
# Find XML output parsing code
grep -rn "OUTPUT_FORMAT_XML\|XDocument.Parse\|Descendants.*word" --include="*.cs" .
# Find Task.Run wrappers around OCR calls
grep -rn "Task.Run.*ocr\|Task.Run.*Recognize" --include="*.cs" .
結果を一覧する:
asprise.ocrをインポートしているファイルの数をカウントします 。これらはすべて名前空間の更新が必要ですRead呼び出しになります- XML出力解析コードを特定する — 各ブロックはオブジェクトモデルの置き換えが必要
- ライセンス階層ガードやシリアル化ラッパーに注意してください。これらは削除可能です。
- ネイティブバイナリのデプロイスクリプトとコンテナ構成を見つける
コードの移行
- すべてのプロジェクトから
asprise-ocr-apiNuGetパッケージを削除します - OCRを実行する各プロジェクトに
IronOcrNuGetパッケージをインストールします - すべてのファイルで
using IronOcrに置き換えます - アプリケーション起動時に
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"を追加する - すべてのスタートアップおよび初期化コードから
Ocr.SetUp()呼び出しを削除します - すべての
Ocr.StartEngine/Recognize/new IronTesseract().Read(path).Textで置き換えます result.Pagesオブジェクトトラバーサルで置き換えますresult.SaveAsSearchablePdf(path)で置き換えます- マルチフレームTIFF分割コードを
input.LoadImageFrames(tiffPath)で置き換えます - ストリームベースの
await ocr.ReadAsync(input)で置き換えます - 同時使用からAspriseを保護する
SemaphoreSlimまたはシリアライゼーションガードを削除します .csprojファイルとDockerfileからネイティブバイナリコピー指示を削除します- 環境設定およびCIスクリプトから
LD_LIBRARY_PATH設定を削除します - 文字列言語コード(
OcrLanguageenum値で置き換えます try/catchブロックで置き換えます
移行後
dotnet buildがネイティブライブラリの欠如に関する警告ゼロで完了したことを確認します- すべてのターゲット環境(Windows、Linux、Docker)で起動時に
BadImageFormatExceptionが発生していないことを確認します 代表的な画像に対してOCRを実行し、テキスト出力が移行前の基準値と一致することを確認する。 - マルチフレームTIFF処理をテストし、すべてのページが正しいページ番号で返されることを確認します。 検索可能なPDFを生成し、PDFビューアでテキストが選択可能かつ検索可能であることを確認します。 OCRを呼び出す任意のAPIエンドポイントに同時HTTPリクエストを送信し、すべてのリクエストがエラーなく完了したことを確認します。
- 同時負荷時でも非同期エンドポイントがデッドロックを起こさずに結果を返すことを検証する
- 構造化データ抽出(単語座標と信頼度)が既知の文書に対して正しい出力を生成することを確認する
- アプリケーションのメモリ使用量を時間経過とともに確認し、(以前は見逃された
StopEngine()呼び出しが原因で発生していた)ネイティブメモリリークがないことを確認します - Linux 環境または Docker コンテナ内でアプリケーションを実行し、バイナリ構成なしでクロスプラットフォーム展開が機能することを確認します。
IronOCRへの移行の主なメリット
デプロイメントは単一のNuGetパッケージ参照に集約されます。移行後、開発ワークステーション、ステージングサーバー、Linux コンテナ、CI エージェントなど、すべてのデプロイメント対象で同じパッケージが同じコマンドでインストールされます。 プラットフォーム検出ロジックも、アーキテクチャ固有のバイナリソースも、ランタイムパス構成もありません。 以前は手動のネイティブバイナリCOPY指示が必要だったDockerイメージは、今やdotnet restore以上の何も必要としません。 Linux デプロイガイドとAzure デプロイガイドには、該当する場合に環境固有の注意事項が記載されています。
すべてのライセンスティアがサーバーグレードのデプロイをアンロックします。 $999Liteライセンスは、ASP.NET Core Web API、Windows Services、Azure Functions、AWS Lambda、および他の任意のマルチスレッド.NETワークロードをサポートします。 Aspriseが2,000ドルから5,000ドル以上を請求するエンタープライズレベルのスレッディング機能は、 IronOCRのすべてのプランに含まれています。 Asprise EnterpriseからIronOCR Liteに移行するチームは、OCRライセンス費用を削減できるだけでなく、 Enterpriseでは提供されていなかったネイティブPDF、構造化出力、検索可能なPDF生成、125言語への対応といった機能を利用できるようになります。
構造化OCR結果がXML文字列解析に取って代わります。 OcrResultオブジェクトモデルは、完全なドキュメント階層を公開します:ページ、段落、行、単語、文字、それぞれがピクセル精度のバウンディングボックス座標と信頼スコアを持っています。 以前はXDocumentまたは正規表現を使用してAsprise XML文字列を解析していたコードが、プロパティへの直接アクセスに切り替わります。 OCR結果機能ページでは、座標系と、自動品質ゲートにおける信頼度による結果のフィルタリング方法について説明しています。
組み込みの前処理によって外部イメージング依存が除去されます。 OcrInputを通じて利用可能な前処理パイプライン — DeepCleanBackgroundNoise — により、Asprise統合が要求する外部イメージングライブラリが排除されます。この依存が除かれることでライセンスの懸念を取り除き、ビルドフットプリントが軽減され、前処理設定がOCR設定のすぐ隣に配置されます。前処理機能ページおよび画像品質補正ガイドは、各フィルターをどのように適用するか、低品質スキャンでどの程度の精度向上が得られるかをカバーしています。
ネイティブ非同期と真の並列性がスループットを改善します。 async/awaitパターンに統合します。 Parallel.ForEachまたはPLINQを使用した並列バッチ処理は、利用可能なコアに応じて線形にスケールします。 Asprise Lite/STANDARD が強制的に順次実行させた文書バッチ (100 文書をそれぞれ 2 秒で処理し、3 分以上かかる) は、 IronOCRを搭載した 8 コアのマシンでは約 25 秒で実行されます。 マルチスレッド例は、並列スループットパターンを示し、スレッドセーフな結果収集にConcurrentBagを使用する方法を示します。
125以上の言語がバイナリ配布なしで利用可能です。 言語パックはNuGetパッケージとしてインストールされます—dotnet add package IronOcr.Languages.Japanese—およびアプリケーションとともに他のどの依存とも同じようにデプロイされます。 手動でtessdataフォルダを作成する必要も、言語バイナリを探す必要も、対象マシン上でパスを設定する必要もありません。言語インデックスには、利用可能な125以上の言語パックがすべて一覧表示されます。
よくある質問
なぜAsprise OCR SDKからIronOCRに移行する必要があるのですか?
一般的な推進要因には、COM相互接続の複雑さの解消、ファイルベースのライセンス管理の置き換え、ページ単位の課金の回避、Docker/コンテナデプロイの有効化、標準的な.NETツールと統合するNuGetネイティブワークフローの採用などがあります。
Asprise OCR SDKからIronOCRに移行する際の主なコード変更は何ですか?
Asprise OCRの初期化シーケンスをIronTesseractのインスタンス化に置き換え、COMのライフサイクル管理(明示的なCreate/Load/Closeパターン)を削除し、結果のプロパティ名を更新します。その結果、定型的な行が大幅に減りました。
IronOCRをインストールして移行を開始するにはどうすればいいですか?
パッケージマネージャーコンソールで'Install-Package IronOcr'を実行するか、CLIで'dotnet add package IronOcr'を実行してください。言語パックは別のパッケージです:例えばフランス語の場合は'dotnet add package IronOcr.Languages.French'となります。
IronOCRは標準的なビジネス文書のAsprise OCR SDKのOCR精度に匹敵しますか?
IronOCRは、請求書、契約書、領収書、入力フォームなどの標準的なビジネスコンテンツで高い精度を達成しています。画像前処理フィルター(傾き補正、ノイズ除去、コントラスト強調)により、劣化した入力の認識をさらに向上させます。
IronOCR はAsprise OCR SDKが別途インストールする言語データをどのように扱うのですか?
IronOCRの言語データはNuGetパッケージとして配布されます。'dotnet add package IronOcr.Languages.German'でドイツ語のサポートがインストールされます。手動でのファイル配置やディレクトリパスは必要ありません。
Asprise OCR SDKからIronOCRに移行する際、導入インフラの変更は必要ですか?
IronOCRはAsprise OCR SDKよりもインフラストラクチャの変更が少なくて済みます。SDKのバイナリパス、ライセンスファイルの配置、ライセンスサーバーの設定は必要ありません。NuGetパッケージには完全なOCRエンジンが含まれており、ライセンスキーはアプリケーションコードに設定された文字列です。
移行後のIronOCRライセンスの設定方法は?
アプリケーションの起動コードでIronOcr.License.LicenseKey = "YOUR-KEY "を割り当てます。DockerまたはKubernetesでは、キーを環境変数として保存し、スタートアップで読み込む。License.IsValidLicenseを使用して、トラフィックを受け入れる前にバリデーションを行う。
IronOCRはAsprise OCRと同じようにPDFを処理できますか?
IronOCRはネイティブPDFもスキャンしたPDFも読み取ります。IronTesseractをインスタンス化し、ocr.Read(input)を呼び出し、入力はPDFパスまたはOcrPdfInputであり、OcrResultページを反復します。別のPDFレンダリングパイプラインは必要ありません。
IronOCRはどのように大量処理のスレッディングを処理するのですか?
IronTesseractはスレッド毎にインスタンス化しても安全です。Parallel.ForEachまたはタスクプールでスレッドごとにインスタンスを1つスピンアップし、OCRを同時に実行し、完了したら各インスタンスを破棄します。グローバルステートやロックは必要ありません。
IronOCRはテキスト抽出後、どのような出力形式をサポートしていますか?
IronOCRはテキスト、単語座標、信頼度スコア、ページ構造を含む構造化された結果を返します。エクスポートオプションには、プレーンテキスト、検索可能なPDF、下流処理用の構造化結果オブジェクトが含まれます。
IronOCRの価格はAsprise OCR SDKよりもワークロードのスケーリングが予測できますか?
IronOCRは、定額制の永久ライセンスを採用しており、ページ単位やボリューム単位の料金はかかりません。10,000ページでも1,000万ページでも、ライセンスコストは一定です。ボリュームライセンスとチームライセンスのオプションはIronOCRの価格ページをご覧ください。
Asprise OCR SDKからIronOCRに移行した後、既存のテストはどうなりますか?
抽出されたテキストコンテンツをアサートするテストは、移行後もパスし続ける必要があります。APIコールパターンやCOMオブジェクトのライフサイクルを検証するテストは、IronOCRのシンプルな初期化と結果モデルを反映するように更新する必要があります。

