Windows.Media.OcrからIronOCRへの移行|IronOCR
このガイドは、Windows.Media.OCR から IronOCR へ移行する .NET 開発者向けに、段階的な移行手順を説明しています。 本書では、名前空間の削除、プロジェクトファイルの変更、移行時に最も頻繁に発生するパターンに対するコード移行の例、および移行完了後の検証に役立つ実用的なチェックリストについて解説しています。
Windows.Media.OCR (UWP/WinRT OCR) から移行する理由
Windows.Media.OCRは、その機能範囲内では良好に動作します。 その境界線は狭く、プロジェクトは日常的にその枠を超えて拡大していきます。 チームが移行する理由は、予測可能なカテゴリーに分類されます。
WindowsのTFMはすべての非Windowsターゲットをブロックします。 プロジェクトファイルはWindows.Media.Ocr名前空間が解決される前に宣言しなければなりません。その宣言は実行時のフラグではありません。これは、あなたのプロジェクトを参照するすべてのプロジェクトへ伝播されるビルド制約です。 共有OCRサービスライブラリ、Web API、Linuxにデプロイされたバックグラウンドワーカー——これらすべてに制約が課されています。 これを削除すると、Windows.Media.OCRも削除されることになります。
言語の可用性は実行時にOSで決定され、ビルド時に開発者によって決定されるものではありません。 ホストマシンにリクエストされた言語パックが存在しない場合、OcrEngine.TryCreateFromLanguageはnullを返します。開発者はコードから言語パックをインストールすることも、アプリケーションバイナリにバンドルすることも、フォールバックモデルを提供することもできません。 ビルドエージェント、CIランナー、最小構成のクラウドVM、コンテナといった自動化された環境では、言語パックがインストールされることはほとんどありません。 言語パックの欠落によって引き起こされる本番環境での障害は、コードを見ただけでは再現できません; これらは、対象マシンのOS構成を確認する必要があります。
前処理がないため、最適でない入力に対するリカバリパスはありません。 APIはSoftwareBitmapを受け入れ、テキストを生成します。 これら2つのポイント間の画質向上については、Windows専用である個別のWindows Imaging Component APIを使用し、開発者が全責任を負う必要があります。 携帯電話で撮影した写真、位置がずれたフラットベッドスキャン、およびコピーされた文書は、結果を診断したり改善したりする組み込みのメカニズムがないため、知らぬ間に精度を低下させてしまいます。
**PDFは、Enterpriseのワークフローにおいて最も一般的なドキュメント形式です。**Windows.Media.OCRには、PDF入力パスがありません。 スキャンしたPDFを処理するには、外部レンダラー、ページごとのラスタライズ、および手動による結果の組み立てが必要です。 そのレンダラーは、依存関係、ライセンス上の考慮事項、そして別の障害要因を追加することになります。これはまさに、"無料で組み込みの"ライブラリが回避すべきだった複雑さそのものです。
**サーバーサイドでのデプロイは構造的にサポートされていません。**Windows.Media.OCRはクライアントアプリケーションを対象としています。 Windows Server上でこれを実行するには、Desktop Experience機能パックが必要であり、これによりVMのコストとインフラストラクチャの複雑さが増します。 Docker によるデプロイは不可能です。 Linux上のAzure Functions、AWS Lambda、およびLinuxベースのコンテナワークロードでは、このAPIを参照することはできません。
WinRT非同期スタックは標準 for .NETパターンと互換性がありません。 単一の文字が読み取られる前に、6つ以上のRecognizeAsync—が必要です。 そのチェーンをバックグラウンドサービス、Parallel.ForEach ループ、または標準的な ASP.NET コントローラーに組み込むのは、扱いにくいものです。 WinRT IAsyncOperation 機械はその下にあり、.NETのTask モデルとの相互作用が非UIコンテキストで微妙なエッジケースを作り出します。
基本的な問題
Windows.Media.OCR の言語利用可能性は、デプロイ時に解決できないランタイム不明です:
// Windows.Media.Ocr: language availability decided by OS admin, not the developer
// Returns null on any machine without the language pack installed
var engine = OcrEngine.TryCreateFromLanguage(
new Windows.Globalization.Language("ja-JP"));
if (engine == null)
throw new InvalidOperationException(
"Japanese OCR unavailable — install the Japanese language pack in Windows Settings.");
// なし recovery path. なし bundled model. なし fallback.
// IronOCR: language availability is a NuGet package, not an OS configuration
// dotnet add package IronOcr.Languages.Japanese
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.Japanese;
var result = ocr.Read("invoice.jpg"); // Works on any OS, any machine
Console.WriteLine(result.Text);
IronOCR 対 Windows.Media.Ocr (UWP/WinRT OCR): 機能比較
以下の表は、移行の判断に関連する全機能範囲を網羅しています。
| フィーチャー | Windows.Media.Ocr | IronOCR |
|---|---|---|
| プラットフォーム: Windows 10/11 | はい | はい |
| プラットフォーム: Windows Server | 限定(デスクトップ環境での実務経験必須) | はい |
| プラットフォーム: Linux | なし | はい |
| プラットフォーム: macOS | なし | はい |
| プラットフォーム: Docker コンテナ | なし | はい |
| プラットフォーム: Azure Functions (Linux) | なし | はい |
| プラットフォーム: AWS Lambda | なし | はい |
| プロジェクト TFM の要件 | net*-windows* 必須 | なし(標準のTFM) |
| インストール。 | Windowsに組み込み(NuGet非対応) | 単一のNuGetパッケージ (IronOcr) |
| 画像入力(JPG、PNG、BMP) | はい(WinRTパイプライン経由) | はい |
| PDF入力 | なし | はい(ネイティブ) |
| 複数ページのTIFF入力 | なし | はい |
| ストリームおよびバイト配列の入力 | いいえ(StorageFileのみ) | はい |
| 原文 | OSにインストールされている言語パック | 125以上のNuGetパッケージがバンドルされています |
| 言語の移植性 | いいえ(マシン依存) | はい(アプリケーションと共にデプロイ) |
| 多言語同時通訳 | なし | はい |
| 前処理:傾き補正 | なし | はい (input.Deskew()) |
| 前処理:ノイズ除去 | なし | はい (input.DeNoise()) |
| 前処理:対比 | なし | はい (input.Contrast()) |
| 前処理:二値化 | なし | はい (input.Binarize()) |
| 検索可能なPDF出力 | なし | はい (result.SaveAsSearchablePdf()) |
| 単語ごとの信頼度スコア | なし | はい (word.Confidence) |
| 構造化された出力(段落、行、単語) | 行のみ | ページ、段落、行、単語、文字 |
| OCR処理中のBarCode読み取り | なし | はい |
| 地域ベースのOCR | なし | はい (CropRectangle) |
| 同期型OCRパス | なし | はい |
| スレッドセーフな並列処理 | 制限的 | フル |
| 商業サポート | いいえ(Windowsプラットフォームチーム) | はい |
| ライセンスモデル | 無料(Windowsに標準搭載) | 恒久的 ($999 Lite, $1,499 Pro, $2,999 Enterprise) |
クイックスタート:Windows.Media.OCR(UWP/WinRT OCR)からIronOCRへの移行
ステップ 1: NuGet パッケージを置き換える
Windows.Media.OCRにはNuGetパッケージはありません。これはWindowsランタイムの一部であり、Windows TFMを通じて解決されます。 これを削除するということは、Windows固有のネームスペースへの参照を削除し、可能な場合はプロジェクトファイルからWindows TFMを削除することを意味します。
すべてのソースファイルから Windows.Media.OCR 名前空間を削除してください:
# Audit all files referencing Windows OCR namespaces
grep -r "Windows.Media.Ocr\|Windows.Graphics.Imaging\|Windows.Storage" --include="*.cs" .
IronOCRのインストール:
IronOCR NuGetパッケージは、net9.0をターゲットにしており、特定のプラットフォームTFMはありません。 Windows OCR名前空間を削除した後、他のWinRT APIがプロジェクトに残っていない場合、プロジェクトファイル内のnet8.0(または適切なバージョン)に更新します。
ステップ 2: 名前空間の更新
3つのWindows OCRネームスペースを、単一のIronOCRネームスペースに置き換えてください:
// Before (Windows.Media.Ocr)
using Windows.Media.Ocr;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Globalization;
// After (IronOCR)
using IronOcr;
ステップ 3: ライセンスの初期化
アプリケーション起動時に一度ライセンス初期化呼び出しを追加します—Startup.cs、またはアプリケーションホストビルダーで:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"IronOCRのライセンスページから無料トライアルキーを入手でき、評価目的でトライアル用の透かしを削除することができます。
コード移行の例
バックグラウンドサービスにおける WinRT 非同期チェーンの置換
Windows.Media.OCR では、認識が開始されるまでに、少なくとも 6 つの非同期操作を連続して実行する必要があります。 ドキュメントキューを処理するバックグラウンドサービスでは、そのチェーンはループ内で実行され、SoftwareBitmapの破棄、nullチェック、およびWinRT IAsyncOperation の相互運用が毎回摩擦を追加します。
Windows.Media.OCR へのアプローチ:
// Windows.Media.Ocr: full async chain required per document
// Requires net8.0-windows10.0.19041.0 TFM — cannot deploy to Linux workers
public async Task<List<string>> ProcessQueueAsync(IEnumerable<string> imagePaths)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language pack installed on this machine.");
var results = new List<string>();
foreach (var path in imagePaths)
{
// Each document: 4 async steps before RecognizeAsync
var file = await StorageFile.GetFileFromPathAsync(path);
using var stream = await file.OpenAsync(FileAccessMode.Read);
var decoder = await BitmapDecoder.CreateAsync(stream);
var bitmap = await decoder.GetSoftwareBitmapAsync();
var ocrResult = await engine.RecognizeAsync(bitmap);
results.Add(ocrResult.Text);
bitmap.Dispose();
}
return results;
}
IronOCRのアプローチ:
// IronOCR: one call per document, no WinRT, no SoftwareBitmap, no null checks
// Runs on Windows, Linux, macOS, Docker — same binary, no TFM change
public List<string> ProcessQueue(IEnumerable<string> imagePaths)
{
var results = new List<string>();
foreach (var path in imagePaths)
{
var result = new IronTesseract().Read(path);
results.Add(result.Text);
}
return results;
}
IronOCRバージョンはSoftwareBitmap ライフサイクル、およびnullチェックガードを取り除きます。 非同期ネイティブサービスには、IronOCRは非同期パスを提供します。これはWinRT相互運用のオーバーヘッドなしで、Task ベースのパイプラインにクリーンに統合します。 IronTesseractのセットアップガイドでは、高スループットのキューシナリオにおけるインスタンスのライフサイクルに関する推奨事項について解説しています。
メモリ内画像データにおけるソフトウェアによるビットマップ変換の排除
ネットワークダウンロード、データベースのblob、カメラキャプチャコールバックからメモリ内にイメージデータを既に持っているアプリケーションは、そのデータをWindows.Media.Ocrが処理できるようにSoftwareBitmapに変換しなければなりません。 その変換パスはMemoryStreamにコピーする必要があります。 IronOCRは、バイト配列やストリームを直接受け付けます。
Windows.Media.OCR へのアプローチ:
// Windows.Media.Ocr: byte array must travel through WinRT stream → BitmapDecoder → SoftwareBitmap
public async Task<string> RecognizeFromBytesAsync(byte[] imageBytes)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language available.");
// Copy byte array into InMemoryRandomAccessStream (WinRT type)
using var ras = new Windows.Storage.Streams.InMemoryRandomAccessStream();
using var writer = new Windows.Storage.Streams.DataWriter(ras);
writer.WriteBytes(imageBytes);
await writer.StoreAsync();
ras.Seek(0);
var decoder = await BitmapDecoder.CreateAsync(ras);
var bitmap = await decoder.GetSoftwareBitmapAsync();
var result = await engine.RecognizeAsync(bitmap);
bitmap.Dispose();
return result.Text;
}
IronOCRのアプローチ:
// IronOCR: byte array loads directly into OcrInput — no conversion, no WinRT types
public string RecognizeFromBytes(byte[] imageBytes)
{
using var input = new OcrInput();
input.LoadImage(imageBytes); // direct byte array load
var result = new IronTesseract().Read(input);
return result.Text;
}
Windows.Media.OcrパスにはSoftwareBitmapが必要です。 IronOCRパスはOcrInput.LoadImage(byte[])を使用し、2行で結果を生成します。 ストリーム入力ガイドを参照し、バイト配列入力と同じシンプルさに従ったStream ベースの読み込みパターンをご確認ください。
OSとの連携を必要としない多言語ドキュメント処理
英語、フランス語、ドイツ語のテキストを1回の処理で認識する必要がある多言語請求書処理パイプラインは、Windows.Media.OCR を使用する場合、アーキテクチャ上の行き詰まりに直面します。 このAPIでは、1つのエンジンインスタンスにつき1つの言語のみが使用可能です。 複数言語が混在する文書を処理するには、最善の推測に基づく単一言語エンジンを使用するか、認識処理を3回実行して結果を統合する必要がありますが、いずれも信頼性の高い出力を得ることはできません。
Windows.Media.OCR へのアプローチ:
// Windows.Media.Ocr: one language per engine, no simultaneous multi-language support
// Each language requires a separate language pack installed on the machine
public async Task<string> RecognizeMultiLanguageAsync(SoftwareBitmap bitmap)
{
// Must pick ONE language — no simultaneous recognition
var engine = OcrEngine.TryCreateFromLanguage(
new Windows.Globalization.Language("en-US"));
if (engine == null)
throw new InvalidOperationException("English language pack not installed.");
// French and German text on the same document will be misrecognized
var result = await engine.RecognizeAsync(bitmap);
return result.Text;
}
IronOCRのアプローチ:
// IronOCR: simultaneous multi-language recognition in a single pass
// Language packs are NuGet packages — no OS coordination required
// dotnet add package IronOcr.Languages.French
// dotnet add package IronOcr.Languages.German
public string RecognizeMultiLanguage(string documentPath)
{
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;
var result = ocr.Read(documentPath);
// Structured output: walk paragraphs with location data
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"[{paragraph.X},{paragraph.Y}] {paragraph.Text}");
}
}
return result.Text;
}
IronOCRは、単一の認識処理で複数の言語モデルを組み合わせるため、対象領域がどの言語を使用しているかを推測する必要がなくなります。 多言語OCRガイドは、言語パックのインストールおよび125以上のサポートされている言語すべてのOcrLanguage列挙値をカバーしています。 言語インデックスには、CJK文字、アラビア語、ヘブライ語、デーヴァナーガリー文字、キリル文字ファミリーを含む全カタログが掲載されています。
並列処理によるサーバーサイド OCR の実現
Windows.Media.OCRは、Linux上のサーバーコンテキストでは実行できず、クロスプラットフォームホスト上の標準的なASP.NET Coreコントローラーからは呼び出すことができず、サーバー環境においてUIスレッド以外から呼び出した場合、未定義の挙動を示します。 OCRエンドポイントをWindows専用のデスクトップアプリケーションからスケーラブルなWeb APIへ移行するチームは、これら3つの制約すべてに同時に直面します。
Windows.Media.OCR へのアプローチ:
// Windows.Media.Ocr: cannot run on Linux, Docker, or Azure Functions on Linux
// UWP/WinRT assumptions about thread context cause failures in ASP.NET pipelines
// The entire approach below is non-deployable outside Windows with Desktop Experience
[HttpPost("ocr")]
public async Task<IActionResult> RecognizeDocument(IFormFile file)
{
// WinRT requires STA thread context in some scenarios — not guaranteed in ASP.NET
// Cannot deploy this controller to a Linux App Service plan
using var stream = file.OpenReadStream();
// InMemoryRandomAccessStream is a WinRT type — does not exist on Linux
// var ras = new InMemoryRandomAccessStream(); // compile error on net8.0 TFM
return StatusCode(503, "Windows-only — cannot deploy cross-platform.");
}
IronOCRのアプローチ:
// IronOCR: ASP.NET Core controller running on Linux, Docker, or Windows — same code
[HttpPost("ocr")]
public async Task<IActionResult> RecognizeDocument(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("No file provided.");
using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream);
var imageBytes = memoryStream.ToArray();
using var input = new OcrInput();
input.LoadImage(imageBytes);
input.Deskew(); // straighten uploaded scans automatically
input.DeNoise(); // remove mobile camera noise
var result = new IronTesseract().Read(input);
return Ok(new
{
Text = result.Text,
Confidence = result.Confidence,
Pages = result.Pages.Count
});
}
このコントローラーは、変更を加えることなく、Linux App Service、Docker、および AWS Lambda にデプロイできます。 Docker展開ガイドは、Linuxベースイメージに必要な単一のapt-get依存関係をカバーしています。 Azure 導入ガイドおよび AWS ガイドでは、クラウド固有の設定手順を解説しています。
スキャン済みアーカイブから検索可能なPDFを生成する
Windows.Media.OCR はプレーンテキストの文字列を生成します。 それはOcrResult.Linesのラインジオメトリを超えた出力形式を持ちません。 スキャンしたアーカイブを検索可能なPDFに変換すること(これは文書管理システムやコンプライアンスワークフローにおける一般的な要件です)には、PDF出力レイヤーを構築するための3つ目のライブラリが必要です。 IronOCRは、ネイティブに検索可能なPDFを生成します。
Windows.Media.OCR へのアプローチ:
// Windows.Media.Ocr: plain text output only
// Searchable PDF requires external PDF library + manual text layer construction
public async Task<string> GetTextOnlyAsync(SoftwareBitmap bitmap)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language available.");
var result = await engine.RecognizeAsync(bitmap);
// result.Text is all you get
// Producing a searchable PDF requires an entirely separate library
return result.Text;
}
IronOCRのアプローチ:
// IronOCR: searchable PDF output is one method call on OcrResult
public void ProcessScannedArchive(IEnumerable<string> pdfPaths, string outputDirectory)
{
foreach (var sourcePdf in pdfPaths)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(sourcePdf); // native PDF input — no external renderer
input.Deskew(); // correct scan misalignment per page
input.DeNoise(); // remove scanner speckle
var result = ocr.Read(input);
var outputFileName = Path.Combine(
outputDirectory,
Path.GetFileNameWithoutExtension(sourcePdf) + "-searchable.pdf");
result.SaveAsSearchablePdf(outputFileName);
Console.WriteLine($"Processed: {sourcePdf} → {outputFileName} " +
$"({result.Pages.Count} pages, {result.Confidence:F1}% confidence)");
}
}
SaveAsSearchablePdf呼び出しは、元のスキャンされたイメージにテキストレイヤーを埋め込み、視覚の忠実性を保持しながら、任意のPDFビューアでのフルテキスト検索とCtrl+Fを可能にします。 検索可能なPDF形式のハウツーガイドでは、フォントの埋め込み、テキストレイヤーの配置、および複数ページ出力に関するオプションについて解説しています。 PDF入力ガイドでは、パスワードで保護されたPDFや、大規模なアーカイブにおけるページ範囲の選択について解説しています。
単語単位の座標を用いた構造化データの抽出
Windows.Media.Ocrは、ラインレベルのテキストとバウンディング矩形を使用して、OcrResult.Linesを公開しています。 単語ごとのジオメトリはOcrWord.BoundingRectと共に存在しますが、段落、信頼度スコア、文字レベルデータはありません。 フォームフィールドの抽出や請求書の明細行の解析においては、行の境界情報だけでは不十分です。構造化されたフィールドを周囲のテキストから区別するためには、段落の境界および単語の信頼度スコアが必要です。
Windows.Media.OCR へのアプローチ:
// Windows.Media.Ocr: line-level geometry, no paragraph grouping, no confidence scores
public async Task<List<string>> ExtractLineTextAsync(SoftwareBitmap bitmap)
{
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("No OCR language available.");
var result = await engine.RecognizeAsync(bitmap);
var lineTexts = new List<string>();
foreach (var line in result.Lines)
{
// Line text + word bounding rects — no paragraph grouping, no confidence
lineTexts.Add(line.Text);
}
return lineTexts;
}
IronOCRのアプローチ:
// IronOCR: full hierarchy — pages, paragraphs, lines, words, characters
// Each element carries coordinates and confidence for downstream validation
public void ExtractStructuredData(string documentPath)
{
var result = new IronTesseract().Read(documentPath);
Console.WriteLine($"Overall confidence: {result.Confidence:F1}%");
foreach (var page in result.Pages)
{
Console.WriteLine($"\n--- Page {page.PageNumber} ---");
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Paragraph at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");
// Filter words below confidence threshold for validation workflows
var lowConfidence = paragraph.Words
.Where(w => w.Confidence < 70)
.ToList();
if (lowConfidence.Any())
{
Console.WriteLine($" Low-confidence words: " +
string.Join(", ", lowConfidence.Select(w => $"'{w.Text}' ({w.Confidence:F0}%)")));
}
}
}
}
構造化された結果モデル—Characters—は、フォームフィールド抽出、請求書解析、ドキュメントレイアウト分析に必要な座標および信頼データを提供します。 結果を読み取るガイドは、完全なOcrResultオブジェクトグラフを文書化しています。 信頼度スコアのガイドでは、WORDごとの信頼度値を使用して、不確実な抽出箇所を特定し、人間によるレビューに回す方法について説明しています。
Windows.Media.OCR API から IronOCR へのマッピングリファレンス
| Windows.Media.Ocr | IronOCR |
|---|---|
OcrEngine.TryCreateFromLanguage(lang) | new IronTesseract() + ocr.Language = OcrLanguage.X |
OcrEngine.TryCreateFromUserProfileLanguages() | new IronTesseract() (デフォルトの英語、 (nullを返さない) |
engine.RecognizeAsync(softwareBitmap) | ocr.Read("image.jpg") 又は ocr.Read(ocrInput) |
StorageFile.GetFileFromPathAsync(path) | ocr.Read("path") 直接 (ファイルハンドル不要) |
file.OpenAsync(FileAccessMode.Read) | 排除済 — OcrInput は直接読み込まれます |
BitmapDecoder.CreateAsync(stream) | input.LoadImage(stream) は OcrInput 経由で |
decoder.GetSoftwareBitmapAsync() | 排除済 — IronOCRにSoftwareBitmap はありません |
SoftwareBitmap (WinRTタイプ) | 排除済 — OcrInput はバイト、ストリーム、ファイルパスを受け入れます |
InMemoryRandomAccessStream (WinRTタイプ) | new MemoryStream() + input.LoadImage(stream) |
OcrResult.Text | OcrResult.Text |
OcrResult.Lines | OcrResult.Lines (または Characters) |
OcrLine.Text | OcrResult.Lines[i].Text |
OcrLine.Words | OcrResult.Words 又は page.Paragraphs[i].Words |
OcrWord.BoundingRect | word.X, word.Y, word.Width, word.Height |
| 同等のものはありません | result.Confidence (全体) / word.Confidence (単語単位) |
| 同等のものはありません | result.SaveAsSearchablePdf("output.pdf") |
| 同等のものはありません | input.LoadPdf("document.pdf") |
| 同等のものはありません | input.Deskew(), input.DeNoise(), input.Contrast() |
| 同等のものはありません | ocr.Language = OcrLanguage.A + OcrLanguage.B (同時) |
| 同等のものはありません | ocr.Configuration.ReadBarCodes = true |
| 同等のものはありません | input.LoadImage(byteArray) |
一般的な移行の問題と解決策
課題 1: 移行後もプロジェクトファイルには Windows TFM が必要
Windows.Media.Ocr: <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>の宣言は、WinRTタイプを解決するために必要です。 同じプロジェクト内の他の WinRT 依存関係を確認せずに Windows.Media.OCR の参照を削除すると、TFM が残ったままになり、クロスプラットフォームのビルドが妨げられる可能性があります。
**解決策:**OCR ネームスペースへの参照を削除した後、TFM を変更する前に、プロジェクト内で残っている WinRT API の使用箇所を検索してください:
# Find remaining WinRT API usage before removing the Windows TFM
grep -r "Windows\." --include="*.cs" .
grep -r "WinRT\|IAsyncOperation\|StorageFile\|SoftwareBitmap" --include="*.cs" .
WinRTへの参照が残っていない場合は、プロジェクトファイルを更新してください:
<!-- Before -->
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<!-- After -->
<TargetFramework>net8.0</TargetFramework>
その他の WinRT 機能(Windows 通知、シェル統合、XAML)を引き続き使用する場合は、TFM をプロジェクト全体から削除するのではなく、OCR 呼び出しをインターフェースの背後で抽象化し、プラットフォーム固有の実装を提供してください。
課題 2: Null Engine Checks に IronOCR 相当の機能がない
Windows.Media.Ocr: TryCreateFromLanguage と TryCreateFromUserProfileLanguages へのすべての呼び出しはnullを返す可能性があります。 既存のコードにはすべて、null エンジンが発生した場合に例外をスローするか分岐を行う null チェックのガード句が含まれています。
解決策: IronOCRは、初期化に失敗した場合、nullを返すのではなく、構造化された例外をスローします。 nullチェックのガード句を削除してください。 初期化エラーを呼び出し元に通知する必要がある場合は、標準的な try/catch ブロックで囲んでください:
// Before: null-check pattern
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
throw new InvalidOperationException("OCR unavailable.");
// After: no null — IronTesseract throws if misconfigured
try
{
var result = new IronTesseract().Read("document.jpg");
}
catch (IronOcr.Exceptions.OcrException ex)
{
// structured exception with diagnostic message
logger.LogError("OCR failed: {Message}", ex.Message);
}
課題 3: 既存のメソッドシグネチャにおける SoftwareBitmap パラメータ
Windows.Media.Ocr: ユーティリティメソッド、サービス、およびリポジトリクラスは、パラメータタイプとしてSoftwareBitmapを受け入れる可能性があります。 Windows TFM を削除すると、それらのメソッドシグネチャはコンパイルできません。
解決策: Streamに置き換えます。 IronOCRのOcrInputは両方を直接受け入れます。 以前にSoftwareBitmapを構築していた呼び出し元は、基になるデータを代わりに渡すことができます:
// Before: SoftwareBitmap parameter — cannot compile cross-platform
public async Task<string> RecognizeAsync(SoftwareBitmap bitmap) { ... }
// After: byte array parameter — compiles on all platforms
public string Recognize(byte[] imageBytes)
{
using var input = new OcrInput();
input.LoadImage(imageBytes);
return new IronTesseract().Read(input).Text;
}
課題 4: 非同期専用呼び出し元は、同期型の IronOCR を直接使用できない
Windows.Media.Ocr: すべての認識呼び出しはasyncです。 コードベース全体の呼び出し元は、Task<string>を返します。 IronOCRの同期asyncが建築上であったコンテキストでブロッキング呼び出しを導入する可能性があります。
**解決策:**IronOCRは、それを必要とする呼び出し元向けに非同期パスを提供します。 既存の非同期メソッドでCPUバウンドのラッピングにTask.Runを使用するか、ネイティブの非同期APIを使用します:
// Option A: wrap synchronous call in Task.Run for async callers
public async Task<string> RecognizeAsync(string imagePath)
{
return await Task.Run(() => new IronTesseract().Read(imagePath).Text);
}
// Option B: IronOCR async path
// See: https://ironsoftware.com/csharp/ocr/how-to/async/
非同期OCRガイドは、ファイア・アンド・フォーゲット(実行して放置)や進行状況報告のパターンが必要なコンテキスト向けの、組み込みの非同期APIについて解説しています。
課題 5: Windows の言語タグ形式は直接対応しない
Windows.Media.Ocr: 言語は、Windows.Globalization.Language("fr-FR")に渡されるBCP-47文字列タグを使用して指定します。 これらの文字列タグには、IronOCR内に直接対応するものは存在しません。
解決策: BCP-47言語タグをOcrLanguage列挙型にマップします。 一般的な言語については、対応関係は単純明快です:
// Before: BCP-47 string tags
var engine = OcrEngine.TryCreateFromLanguage(
new Windows.Globalization.Language("fr-FR"));
// After: OcrLanguage enum
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.French;
// Also: OcrLanguage.German, OcrLanguage.Japanese, OcrLanguage.Arabic, etc.
完全なマッピングは、IronOCR言語カタログで確認できます。 カスタム言語パックサポートは、メインの列挙型にリストされていない言語用に.traineddataファイルを直接読み込むことを示します。
課題 6: FileAccessMode.Read に代替機能がない
Windows.Media.Ocr: file.OpenAsync(FileAccessMode.Read)は、WinRT特有のファイルオープンパターンです。 標準 for .NETにはFileAccessMode列挙型が存在しません。
解決策: 標準のFileStreamで置き換えます。 OcrInputは両方を受け入れます:
// Before: WinRT file access
using var stream = await file.OpenAsync(FileAccessMode.Read);
// After: standard .NET
var imageBytes = File.ReadAllBytes(imagePath);
using var input = new OcrInput();
input.LoadImage(imageBytes);
Windows.Media.OCR (UWP/WinRT OCR) 移行チェックリスト
移行前
変更を加える前にコードベースを監査してください:
# Find all Windows OCR namespace usages
grep -rn "using Windows.Media.Ocr" --include="*.cs" .
grep -rn "using Windows.Graphics.Imaging" --include="*.cs" .
grep -rn "using Windows.Storage" --include="*.cs" .
grep -rn "using Windows.Globalization" --include="*.cs" .
# Find WinRT type usages
grep -rn "OcrEngine\|SoftwareBitmap\|BitmapDecoder\|StorageFile" --include="*.cs" .
grep -rn "TryCreateFromLanguage\|TryCreateFromUserProfileLanguages\|RecognizeAsync" --include="*.cs" .
grep -rn "InMemoryRandomAccessStream\|DataWriter\|FileAccessMode" --include="*.cs" .
# Find project files with Windows TFM
grep -rn "net.*-windows" --include="*.csproj" .
# Count files requiring changes
grep -rl "Windows.Media.Ocr\|Windows.Graphics.Imaging\|SoftwareBitmap" --include="*.cs" . | wc -l
影響を受けたファイルの数、使用されている言語タグ("fr-FR"など)、およびWinRTタイプが公開メソッドのシグネチャに登場するかどうかを記録します(これらは内部の書き換えに加えてAPIの変更を必要とします)。
コードの移行
IronOcrNuGetパッケージをインストールします:dotnet add package IronOcr- ライセンス初期化呼び出しを
Startup.csに追加します:IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; - すべてのソースファイルから
using Windows.Media.Ocr;を削除します - すべてのソースファイルから
using Windows.Graphics.Imaging;を削除します - すべてのソースファイルから
using Windows.Storage;を削除します - すべてのソースファイルから
using Windows.Globalization;を削除します - OCRを実行するすべてのファイルに
using IronOcr;を追加します - すべての
ocr.Language = OcrLanguage.Xを設定します - すべての
new IronTesseract()に置き換えます - エンジン作成結果に関するすべてのヌルチェックガード句を削除する
- メソッドシグネチャ内の
Streamに置き換えます StorageFile+BitmapDecoder+OcrInput.LoadImage(stream)に置き換えますocr.Read(input)に置き換えますMemoryStreamに置き換えます- WindowsのBCP-47言語タグ文字列を
OcrLanguage列挙値に置き換えます; 必要な言語の NuGet パッケージをインストールする .csprojファイルで更新し、他のWinRT APIが残っていない場所で-windowsX.Y.Z接尾辞を削除します
移行後
- プロジェクトが
net8.0(またはターゲットバージョン)をターゲットにしてコンパイルされることを確認します。Windows TFM接尾辞なしで - プロジェクトがLinux環境またはDockerコンテナでコンパイルおよび実行されることを確認します。
mcr.microsoft.com/dotnet/aspnet:8.0を使用します - テストSuite内の各ドキュメントタイプについて、OCR出力テキストが期待される結果と一致することを確認する
- IronOCR言語用NuGetパッケージを使用して、これまでサポートされていたすべての言語で正しい出力が得られることを確認してください
- 単一の認識処理で、多言語文書が正しい結果を生成することを確認する
- Windows言語パックがインストールされていないマシンでのエンジン初期化時に
InvalidOperationExceptionがないことを確認します - クリーンおよび低品質の入力ドキュメントに対して
result.Confidenceの値が期待範囲内にあることを確認します - アプリケーションがドキュメントを生成する場合、PDFビューアで正常に開き、テキスト検索をサポートする
SaveAsSearchablePdf出力を確認します - 既存の並列またはマルチスレッド処理パスを実行し、負荷下でのスレッドセーフ性を確認する
- ターゲット環境(Docker、Azure App Service、AWS、Linuxサーバー)にデプロイし、少なくとも1回の完全なエンドツーエンドのOCR処理を実行する
IronOCRへの移行の主なメリット
**クロスプラットフォーム展開は、コードの書き換えではなく、設定の決定事項となります。**移行後、OCRコンポーネントはWindows、Linux、macOS、Docker、および主要なクラウドプロバイダーすべてで同一に動作します。 ホスティングコストを削減するために、OCRワークロードをWindows VMからLinuxコンテナに移行することは、デプロイメント作業です。 Linux 導入ガイドおよび Docker 導入ガイドでは、Linux ベースイメージに必要な 1 行の依存関係の追加について解説しています。
**言語サポートはアプリケーションのバイナリと共に提供されます。**言語パックは NuGet パッケージとしてインストールされ、IronOCR パッケージとバージョン固定されます。 アプリケーションが認識できる言語セットはプロジェクトファイルで定義されており、開発者のワークステーション、CIランナー、ステージングサーバー、本番ホストなど、すべてのマシンで同一です。OS管理者の調整も、グループポリシーの例外設定も、実行時のnullチェックも不要です。
外部ツール無しでOCR精度が向上します。 前処理パイプライン—Scale—は、認識エンジンがイメージを見る前にIronOCR内で実行されます。 スキャンのズレやノイズにより Windows.Media.OCR で画質が劣化していたドキュメントも、外部の画像処理ライブラリに依存することなく、画質が向上します。 画質補正ガイドとフィルターウィザードは、各ドキュメントの種類に適したフィルターの組み合わせを特定するのに役立ちます。
**PDF ワークフローが単一のライブラリに統合されました。**Windows.Media.OCR と PDF 入力の橋渡しに必要だった外部 PDF レンダラーは、もはや不要になりました。 スキャンされたPDFアーカイブは、イメージとしての同じIronTesseract.Read呼び出しを通過します。 検索可能なPDF出力は、resultオブジェクトのメソッドです。 2つのライブラリからなるアーキテクチャが解消され、それに伴うバージョン管理、ライセンス管理の負担、およびデプロイメントの複雑さも解消されます。
構造化出力がドキュメントインテリジェンスパイプラインを可能にします。 OcrResult 階層—Characters—では、各要素ごとの座標と信頼度スコアが提供され、請求書のフィールド抽出、フォームパーシング、ドキュメント分類に必要なデータが提供されます。 Windows.Media.OCRの行単位の出力では、これらのワークフローには不十分です。 IronOCRでは、信頼度フィルタリングによる単語抽出、段落境界の検出、座標ベースのフィールドマッピングが、追加のライブラリを必要としない標準機能として提供されています。
**永続ライセンスは、インフラへの無制限な依存に取って代わります。**異種混在のマシン群における Windows 言語パックのインストール維持、Windows Server Desktop Experience のライセンス、および Windows 専用の CI インフラにかかるコストは、現実のものですが、その影響は拡散しています。つまり、OCR 予算の個別項目としてではなく、IT チケットやインフラ予算の中に現れるのです。 単一の開発者プロジェクトに対して、そのオーバーヘッドを除去する$999 IronOCR Liteライセンス。 1,499ドルのProfessional Licenseは、10名の開発者を対象としています。 いずれも1回限りの購入で、1年間のアップデートが含まれています。
