
IronOCR対 AWS Textract: スタートアップ向け OCR ソリューション
GdPicture.NETはOCRプラグインに1ドルを払う前にコアライセンスが必要であり、PDFを読み取ったり、検索可能な出力を作成したりする場合、追加のPDFプラグインも必要です。 現在の価格はGdPictureにお問い合わせください。 画像やPDFからテキストを抽出する必要があるチームの場合、複数のプラグインの合算コストと年間保守料金はかなりの額になる可能性があります。 課金はGdPictureのアーキテクチャに起因するものです。GdPictureはスキャン、DICOM、注釈、バーコード処理、PDF編集などを含む包括的なドキュメントイメージングプラットフォームであり、OCRはその数あるプラグインの一つに過ぎません。 OCRのみを必要とするチームは、決して完全には使用しないドキュメント画像処理SDK全体のコストを負担することになる。
APIも同じ理念を反映している。 GdPictureはメモリ内のリソースを追跡するために整数の画像IDを使用します。ロードするたびにintを返し、その整数ハンドルに対してメソッドを呼び出し、明示的にリリースするかメモリリークを受け入れなければなりません。 このパターンはusing文よりも前に存在しました。 機能はするものの、毎回、クリーンアップに関するあらゆる判断を開発者に委ねることになる。本比較では、プラグインベースの価格設定と画像IDのライフサイクルという2つの課題に加え、APIの複雑さ、前処理、PDF処理についても、 IronOCRを対照として検証する。
.NETについて理解する
GdPicture .NETは、ORPALIS社が開発した商用ドキュメントイメージングSDKです。 長年にわたり開発が重ねられ、画像処理、PDFの作成と編集、バーコードの読み取りと生成、TWAIN/WIAスキャナーとの統合、DICOM医用画像処理、注釈とレビューのワークフロー、そしてPDF/A準拠の文書アーカイブなど、幅広い機能を網羅するプラットフォームへと成長しました。 OCRはこのエコシステムにおける機能の一つであり、専用プラグインを通じて提供されます。
SDKは、機能を個別のモジュールに整理しており、各モジュールには独自のプライマリクラスがあります。
- GdPictureImaging - 画像の読み込み、処理、フォーマット変換、およびすべての整数画像IDのソース
- GdPicturePDF - PDFの作成、編集、レンダリング、およびページレベルのOCR操作(別途プラグインライセンスが必要)
- GdPictureOCR - テキスト認識および抽出; GdPictureImagingによって生成された画像IDを消費します
- GdPicture1DBarcode / GdPicture2DBarcode - リニアバーコードおよび2次元バーコードの読み取りと書き込み(プラグインライセンスは別売)
- GdPictureDocumentImaging - 傾き補正、ノイズ除去、境界線除去、パンチ穴除去などの高度なドキュメントクリーンアップフィルター(別売プラグイン)
- GdPictureAnnotations - 文書のマークアップ、レビュー、編集
基本的なOCRでさえ、画像をロードするためのGdPictureOCRの2つのコンポーネントを初期化し、そのライフサイクルを管理する必要があります。 PDFからのOCRには3つ目の@Component: GdPicturePDFが必要です。 名前空間自体にバージョン番号(GdPicture14)が含まれているため、すべての大規模なSDKアップグレードはコードベース全体での検索と置換を強制します。
一般的なOCRシナリオにおけるプラグインの依存関係ツリーは次のようになります。
| 必要であれば | ライセンスが必要です |
|---|---|
| 画像からのOCR | 基本ライセンス + OCRプラグイン |
| PDFからのOCR | 基本パッケージ + OCRプラグイン + PDFプラグイン |
| 検索可能なPDF出力 | 基本パッケージ + OCRプラグイン + PDFプラグイン |
| OCR処理前の文書のクリーンアップ | 基本パッケージ + OCRプラグイン + ドキュメントイメージングプラグイン |
画像IDライフサイクル
GdPictureの決定的なアーキテクチャ上の特徴は、整数型画像ID管理である。 画像をロードすることは、GdPictureランタイム内にメモリを割り当て、intハンドルを返すことを意味します。 その整数値を使用して、以降のすべての呼び出しで画像を参照します。 終了したら、その整数でReleaseGdPictureImageを呼び出します。 そうしないと、プロセスが終了するまでメモリは解放されません。
using GdPicture14;
// Every image load returns an integer handle
int imageId = _imaging.CreateGdPictureImageFromFile(imagePath);
if (imageId == 0)
{
throw new Exception($"Failed to load image: {_imaging.GetStat()}");
}
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId))
{
throw new Exception($"OCR failed: {_ocr.GetStat()}");
}
return _ocr.GetOCRResultText(resultId);
}
finally
{
// CRITICAL: omitting this line causes a memory leak
_imaging.ReleaseGdPictureImage(imageId);
}Imports GdPicture14
' Every image load returns an integer handle
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(imagePath)
If imageId = 0 Then
Throw New Exception($"Failed to load image: {_imaging.GetStat()}")
End If
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then
Throw New Exception($"OCR failed: {_ocr.GetStat()}")
End If
Return _ocr.GetOCRResultText(resultId)
Finally
' CRITICAL: omitting this line causes a memory leak
_imaging.ReleaseGdPictureImage(imageId)
End TryImports GdPicture14
' Every image load returns an integer handle
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(imagePath)
If imageId = 0 Then
Throw New Exception($"Failed to load image: {_imaging.GetStat()}")
End If
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then
Throw New Exception($"OCR failed: {_ocr.GetStat()}")
End If
Return _ocr.GetOCRResultText(resultId)
Finally
' CRITICAL: omitting this line causes a memory leak
_imaging.ReleaseGdPictureImage(imageId)
End Try複数ページのPDFを処理する場合、レンダリングされた各ページには個別の画像IDが生成されます。 200 DPIの100ページ文書は、クリーンアップを怠ると1~5GBのメモリを消費する可能性があります。 正しいパターンはすべてのIDを収集し、開発者の責任としてfinallyブロック内でそれらを解放することを要求します。
IronOCRを理解する
IronOCRは、単一のNuGetパッケージとして構築された、 .NET向けの商用OCRライブラリです。 その設計目標は、構成のオーバーヘッドなしでの正確性です。パッケージをインストールし、ライセンスキーを設定し、Readを呼び出します。 このライブラリは、最適化されたTesseract 5エンジンをラップし、自動前処理、ネイティブPDF処理、構造化された結果アクセスといった機能をすべて標準的な.NETパターンを通じて提供します。
主な特徴:
- 単一のNuGetパッケージ -
dotnet add package IronOcrは英語の言語サポートを含むすべてをインストールします; 外部リソースフォルダなし、ネイティブバイナリ管理なし - 標準 for .NETリソース管理 -
IDisposableを実装します;using文はすべてのクリーンアップを例外に関係なく処理します - 自動前処理 - Deskew、DeNoise、Contrast、Binarize、およびEnhanceResolutionは、
OcrInputでの一行メソッド呼び出しです; このエンジンは、明示的な指示なしに自動修正も行います。 - ネイティブPDF入力 - スキャンしたPDFとネイティブPDFの両方が、別々のレンダリングステップなしで
IronTesseract.Readに直接供給されます - 設計上のスレッドセーフ - 単一の
IronTesseractインスタンスが同時要求を処理;Parallel.ForEachは追加の同期なしで動作します - 125以上の言語 - 別々のNuGetパッケージ(
IronOcr.Languages.Frenchなど)として配布され、管理するtessdataフォルダはありません - 構造化された結果のアクセス -
.Barcodesを座標データ付きの型付けされたコレクションとして公開します
価格設定は永久です: $999 Lite、$1,499 Plus、$2,999 Professional、$5,999 Unlimited。 すべての機能はどのプランでも利用可能です。 違いは、対象となる開発者とプロジェクトの数です。
機能比較
| フィーチャー | GdPicture.NET | IronOCR |
|---|---|---|
| 価格設定モデル | プラグインベースの永久ライセンス + 年間メンテナンス料20% | 定額永久プラン、年間更新オプションあり |
| 入場料(PDFからのOCR) | 複数のプラグインが必要 (価格についてはGdPictureにお問い合わせください) | $2,999(1つのパッケージですべての機能) |
| リソース管理 | 手動整数ID追跡とリリース | IDisposable / using 文 |
| 名前空間の安定性 | 名前空間のバージョン番号(GdPicture14) | バージョンに依存しない(IronOcr) |
| PDF OCR。 | 別途PDFプラグインが必要です | 組み込み済み、追加ライセンス不要 |
| インストール。 | 複数のNuGetパッケージと外部リソースフォルダ | NuGetパッケージ1つ、外部ファイルなし |
| クロスプラットフォーム | Windows、Linux、macOS | Windows、Linux、macOS、Docker、AWS、Azure |
詳細な機能比較
| フィーチャー | GdPicture.NET | IronOCR |
|---|---|---|
| セットアップとインストール | ||
| NuGetのインストール | 複数のパッケージが必要です | dotnet add package IronOcr |
| 外部リソースフォルダ | 必須(tessdata形式の言語ファイル) | 必須ではありません(同梱されています) |
| ライセンス認証 | LicenseManager.RegisterKEY() | IronOcr.License.LicenseKey = "..." |
| コンポーネントの初期化 | PDF OCRワークフローのための3~4クラス | new IronTesseract() |
| メジャーアップグレード時の名前空間 | すべてのソースファイルを更新する必要があります | 変更は不要です |
| OCR機能 | ||
| 画像OCR | はい | はい |
| PDF OCR | はい(PDFプラグインが必要です) | はい(内蔵) |
| パスワードで保護されたPDF | はい | はい |
| 複数ページPDF | 手動ページループ + ID クリーンアップ | 自動翻訳 |
| 検索可能なPDF出力 | OcrPage + SaveToFile | result.SaveAsSearchablePdf() |
| hOCRエクスポート | なし | はい |
| 前処理 | ||
| デスキュー | GdPictureDocumentImagingプラグイン経由 | input.Deskew() |
| ノイズ除去 | GdPictureDocumentImagingプラグイン経由 | input.DeNoise() |
| コントラスト強調 | GdPictureImaging経由 | input.Contrast() |
| 二値化 | GdPictureImaging経由 | input.Binarize() |
| DPIの向上 | GdPictureImaging経由 | input.EnhanceResolution(300) |
| 自動修正(コードなし) | なし | はい(読み取り機能に組み込まれています) |
| リソース管理。 | ||
| メモリ管理モデル | 手動整数ID追跡 | IDisposable / GC |
| メモリリークのリスク | 高(ReleaseGdPictureImageが欠落しています) | なし(usingステートメント) |
| スレッドセーフティ | 手動インスタンス管理 | スレッドセーフ設計 |
| 結果とデータ | ||
| プレーンテキスト | GetOCRResultText(resultId) | result.Text |
| 信頼度スコア | GetOCRResultConfidence(resultId) | result.Confidence |
| 単語レベルのデータ | ネストされたブロック/行/単語の反復 | result.Words コレクション |
| アクセスを調整する | ブロック/行/単語インデックス呼び出し経由 | 直接.Height |
| OCR中のバーコード読み取り | 別個のバーコードプラグイン経由 | ocr.Configuration.ReadBarCodes = true |
| 言語 | ||
| 言語数 | Tesseract ベース、同様のカバレッジ | NuGetパッケージ経由で125以上 |
| 言語分布 | リソースフォルダファイル | NuGetパッケージ |
| 一度の処理で多言語対応 | はい | はい(AddSecondaryLanguage) |
| デプロイメント | ||
| Docker | サポート対象 | サポート対象(ドキュメントあり) |
| Linux | サポート対象 | サポート対象 |
| AWSラムダ | 可能 | ドキュメント付きガイド |
| Azure App Service | 可能 | ドキュメント付きガイド |
画像IDライフサイクルと使い捨てOCR入力の比較
GdPictureとIronOCRの最も重要なアーキテクチャ上の違いは、機能の差ではなく、それぞれのライブラリが処理する画像のメモリをどのように扱うかという点にある。
GdPictureアプローチ
GdPicture内のすべての画像は、ランタイム管理プール内の整数ハンドルとして存在します。 画像を読み込むことでハンドルを取得し、その整数値をOCRなどの処理に渡して、処理が完了したらハンドルを解放します。 そのパターンは明確であり、従えば正しい。 問題は、間違えやすく、その結果としてメモリ使用量が際限なく増加してしまうことだ。
PDF OCRのワークフローは、そのリスクを最も明確に示している。 pdf.RenderPageToGdPictureImage() への各呼び出しは、メモリに新しいラスタ画像を割り当て、新しい整数IDを返します。 100ページの文書は、100個の個別の割り当てを作成する。 1つのReleaseGdPictureImage呼び出しを逃すと、プロセスは漏出したメモリを蓄積します:
using GdPicture14;
public string ExtractTextFromPdf(string pdfPath)
{
var text = new StringBuilder();
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(pdfPath, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Failed to load PDF: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// Each page render = new memory allocation + new integer ID
int imageId = pdf.RenderPageToGdPictureImage(200, false);
if (imageId == 0) continue;
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (!string.IsNullOrEmpty(resultId))
text.AppendLine(_ocr.GetOCRResultText(resultId));
}
finally
{
// Without this: ~10–50MB leaked per page
_imaging.ReleaseGdPictureImage(imageId);
}
}
return text.ToString();
}using GdPicture14;
public string ExtractTextFromPdf(string pdfPath)
{
var text = new StringBuilder();
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(pdfPath, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Failed to load PDF: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// Each page render = new memory allocation + new integer ID
int imageId = pdf.RenderPageToGdPictureImage(200, false);
if (imageId == 0) continue;
try
{
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (!string.IsNullOrEmpty(resultId))
text.AppendLine(_ocr.GetOCRResultText(resultId));
}
finally
{
// Without this: ~10–50MB leaked per page
_imaging.ReleaseGdPictureImage(imageId);
}
}
return text.ToString();
}Imports GdPicture14
Imports System.Text
Public Function ExtractTextFromPdf(ByVal pdfPath As String) As String
Dim text As New StringBuilder()
Using pdf As New GdPicturePDF()
Dim status As GdPictureStatus = pdf.LoadFromFile(pdfPath, False)
If status <> GdPictureStatus.OK Then
Throw New Exception($"Failed to load PDF: {status}")
End If
Dim pageCount As Integer = pdf.GetPageCount()
For i As Integer = 1 To pageCount
pdf.SelectPage(i)
' Each page render = new memory allocation + new integer ID
Dim imageId As Integer = pdf.RenderPageToGdPictureImage(200, False)
If imageId = 0 Then Continue For
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If Not String.IsNullOrEmpty(resultId) Then
text.AppendLine(_ocr.GetOCRResultText(resultId))
End If
Finally
' Without this: ~10–50MB leaked per page
_imaging.ReleaseGdPictureImage(imageId)
End Try
Next
End Using
Return text.ToString()
End FunctionImports GdPicture14
Imports System.Text
Public Function ExtractTextFromPdf(ByVal pdfPath As String) As String
Dim text As New StringBuilder()
Using pdf As New GdPicturePDF()
Dim status As GdPictureStatus = pdf.LoadFromFile(pdfPath, False)
If status <> GdPictureStatus.OK Then
Throw New Exception($"Failed to load PDF: {status}")
End If
Dim pageCount As Integer = pdf.GetPageCount()
For i As Integer = 1 To pageCount
pdf.SelectPage(i)
' Each page render = new memory allocation + new integer ID
Dim imageId As Integer = pdf.RenderPageToGdPictureImage(200, False)
If imageId = 0 Then Continue For
Try
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If Not String.IsNullOrEmpty(resultId) Then
text.AppendLine(_ocr.GetOCRResultText(resultId))
End If
Finally
' Without this: ~10–50MB leaked per page
_imaging.ReleaseGdPictureImage(imageId)
End Try
Next
End Using
Return text.ToString()
End Function複数のPDFファイルに対するバッチ処理は、この問題をさらに悪化させる。 それぞれのfinallyでそれらをすべて解放することをリマインドするメモを持たなければなりません。 それはインフラ整備作業であって、OCR作業ではない。
IronOCRのアプローチ
OcrInput は標準のIDisposable です。 using文は、メソッドが通常に戻るか、例外を投げるかに関係なくクリーンアップを保証します。 追跡すべき整数IDはなく、初期化すべき個別の画像処理コンポーネントもなく、PDFページ用の外部DPIレンダリング手順もありません。
using IronOcr;
public string ExtractTextFromPdf(string pdfPath)
{
// LoadPdf handles page rendering internally
using var input = new OcrInput();
input.LoadPdf(pdfPath);
var result = new IronTesseract().Read(input);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
return result.Text;
// using block exits — all internal resources released automatically
}using IronOcr;
public string ExtractTextFromPdf(string pdfPath)
{
// LoadPdf handles page rendering internally
using var input = new OcrInput();
input.LoadPdf(pdfPath);
var result = new IronTesseract().Read(input);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text}");
return result.Text;
// using block exits — all internal resources released automatically
}Imports IronOcr
Public Function ExtractTextFromPdf(pdfPath As String) As String
' LoadPdf handles page rendering internally
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Dim result = New IronTesseract().Read(input)
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
Next
Return result.Text
' using block exits — all internal resources released automatically
End Using
End FunctionImports IronOcr
Public Function ExtractTextFromPdf(pdfPath As String) As String
' LoadPdf handles page rendering internally
Using input As New OcrInput()
input.LoadPdf(pdfPath)
Dim result = New IronTesseract().Read(input)
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text}")
Next
Return result.Text
' using block exits — all internal resources released automatically
End Using
End Functionパスワードで保護されたPDFの場合、パラメータは追加のステータスチェックを必要とする別のオーバーロードではなく、名前付き引数になります。
using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf("searchable-output.pdf");using var input = new OcrInput();
input.LoadPdf("encrypted.pdf", Password: "secret");
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf("searchable-output.pdf");Imports IronOcr
Using input As New OcrInput()
input.LoadPdf("encrypted.pdf", Password:="secret")
Dim result = New IronTesseract().Read(input)
result.SaveAsSearchablePdf("searchable-output.pdf")
End UsingImports IronOcr
Using input As New OcrInput()
input.LoadPdf("encrypted.pdf", Password:="secret")
Dim result = New IronTesseract().Read(input)
result.SaveAsSearchablePdf("searchable-output.pdf")
End UsingIronOCRのPDF入力ガイドには、ページ範囲の選択など、その他のオプションについても記載されています。 Entity Framework、HttpClient、ストリーム処理全般でのOcrInputは新しい精神モデルを必要としません。
プラグインバンドルのコスト
画像とPDFからテキストを抽出し、検索可能な出力を生成するサーバーアプリケーションの場合、GdPictureライセンススタックには複数のプラグインが必要です。 プロフェッショナルのコアライセンス、OCRプラグイン、PDFプラグインの現在の価格はGdPictureにお問い合わせください。 毎年の保守料は(通常はライセンスの総費用の割合)年を重ねるごとに積み重なります。
IronOCR Professionalは、同じワークフローを単一のパッケージでカバーします。
IronOCR Professional: $professionalLicense (one-time)
オプションの年次アップデート: $plusLicense/年
3年間の合計(永続、アップデートなし): $professionalLicense
アップデートの好みによっては、複数年のコスト差が大きくなる可能性があります。 そのギャップが存在するのは、GdPictureのプラグインモデルが、OCRに特化したワークロードではなく、フル機能のドキュメントイメージングプラットフォーム向けに価格設定されているためである。 OCRプラグインは、最適なOCR入力形式を使用可能にするPDFプラグインの前に必要です。
OCR向けにGdPictureを評価するチームは、OCRに特化したバックログにはめったに見られない機能、例えばTWAIN/WIAスキャナーとの統合、DICOM医療画像処理、注釈および墨消しワークフロー、テキスト抽出にとどまらない高度なPDF編集機能などに対して料金を支払っている。 IronOCRライセンスページを参照して、すべての機能が各層で利用可能な価格モデルを確認してください - プラグインなし、アドオンなし、機能ごとのライセンス意思決定はありません。
APIの複雑さと前処理
GdPictureはGdPictureDocumentImagingプラグイン(傾き補正、スポット削除、ボーダー除去)として公開します。 OCR処理の前に傾き補正を適用するには、ドキュメントイメージングプラグインのライセンスが必要となるため、品質の異なるスキャン文書を処理するワークフローにおいて、3つ目のコストが発生することになる。
GdPictureアプローチ
低品質のスキャン済みPDFの処理ワークフロー全体(読み込み、前処理、各ページのOCR処理、リリース)は3つの構成要素にまたがり、各ステップで慎重なステータスチェックが必要です。
using GdPicture14;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(inputPdf, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Load failed: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// OcrPage adds text layer to each page
// Requires: OCR plugin + PDF plugin + resource folder path
GdPictureStatus ocrStatus = pdf.OcrPage(
"eng",
@"C:\GdPicture\Resources\OCR", // 外部リソースフォルダ required
"",
200
);
if (ocrStatus != GdPictureStatus.OK)
Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}");
}
pdf.SaveToFile(outputPdf, true);
}using GdPicture14;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
using var pdf = new GdPicturePDF();
GdPictureStatus status = pdf.LoadFromFile(inputPdf, false);
if (status != GdPictureStatus.OK)
throw new Exception($"Load failed: {status}");
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
// OcrPage adds text layer to each page
// Requires: OCR plugin + PDF plugin + resource folder path
GdPictureStatus ocrStatus = pdf.OcrPage(
"eng",
@"C:\GdPicture\Resources\OCR", // 外部リソースフォルダ required
"",
200
);
if (ocrStatus != GdPictureStatus.OK)
Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}");
}
pdf.SaveToFile(outputPdf, true);
}Imports GdPicture14
Public Sub CreateSearchablePdf(ByVal inputPdf As String, ByVal outputPdf As String)
Using pdf = New GdPicturePDF()
Dim status As GdPictureStatus = pdf.LoadFromFile(inputPdf, False)
If status <> GdPictureStatus.OK Then
Throw New Exception($"Load failed: {status}")
End If
Dim pageCount As Integer = pdf.GetPageCount()
For i As Integer = 1 To pageCount
pdf.SelectPage(i)
' OcrPage adds text layer to each page
' Requires: OCR plugin + PDF plugin + resource folder path
Dim ocrStatus As GdPictureStatus = pdf.OcrPage(
"eng",
"C:\GdPicture\Resources\OCR", ' 外部リソースフォルダ required
"",
200
)
If ocrStatus <> GdPictureStatus.OK Then
Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}")
End If
Next
pdf.SaveToFile(outputPdf, True)
End Using
End SubImports GdPicture14
Public Sub CreateSearchablePdf(ByVal inputPdf As String, ByVal outputPdf As String)
Using pdf = New GdPicturePDF()
Dim status As GdPictureStatus = pdf.LoadFromFile(inputPdf, False)
If status <> GdPictureStatus.OK Then
Throw New Exception($"Load failed: {status}")
End If
Dim pageCount As Integer = pdf.GetPageCount()
For i As Integer = 1 To pageCount
pdf.SelectPage(i)
' OcrPage adds text layer to each page
' Requires: OCR plugin + PDF plugin + resource folder path
Dim ocrStatus As GdPictureStatus = pdf.OcrPage(
"eng",
"C:\GdPicture\Resources\OCR", ' 外部リソースフォルダ required
"",
200
)
If ocrStatus <> GdPictureStatus.OK Then
Console.WriteLine($"Warning: Page {i} OCR failed: {ocrStatus}")
End If
Next
pdf.SaveToFile(outputPdf, True)
End Using
End SubResourceFolderパスは任意ではありません。 実行時に.traineddata 言語ファイルを含むディレクトリに解決する必要があります。このパスは開発マシンで機能し、サービスアカウントがC:\GdPicture\Resources\OCRを見ることができない場合や、アプリケーションがLinuxにデプロイされる場合、またはDockerイメージにそのディレクトリ構造が含まれていない場合は本番環境で失敗します。 これらの失敗をデバッグすることは、根本原因についてほとんど言及しない一般的なGdPictureStatusエラーコードを追跡することをしばしば意味します。
IronOCRのアプローチ
IronOCRにおける同等のワークフロー(傾き補正とノイズ除去の前処理を含む)は、わずか5行です。
using IronOcr;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(inputPdf);
input.Deskew(); // なし separate plugin required
input.DeNoise();
var result = ocr.Read(input);
result.SaveAsSearchablePdf(outputPdf);
}using IronOcr;
public void CreateSearchablePdf(string inputPdf, string outputPdf)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(inputPdf);
input.Deskew(); // なし separate plugin required
input.DeNoise();
var result = ocr.Read(input);
result.SaveAsSearchablePdf(outputPdf);
}Imports IronOcr
Public Sub CreateSearchablePdf(inputPdf As String, outputPdf As String)
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadPdf(inputPdf)
input.Deskew() ' なし separate plugin required
input.DeNoise()
Dim result = ocr.Read(input)
result.SaveAsSearchablePdf(outputPdf)
End Using
End SubImports IronOcr
Public Sub CreateSearchablePdf(inputPdf As String, outputPdf As String)
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.LoadPdf(inputPdf)
input.Deskew() ' なし separate plugin required
input.DeNoise()
Dim result = ocr.Read(input)
result.SaveAsSearchablePdf(outputPdf)
End Using
End SubNuGetパッケージには英語のサポート機能が組み込まれています。 追加言語は.traineddataファイルシステムパスにファイルとしてではありません。 画像品質補正ガイドと画像方位補正ガイドは、OcrInputで利用可能な前処理オプションの完全セットをカバーします。
信頼性を考慮した処理(たとえば、データベースに書き込む前に結果を閾値以下にフィルタリングするなど)の場合、結果オブジェクトは信頼性を直接公開します。
var result = new IronTesseract().Read("scanned.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");
// Per-word confidence for fine-grained filtering
var highConfidenceWords = result.Words
.Where(w => w.Confidence > 85)
.Select(w => w.Text);var result = new IronTesseract().Read("scanned.jpg");
Console.WriteLine($"Confidence: {result.Confidence}%");
// Per-word confidence for fine-grained filtering
var highConfidenceWords = result.Words
.Where(w => w.Confidence > 85)
.Select(w => w.Text);Imports System
Imports System.Linq
Dim result = (New IronTesseract()).Read("scanned.jpg")
Console.WriteLine($"Confidence: {result.Confidence}%")
' Per-word confidence for fine-grained filtering
Dim highConfidenceWords = result.Words _
.Where(Function(w) w.Confidence > 85) _
.Select(Function(w) w.Text)Imports System
Imports System.Linq
Dim result = (New IronTesseract()).Read("scanned.jpg")
Console.WriteLine($"Confidence: {result.Confidence}%")
' Per-word confidence for fine-grained filtering
Dim highConfidenceWords = result.Words _
.Where(Function(w) w.Confidence > 85) _
.Select(Function(w) w.Text)GdPictureは同じデータに到達するために3つのネストされたループ - ブロック、行、単語 - を必要とし、各レベルでインデックスに基づいたメソッド呼び出し(GetOCRResultBlockLineWordConfidence(resultId, b, l, w))を使用します。 信頼度スコアの算出方法については、一般的なユースケースにおける構造化アクセスモデルを実例で示します。
構造化データと結果へのアクセス
単語ごとの座標と信頼度値を抽出することは、文書理解ワークフローにおいて一般的な要件です。請求書のフィールド抽出、フォーム処理、レイアウト分析など、いずれもこれが必要です。
GdPictureアプローチ
GdPictureはGdPictureOCRインスタンスのメソッド呼び出しを通じて照会されます。 単語ごとの信頼度を達成するには、3つのネストされたレベルを反復的に処理する必要があります。
using GdPicture14;
public List<(string word, float confidence)> GetWordConfidences(int imageId)
{
var words = new List<(string, float)>();
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
int blockCount = _ocr.GetOCRResultBlockCount(resultId);
for (int b = 0; b < blockCount; b++)
{
int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);
for (int l = 0; l < lineCount; l++)
{
int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);
for (int w = 0; w < wordCount; w++)
{
string word = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w);
float conf = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w);
words.Add((word, conf));
}
}
}
return words;
}using GdPicture14;
public List<(string word, float confidence)> GetWordConfidences(int imageId)
{
var words = new List<(string, float)>();
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
int blockCount = _ocr.GetOCRResultBlockCount(resultId);
for (int b = 0; b < blockCount; b++)
{
int lineCount = _ocr.GetOCRResultBlockLineCount(resultId, b);
for (int l = 0; l < lineCount; l++)
{
int wordCount = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l);
for (int w = 0; w < wordCount; w++)
{
string word = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w);
float conf = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w);
words.Add((word, conf));
}
}
}
return words;
}Imports GdPicture14
Public Function GetWordConfidences(imageId As Integer) As List(Of (word As String, confidence As Single))
Dim words As New List(Of (String, Single))()
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
Dim blockCount As Integer = _ocr.GetOCRResultBlockCount(resultId)
For b As Integer = 0 To blockCount - 1
Dim lineCount As Integer = _ocr.GetOCRResultBlockLineCount(resultId, b)
For l As Integer = 0 To lineCount - 1
Dim wordCount As Integer = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l)
For w As Integer = 0 To wordCount - 1
Dim word As String = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w)
Dim conf As Single = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w)
words.Add((word, conf))
Next
Next
Next
Return words
End FunctionImports GdPicture14
Public Function GetWordConfidences(imageId As Integer) As List(Of (word As String, confidence As Single))
Dim words As New List(Of (String, Single))()
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
Dim blockCount As Integer = _ocr.GetOCRResultBlockCount(resultId)
For b As Integer = 0 To blockCount - 1
Dim lineCount As Integer = _ocr.GetOCRResultBlockLineCount(resultId, b)
For l As Integer = 0 To lineCount - 1
Dim wordCount As Integer = _ocr.GetOCRResultBlockLineWordCount(resultId, b, l)
For w As Integer = 0 To wordCount - 1
Dim word As String = _ocr.GetOCRResultBlockLineWordText(resultId, b, l, w)
Dim conf As Single = _ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w)
words.Add((word, conf))
Next
Next
Next
Return words
End Functionこれは間違いではない。データは入手可能だ。 しかし、そのためには、単語レベルのデータを必要とするすべてのプロジェクトについて、結果構造への3次元インデックスを理解し、維持する必要がある。
IronOCRのアプローチ
OcrResult は .Words を型付きコレクションとして公開します。 LINQはこれに真っ向から反する働きをする。
using IronOcr;
var result = new IronTesseract().Read("invoice.jpg");
// All words with position and confidence
foreach (var word in result.Words)
{
Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}");
}
// Lines, paragraphs, and pages follow the same pattern
foreach (var line in result.Lines)
Console.WriteLine(line.Text);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters");using IronOcr;
var result = new IronTesseract().Read("invoice.jpg");
// All words with position and confidence
foreach (var word in result.Words)
{
Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}");
}
// Lines, paragraphs, and pages follow the same pattern
foreach (var line in result.Lines)
Console.WriteLine(line.Text);
foreach (var page in result.Pages)
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters");Imports IronOcr
Dim result = New IronTesseract().Read("invoice.jpg")
' All words with position and confidence
For Each word In result.Words
Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}")
Next
' Lines, paragraphs, and pages follow the same pattern
For Each line In result.Lines
Console.WriteLine(line.Text)
Next
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters")
NextImports IronOcr
Dim result = New IronTesseract().Read("invoice.jpg")
' All words with position and confidence
For Each word In result.Words
Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) — {word.Confidence:P0}")
Next
' Lines, paragraphs, and pages follow the same pattern
For Each line In result.Lines
Console.WriteLine(line.Text)
Next
For Each page In result.Pages
Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters")
Next領域ベースのOCR(文書内の定義された矩形領域からテキストを抽出する)も同様に直接的な方法です。
var region = new CropRectangle(0, 0, 600, 100); // header area
using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);
var headerText = new IronTesseract().Read(input).Text;var region = new CropRectangle(0, 0, 600, 100); // header area
using var input = new OcrInput();
input.LoadImage("invoice.jpg", region);
var headerText = new IronTesseract().Read(input).Text;Imports IronOcr
Dim region As New CropRectangle(0, 0, 600, 100) ' header area
Using input As New OcrInput()
input.LoadImage("invoice.jpg", region)
Dim headerText As String = New IronTesseract().Read(input).Text
End UsingImports IronOcr
Dim region As New CropRectangle(0, 0, 600, 100) ' header area
Using input As New OcrInput()
input.LoadImage("invoice.jpg", region)
Dim headerText As String = New IronTesseract().Read(input).Text
End Using読み取り結果ガイドと領域ベースOCRガイドでは、これらのパターンが複数ページの文書や構造化されたフィールド抽出ワークフローにどのように適用されるかを示しています。
APIマッピングリファレンス
| GdPicture.NET | IronOCR相当値 |
|---|---|
LicenseManager.RegisterKEY("key") | IronOcr.License.LicenseKey = "key" |
new GdPictureImaging() | 不要 - 内部で処理されます |
new GdPictureOCR() | new IronTesseract() |
new GdPicturePDF() | 必要ありません - OcrInput.LoadPdf()がこれを処理します |
ocr.ResourceFolder = path | 必須ではありません - NuGetにバンドルされているリソース |
imaging.CreateGdPictureImageFromFile(path) | input.LoadImage(path) on OcrInput |
imaging.ReleaseGdPictureImage(imageId) | using var input = new OcrInput() - 自動 |
ocr.SetImage(imageId) | 必要ありません - OcrInput が画像を保持します |
ocr.Language = "eng" | ocr.Language = OcrLanguage.English |
ocr.RunOCR() → resultId | ocr.Read(input) → OcrResult |
ocr.GetOCRResultText(resultId) | result.Text |
ocr.GetOCRResultConfidence(resultId) | result.Confidence |
ocr.GetOCRResultBlockLineWordText(resultId, b, l, w) | result.Words[i].Text |
ocr.GetOCRResultBlockLineWordConfidence(resultId, b, l, w) | result.Words[i].Confidence |
pdf.LoadFromFile(path, false) → GdPictureStatus | input.LoadPdf(path) - 失敗時に例外を投げます |
pdf.LoadFromFile(path, password) | input.LoadPdf(path, Password: password) |
pdf.RenderPageToGdPictureImage(200, false) | 不要 - IronOCRは内部的にレンダリングします |
pdf.SelectPage(i) | 必須ではありません - すべてのページはデフォルトで処理されます |
pdf.GetPageCount() | 必要ありません - または result.Pages.Count |
pdf.OcrPage("eng", resourcePath, "", 200) | result.SaveAsSearchablePdf(outputPath) |
pdf.SaveToFile(outputPath, true) | result.SaveAsSearchablePdf(outputPath) |
imaging.GetStat() / ocr.GetStat() | .NET Standardの例外 |
GdPictureStatus.OK 各呼び出し後のチェック | 必須ではありません。例外は通常どおり伝播します。 |
using GdPicture14; | using IronOcr; |
チームがGdPicture .NETからIronOCRへの移行を検討する際
OCRは唯一の要件です
スキャンされた請求書の取り込み、医療フォームの処理、契約書のテキスト抽出など、文書取り込みパイプラインを実装するチームは、GdPictureがLEADTOOLSやKofaxと並んでEnterpriseソフトウェアディレクトリに掲載されているため、しばしばGdPictureを評価する。 プラグインの依存関係テーブルが明確になれば、状況は一変する。 PDF入力が必要な場合、PDFプラグインは必須です。 前処理が必要な場合、ドキュメントイメージングプラグインは必須です。 スキャンされたPDFからのOCRが必要でdeskewの補正を持つチームは、かなりのプロフェッショナルの初期費用で3つのプラグインライセンスが必要になります。要件がテキスト抽出であり、GdPicture機能リストでそれ以上のものが必要でない場合、その料金は純粋なオーバーヘッドを表します。 IronOCR at $2,999 Professional は、単一のパッケージで画像入力、PDF入力、前処理、検索可能なPDF出力という同じワークフローをカバーし、プラグインの決定を行う必要はありません。
本番環境におけるメモリリーク発生事例
整数IDのライフサイクルは、高スループットの文書処理サービスにおいて、発生しかねない本番環境上のインシデントになりかねない。 負荷がかかった状態でアップロードされた PDF を処理する Web API エンドポイントでは、最終的に画像解放呼び出しに到達しないコード パスが発生します。これは、エラー ブランチでの早期リターン、クリーンアップ ブロック前の未処理例外、または単にパターンに慣れていない新しい開発者が整数型の画像ハンドルをパラメータとして受け取るヘルパー メソッドを追加し、それを解放し忘れるといったことが原因です。 メモリ使用量が増加し、サービス速度が低下し、ヒープダンプを見ても根本原因が明らかにならない。このような事態をデバッグした経験のあるチームは、通常、ランタイムがクリーンアップを処理するモデルを望む。IronOCRの標準的な破棄パターンはまさにそのモデルであり、開発者が呼び出し箇所ごとに規律を守るのではなく、コンパイラによって構造化されたクリーンアップが強制される。
バージョンアップグレード時の摩擦
GdPictureは、その名前空間にメジャーバージョン番号を埋め込んでいます。 バージョン14からバージョン15へのアップグレードでは、GdPictureクラスを参照するすべてのソースファイル内の名前空間ディレクティブを更新する必要があります。 OCR、PDF処理、画像処理といった機能が数十ものサービスやユーティリティクラスに分散している大規模なアプリケーションでは、これは容易ではない移行作業であり、機能的なメリットも一切ありません。 Microsoft.EntityFrameworkCoreからNewtonsoft.Jsonに至るまで、最新 for .NETライブラリはすべてバージョンに依存しない名前空間を使用し、 NuGetパッケージのバージョン番号を通じてバージョン管理を行っています。 IronOCRその慣例に従っており、バージョン1から現在のリリースまで、同じ名前空間インポートが適用されます。
マイクロサービスとコンテナのデプロイメント
GdPicture OCRは、実行時に言語データファイルを含む外部リソースフォルダが特定のパスに存在することを必要とします。コンテナ化された環境では、これらのファイルをDockerイメージに組み込むか、ボリュームをマウントするか、または起動スクリプトを設定してダウンロードする必要があります。 典型的な結果として、必要以上に数百メガバイトも大きいDockerイメージが生成され、デプロイメントチェックリストの項目が漏れ、ボリュームがマウントされていないためにクリーンなコンテナ再起動時に本番環境で障害が発生する。 IronOCRは、パッケージ自体に英語サポートを同梱しています。 追加言語は、ビルド出力の一部であるNuGetパッケージとしてインストールされます。 コンテナは復元ステップから必要なものを取得するため、設定すべきパスはありません。 Docker導入ガイドとLinux導入ガイドでは、それぞれの対象環境における具体的な設定方法について説明しています。
文書画像処理の専門知識を持たない開発チーム
GdPictureの表面積が大きいのは必然である。なぜなら、それは完全なドキュメントイメージングプラットフォームを網羅しているからだ。 OCRマイクロサービスの保守を担当するチームに加わる開発者にとって、画像処理コンポーネント、OCRコンポーネント、PDFコンポーネント、整数IDのライフサイクル、ステータス戻りコードの処理、およびリソースフォルダの構成を理解することは、初期投資としてかなりの労力を要する。 IronOCRのOCR処理領域は、エンジン、入力コンテナ、結果オブジェクトの3つのクラスに分けられます。 これは、90%のユースケースにおけるメンタルモデルの全体像です。 新しい開発者をオンボーディングするということは、マルチモジュールSDKガイドではなく、 IronTesseractのセットアップ手順を示すことを意味します。
一般的な移行の考慮事項
コンポーネント初期化の置き換え
GdPictureはライセンスキーをGdPictureOCRを初期化し、リソースフォルダーのパスを設定する4段階の初期化手順が必要です。 IronOCRでは、これはStartup.csに所属する1つのプロパティ割り当てに減少されます。
// Remove
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR";
// Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY";
// IronTesseract instances are instantiated per-use or as a singleton// Remove
LicenseManager lm = new LicenseManager();
lm.RegisterKEY("GDPICTURE-LICENSE-KEY");
_imaging = new GdPictureImaging();
_ocr = new GdPictureOCR();
_ocr.ResourceFolder = @"C:\GdPicture\Resources\OCR";
// Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY";
// IronTesseract instances are instantiated per-use or as a singleton' Remove
Dim lm As New LicenseManager()
lm.RegisterKEY("GDPICTURE-LICENSE-KEY")
_imaging = New GdPictureImaging()
_ocr = New GdPictureOCR()
_ocr.ResourceFolder = "C:\GdPicture\Resources\OCR"
' Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY"
' IronTesseract instances are instantiated per-use or as a singleton' Remove
Dim lm As New LicenseManager()
lm.RegisterKEY("GDPICTURE-LICENSE-KEY")
_imaging = New GdPictureImaging()
_ocr = New GdPictureOCR()
_ocr.ResourceFolder = "C:\GdPicture\Resources\OCR"
' Replace with
IronOcr.License.LicenseKey = "IRONOCR-LICENSE-KEY"
' IronTesseract instances are instantiated per-use or as a singleton画像ID追跡の排除
すべてのReleaseGdPictureImage呼び出しがあります。 それらのクリーンアップ呼び出しはIronOCRで完全に削除されます - OcrInputはディスポーザルを処理します。 マイグレーションは機械的です: 各using var input = new OcrInput()でラップし、GdPictureメソッド呼び出しを対応するIronOCRに置き換えます。
// Remove
int imageId = _imaging.CreateGdPictureImageFromFile(path);
if (imageId == 0) throw new Exception(_imaging.GetStat().ToString());
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId)) throw new Exception(_ocr.GetStat().ToString());
string text = _ocr.GetOCRResultText(resultId);
_imaging.ReleaseGdPictureImage(imageId);
// Replace with
using var input = new OcrInput();
input.LoadImage(path);
var result = new IronTesseract().Read(input);
string text = result.Text;// Remove
int imageId = _imaging.CreateGdPictureImageFromFile(path);
if (imageId == 0) throw new Exception(_imaging.GetStat().ToString());
_ocr.SetImage(imageId);
_ocr.Language = "eng";
string resultId = _ocr.RunOCR();
if (string.IsNullOrEmpty(resultId)) throw new Exception(_ocr.GetStat().ToString());
string text = _ocr.GetOCRResultText(resultId);
_imaging.ReleaseGdPictureImage(imageId);
// Replace with
using var input = new OcrInput();
input.LoadImage(path);
var result = new IronTesseract().Read(input);
string text = result.Text;Imports System
' Remove
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(path)
If imageId = 0 Then Throw New Exception(_imaging.GetStat().ToString())
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then Throw New Exception(_ocr.GetStat().ToString())
Dim text As String = _ocr.GetOCRResultText(resultId)
_imaging.ReleaseGdPictureImage(imageId)
' Replace with
Using input As New OcrInput()
input.LoadImage(path)
Dim result = New IronTesseract().Read(input)
Dim text As String = result.Text
End UsingImports System
' Remove
Dim imageId As Integer = _imaging.CreateGdPictureImageFromFile(path)
If imageId = 0 Then Throw New Exception(_imaging.GetStat().ToString())
_ocr.SetImage(imageId)
_ocr.Language = "eng"
Dim resultId As String = _ocr.RunOCR()
If String.IsNullOrEmpty(resultId) Then Throw New Exception(_ocr.GetStat().ToString())
Dim text As String = _ocr.GetOCRResultText(resultId)
_imaging.ReleaseGdPictureImage(imageId)
' Replace with
Using input As New OcrInput()
input.LoadImage(path)
Dim result = New IronTesseract().Read(input)
Dim text As String = result.Text
End Usingエラー処理の適応
GdPictureはGdPictureStatus を使用し、すべての重要な操作後にチェックされる返り値コードを利用します。 IronOCRは標準的な.NET例外をスローします。 マイグレーションではif (status != GdPictureStatus.OK) ガードをFileNotFoundExceptionを標準として処理します。 画像からテキストを読み取るチュートリアルでは、一般的なシナリオにおけるエラー処理パターンについて解説します。
言語パックの展開
GdPictureの言語ファイルはファイルシステムフォルダ内の.traineddataファイルです。 IronOCRの言語パックはNuGetパッケージです。 この移行では、デプロイメントマニフェストからリソースフォルダを削除し、必要な各言語に対応するNuGetパッケージ参照を追加します。
# Remove filesystem dependency for each language
# Add NuGet package instead
dotnet add package IronOcr.Languages.French
dotnet add package IronOcr.Languages.German
dotnet add package IronOcr.Languages.ChineseSimplified
複数の言語ガイドは、プライマリ言語とセカンダリ言語の両方がIronTesseractインスタンスで指定されているマルチランゲージドキュメントの設定をカバーしています。
IronOCRの追加機能
この比較で取り上げた領域以外にも、 IronOCRには、純粋なOCRの文脈ではGdPictureに直接対応する機能がない機能が含まれています。
非同期OCR - ASP.NET Coreリクエストハンドラーおよびバックグラウンドサービスでの非ブロッキング操作のためのReadAsync
-ページ回転検出 - 手動による前処理なしで、回転したページを自動的に検出して修正します。
-進捗状況の追跡 - UI の進捗バーに表示される、長時間実行されるバッチジョブのコールバックベースの進捗イベント
ストリーム入力 - System.IO.Streamを直接受け入れ、パイプラインアーキテクチャでの一時ファイル書き込みを回避
特殊な文書読み取り - パスポート、ナンバープレート、MICR小切手、手書きテキストのための特別に設計されたIronTesseractインターフェースを通じて取り扱い
.NETの互換性と将来の準備
IronOCRは、.NET 8、 .NET 9、 .NET Standard 2.0、および.NET Framework 4.6.2以降を対象としています。 この単一のNuGetパッケージは、Windows x64、Windows x86、Linux x64、およびmacOSに同一の方法でデプロイされます。 GdPicture .NETはクロスプラットフォーム環境もサポートしていますが、プラグインアーキテクチャを採用しているため、Linuxやコンテナ環境でのデプロイメントでは、各プラグインのネイティブ依存関係を個別に考慮する必要があります。 IronOCRの名前空間はすべての主要バージョン変更を通じてIronOcrと一貫しており、アップグレードパスはコードベース全体での検索と置換操作を必要としません。 .NET 10が2026年後半にリリースされるにあたり、IronOCRはAPIの変更を伴わずに.NETの連続リリース間で互換性を維持してきた実績があり、長期にわたるメンテナンスサイクルを必要とするアプリケーションにとって安定した基盤となります。
結論
GdPicture .NETは、スキャナー統合、PDF編集、注釈機能、DICOMサポート、OCRといった機能を1つのSDKで1つのベンダーから提供する、統合されたドキュメントイメージングプラットフォームを必要とするチームにとって、正当な選択肢です。 そのようなユースケースは確かに存在する。 プラグインモデルは、それらの機能のほとんどが実際に適用範囲内にある場合に理にかなっています。
要件がOCRで、回答がGdPictureの場合に不一致が発生します。 PDFプラグインは、PDFからのOCR処理というユースケースと切り離すことはできません。 ドキュメントイメージングプラグインは、前処理と切り離すことはできません。 整数IDのライフサイクルはオプションではなく、SDK全体の基本的なリソース管理モデルです。 スキャンされたPDFからテキストを抽出する必要があるチームは、その複雑さとコストをすべて負担しなければならず、追加機能のどれも、彼らの作業負荷に見合うものではない。
単一の開発者のプロフェッショナルワークフローでの年間コストの差は大きくなる可能性があります。 コードの複雑さの差は測定可能だ。基本的なOCRにクリーンアップを加えた場合、25行以上かかるのに対し、わずか1行で済む。 外部リソースフォルダ、バージョン固有の名前空間、複数コンポーネントの初期化といった運用上のギャップは、コード行数ではなく、デプロイメントの摩擦やオンボーディング時間として現れるが、確かに存在する。
IronOCR at $2,999 永続的 は、画像テキスト抽出、スキャンしたPDF処理、検索可能なPDF出力、125以上の言語、信頼スコアリング、構造化データアクセスを提供し、特別なSDKの知識を必要とせずに標準 for .NETパターンを通じて提供します。 OCRが目的であり、より広範な文書管理プラットフォームの構成要素ではないチームにとっては、そちらの方がより適切な選択肢となるでしょう。
関連する記事


