IRONSOFTWAREHOME
ビデオ

Tesseract.NET SDKからIronOCRへの移行|IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 2026年8月1日

このガイドでは、.NET 開発者が Tesseract .NET SDK (Tesseract.Net.SDK、namespace Patagames.Ocr) から IronOCR への具体的な移行を案内します。 特に、.NET Framework時代の初期化パターン、レガシーなディスポーズの慣用表現、および同期処理のみのパイプラインを、現在.NET 8、Linuxコンテナ、および非同期ファーストのWebフレームワーク上で動作する環境へと移行させているチームを対象としています。 あなたの OCR サービスが net472 に対してコンパイルされ、<TargetFramework>net8.0</TargetFramework>.csproj に追加したとき失敗するなら、このガイドはあなたのために書かれています。

Tesseract .NET SDK から移行する理由

Patagames SDKは、.NET Framework 4.5がデプロイメントのベースラインであり、Windows Serverが唯一のターゲットであった当時、真の価値を提供していました。 その状況は変化しました。 現在、多くの組織ではサービスのコンテナ化、LinuxランナーでのCI実行、および.NET 6、8、または9への標準化が進んでいます。Tesseract.NET SDKは、こうした動向に対応できていません。

.NET Framework 4.5 でのハード上限。 パッケージは net20 から net45 をターゲットにしています。 それは netstandardnet6.0 アセンブリを生成しません。 Tesseract.Net.SDK を含むプロジェクトファイルは <TargetFramework>net8.0</TargetFramework> を設定できません。 コードベースの残りの部分がスプリント内で完了するはず for .NETのアップグレードが、OCRレイヤーで無期限に停滞している。

**コンテナパスは指定されません。**この SDK は、Windows ネイティブバイナリへの Windows 専用 P/Invoke 呼び出しを提供します。 どの Linux ベースイメージでも — alpine:3.19 — アプリケーションは単一のドキュメントを処理する前に DllNotFoundException をスローします。 Windowsコンテナは代替手段として存在しますが、イメージサイズが大きく、別途ライセンス費用がかかり、デフォルトでLinuxノードプールを使用するほとんどのマネージドKubernetesサービスとは互換性がありません。

同期のみの API が ASP.NET Core パイプラインをブロックします。 OcrApi.GetTextFromImage() メソッドは同期です。 .NET Core では、リクエストスレッドでブロッキング型の同期操作を呼び出すと、負荷がかかった際のスループットが低下し、スレッドプールの枯渇リスクが生じます。 IronOCR は ReadAsync() を提供して非同期統合を可能にします。 パターンについては、非同期OCRガイドを参照してください。

リクエストごとのエンジン作成はメモリを消費します。 .NET Framework コードでは通常、メソッドコールやリクエストごとに OcrApi インスタンスを作成し、終了時に破棄します。 これは、.NET Frameworkのライフサイクル管理における慣用的な表現です。 それはまた高価です: 各 Init() で 40–100 MB の言語データがロードされます。 10件の同時リクエストにより、同じ言語モデルが10回読み込まれます。 IronOCR の IronTesseract はスレッドセーフです — アプリケーションライフタイム中に一つのインスタンスが存在し、全ての同時呼び出しに対応するために単一の言語モデルロードを使用します。

**レガシーな処理パターンはリスクを蓄積させます。**SDKを正しく使用するには、using (var api = OcrApi.Create()) { ... statement that predates using var 宣言。 C# 8.0 以前に書かれたコードベースには、try/finally 廃棄パターンや、バグの場合には廃棄が全く行われないものがよく含まれています。 これらのパターンは.NET Framework上でコンパイルおよび実行可能ですが、現代的なリファクタリングを妨げる技術的負債を抱えています。

非同期なし、DIなし、モダンスタートアップなし。 SDK は依存性注入の統合、ホストされたサービスライフタイム、または IOptions<t> 設定の概念を持っていません。 これを ASP.NET Core アプリケーションに組み込むには、手動でのサービス登録が必要であり、リクエストごとのインスタンス化を慎重に回避する必要があります。 IronOCRは、標準的なDIコンテナ内でシングルトンサービスとしてシームレスに統合されます。

基本的な問題

// Tesseract.NET SDK: .NET Framework 4.5 ceiling — will not compile on net8.0
// Every project referencing this package is locked below the upgrade line
using Patagames.Ocr;  // Patagames.Ocr targets net45; no netstandard or net8 assembly

public class OcrService
{
    public string ProcessDocument(string imagePath)
    {
        // Synchronous-only — blocks ASP.NET Core request threads
        // なし DI support — must be instantiated manually each time
        using (var api = OcrApi.Create())    // C# 1.0 using statement, 40-100MB load per call
        {
            api.Init(Languages.English);
            return api.GetTextFromImage(imagePath);
        }
        // Project cannot target net6.0, net8.0, or any Linux container base image
    }
}
C#
// IronOCR: same logic, any runtime from net462 to net9.0, any platform
using IronOcr;  // Single NuGet, supports .NET Framework 4.6.2+, .NET 5/6/7/8/9

// Register once as singleton — load language model once, share across all requests
// Call ReadAsync() in ASP.NET Core for non-blocking operation
var ocr = new IronTesseract();
var result = await ocr.ReadAsync("document.jpg");  // Async-first, no thread blocking
Console.WriteLine(result.Text);
C#

IronOCR 対 Tesseract.NET SDK:機能比較

以下の表は、.NET へのモダナイゼーション移行に直接関連する機能を示しています。

フィーチャーTesseract .NET SDKIronOCR
.NET Framework 2.0~4.5はいなし
.NET Framework 4.6.2~4.8なしはい
.NET Core 2.x / 3.xなしはい
.NET 5なしはい
.NET 6なしはい
.NET 7なしはい
.NET 8なしはい
.NET 9なしはい
Windows展開はいはい
Linuxの展開なしはい
macOSへの展開なしはい
Docker Linux コンテナなしはい
Azure App Service(Linux)なしはい
AWSラムダなしはい
非同期 API (ReadAsync)なしはい
スレッドセーフなシングルインスタンスなしはい
ASP.NET Core DI 統合マニュアルシングルトンサービス
ネイティブPDF入力なしはい
組み込みの前処理なしはい
検索可能なPDF出力なしはい
構造化データ(WORD、行、段落)なしはい
商用サポート/SLAいいえ(個人開発者)はい
永続ライセンス価格~$20–50(開発者1名)$999 から

クイックスタート:Tesseract.NET SDK から IronOCR への移行

ステップ 1: NuGet パッケージを置き換える

Tesseract.NET SDKを削除:

dotnet remove package Tesseract.Net.SDK
SHELL

PdfiumViewerや類似のPDFレンダリングライブラリが、SDKにPDFページを供給する目的のみでインストールされていた場合は、それらも削除してください。IronOCRはPDFをネイティブで読み取ります:

dotnet remove package PdfiumViewer
SHELL

NuGetからIronOCRをインストールしてください。

dotnet add package IronOcr

ステップ 2: 名前空間の更新

// Before (Tesseract.NET SDK)
using Patagames.Ocr;
using Patagames.Ocr.Enums;

// After (IronOCR)
using IronOcr;
C#

ステップ 3: ライセンスの初期化

アプリケーションの起動時に一度ライセンスキーコールを追加します — Startup.cs、またはアプリケーションホストビルダー内で:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

ウォーターマークなしで評価できる無料トライアルライセンスが利用可能です。

コード移行の例

.NET Framework スタートアップ パターンから Modern Host Builder へ

.NET Framework アプリケーションは通常、OCR エンジンを静的コンストラクター、Application_Start イベント、または Global.asax ハンドラー内で初期化します。 これらは、ジェネリックホストモデルに基づいて構築された.NET 6以降のアプリケーションには存在しません。

Tesseract.NET SDK へのアプローチ:

// Global.asax.cs — .NET Framework MVC application
// OcrApi lifecycle managed manually; no DI container involved
public class MvcApplication : System.Web.HttpApplication
{
    // Static field — one engine for the app lifetime
    // But: NOT thread-safe; concurrent requests share a single OcrApi instance
    private static OcrApi _globalApi;

    protected void Application_Start()
    {
        // Initialize OCR engine on app startup
        // Path to tessdata hardcoded for deployment environment
        _globalApi = OcrApi.Create();
        _globalApi.Init(Languages.English);

        AreaRegistration.RegisterAllAreas();
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

    protected void Application_End()
    {
        // Must manually dispose on shutdown
        _globalApi?.Dispose();
    }
}
C#

IronOCRのアプローチ:

// Program.cs —.NET 8ASP.NET Core application
// IronTesseractはスレッドセーフです。 register as singleton, inject where needed
var builder = WebApplication.CreateBuilder(args);

IronOcr.License.LicenseKey = builder.Configuration["IronOcr:LicenseKey"];

// Register as singleton — one instance, thread-safe, shared across all requests
builder.Services.AddSingleton<IronTesseract>();

builder.Services.AddControllers();

var app = builder.Build();
app.MapControllers();
app.Run();
C#

Global.asax パターンは完全に消え去ります。 IronTesseract は標準のシングルトンサービスとして登録され、コントローラーやサービスにコンストラクターを通じて注入されます。 言語モデルは初回使用時に一度読み込まれ、アプリケーションの稼働中はメモリ内に保持されます。IronTesseractのセットアップガイドでは、登録時の言語選択やエンジンモードを含む設定オプションについて解説しています。

レガシー処理パターンの近代化

.NET Framework 2.0 コードは using (var x = ...) { } ブロック文を使用します。 C# 8.0 により using var 宣言が導入され、廃棄が囲みブロックにスコープされます。 古いコードベースには try/finally 廃棄ガードも含まれており、using 文が全てのシナリオで信頼されていなかった時に書かれたものです。 これらのパターンはすべて、.NET Framework向けに記述されたコードを示しており、移行の際に最新化する必要があります。

Tesseract.NET SDK へのアプローチ:

// .NET Framework 4.x disposal patterns — three variants encountered in production
public class LegacyOcrProcessor
{
    // Pattern 1: try/finally guard (pre-C# 2.0 style, still common in legacy code)
    public string ProcessWithTryFinally(string imagePath)
    {
        OcrApi api = null;
        try
        {
            api = OcrApi.Create();
            api.Init(Languages.English);
            return api.GetTextFromImage(imagePath);
        }
        finally
        {
            if (api != null)
                api.Dispose();  // マニュアル null check required
        }
    }

    // Pattern 2: nested using blocks — one for engine, one for image object
    public string ProcessWithNestedUsing(string imagePath)
    {
        using (var api = OcrApi.Create())
        {
            api.Init(Languages.English);
            using (var img = OcrImage.FromFile(imagePath))
            {
                api.SetImage(img);
                return api.GetText();
            }   // img disposed here
        }       // api disposed here — nested indentation grows with each resource
    }

    // Pattern 3: missing disposal — memory leak, common in older service code
    public string ProcessUnsafe(string imagePath)
    {
        var api = OcrApi.Create();   // WARNING: never disposed
        api.Init(Languages.English);
        return api.GetTextFromImage(imagePath);
    }
}
C#

IronOCRのアプローチ:

// Modern C# 8.0+ disposal — flat, readable, no nesting
public class ModernOcrProcessor
{
    private readonly IronTesseract _ocr;  // Injected singleton, never disposed per-request

    public ModernOcrProcessor(IronTesseract ocr) => _ocr = ocr;

    // Pattern 1: using var declaration — scoped to method, no nesting
    public string ProcessDocument(string imagePath)
    {
        using var input = new OcrInput();  // OcrInput is the disposable resource, not the engine
        input.LoadImage(imagePath);
        return _ocr.Read(input).Text;
    }   // input disposed here automatically — no nesting, no try/finally

    // Pattern 2: multiple inputs in one scope — still flat
    public string ProcessMultipleInputs(string imagePath, string pdfPath)
    {
        using var imageInput = new OcrInput();
        imageInput.LoadImage(imagePath);

        using var pdfInput = new OcrInput();
        pdfInput.LoadPdf(pdfPath);

        var imageText = _ocr.Read(imageInput).Text;
        var pdfText = _ocr.Read(pdfInput).Text;

        return $"{imageText}\n{pdfText}";
    }   // both inputs disposed here — zero nesting
}
C#

OcrInput は IronOCR で唯一の廃棄可能なリソースです。 エンジン自体 (IronTesseract) はリクエストごとに廃棄されません — それはシングルトンです。 これにより OcrApi.Create() + api.Init() が強制したリクエストごとの 40–100 MB 言語モデルの再ロードが排除されます。 画像入力ガイド にはストリーム、バイト配列、および URL を含むすべての OcrInput のロード方法が説明されています。

ASP.NET Core コントローラー向け Async Integration

Tesseract.NET SDK には非同期 API はありません。 すべての呼び出しは同期式です。 .NET Core では、非同期コントローラーアクションから同期的なブロッキング操作を呼び出すと、負荷がかかった際にスレッドプールのリソース枯渇リスクが生じます。 一般的な回避策 — 同期呼び出しを Task.Run() でラップする — ブロッキング作業をスレッドプールスレッドにオフロードしますが、スレッドの消費を排除しません。 IronOCR の ReadAsync() は本物の非同期 I/O 統合を提供します。

Tesseract.NET SDK へのアプローチ:

// ASP.NET Core controller — forced workaround for synchronous OCR API
[ApiController]
[Route("api/ocr")]
public class OcrController : ControllerBase
{
    [HttpPost("extract")]
    public async Task<IActionResult> ExtractText(IFormFile file)
    {
        // Must copy upload to temp file — OcrApi does not accept streams directly
        var tempPath = Path.GetTempFileName();
        await using (var stream = System.IO.File.OpenWrite(tempPath))
            await file.CopyToAsync(stream);

        string text;
        try
        {
            // Task.Run wraps synchronous call — still consumes a thread-pool thread
            // Does NOT free the calling thread during OCR processing
            text = await Task.Run(() =>
            {
                using (var api = OcrApi.Create())   // 40-100MB load per request
                {
                    api.Init(Languages.English);
                    return api.GetTextFromImage(tempPath);  // synchronous, blocking
                }
            });
        }
        finally
        {
            System.IO.File.Delete(tempPath);  // マニュアル temp file cleanup
        }

        return Ok(new { text });
    }
}
C#

IronOCRのアプローチ:

// ASP.NET Core controller — genuine async OCR, no temp files, no thread blocking
[ApiController]
[Route("api/ocr")]
public class OcrController : ControllerBase
{
    private readonly IronTesseract _ocr;  // Singleton injected via DI

    public OcrController(IronTesseract ocr) => _ocr = ocr;

    [HttpPost("extract")]
    public async Task<IActionResult> ExtractText(IFormFile file)
    {
        // Load stream directly — no temp file needed
        using var input = new OcrInput();
        input.LoadImage(file.OpenReadStream());  // Stream input, no disk write

        // ReadAsync — genuinely non-blocking, integrates with ASP.NET Core pipeline
        var result = await _ocr.ReadAsync(input);

        return Ok(new
        {
            text = result.Text,
            confidence = result.Confidence
        });
    }
}
C#

一時ファイルの往復通信が終了します。 Task.Run ラッパーは消え去ります。 リクエストごとの OcrApi.Create() およびそれに続く 40–100 MB のロードは消え去ります。 非同期OCRハウツーストリーム入力ガイドでは、キャンセルトークンのサポートを含む、完全な非同期パイプラインについて解説しています。

マルチフレームTIFF処理

フェーズ1の比較記事では、基本的な画像およびPDF処理について取り上げました。 マルチフレーム TIFF は、文書アーカイブ、FAX システム、および医療画像処理パイプラインで一般的な、特有のシナリオです。 Tesseract .NET SDK は System.Drawing.Bitmap を使用して TIFF フレームを手動でイテレートし、各フレームを一時的な PNG ファイルに抽出し、テンポラリファイルに OCR を実行し、クリーンアップを行う必要があります。このパターンはメモリ不足エラーを避けるために大きな文書で明示的な GC 呼び出しを強制します。

Tesseract.NET SDK へのアプローチ:

// Multi-frame TIFF: manual frame extraction to temp files + forced GC
using System.Drawing;
using System.Drawing.Imaging;
using Patagames.Ocr;

public List<string> ProcessMultiFrameTiff(string tiffPath)
{
    var pageTexts = new List<string>();

    using (var api = OcrApi.Create())
    {
        api.Init(Languages.English);

        using (var bitmap = new Bitmap(tiffPath))
        {
            var dimension = new FrameDimension(bitmap.FrameDimensionsList[0]);
            int frameCount = bitmap.GetFrameCount(dimension);

            for (int i = 0; i < frameCount; i++)
            {
                bitmap.SelectActiveFrame(dimension, i);

                // Must write each frame to a temp file — no in-memory path
                var tempPath = Path.GetTempFileName() + ".png";
                bitmap.Save(tempPath, ImageFormat.Png);

                try
                {
                    pageTexts.Add(api.GetTextFromImage(tempPath));
                }
                finally
                {
                    File.Delete(tempPath);  // マニュアル cleanup on every frame
                }

                // Force GC every 10 frames — workaround for memory pressure
                // Slows processing; indicates memory management is manual
                if (i % 10 == 0)
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
            }
        }
    }

    return pageTexts;
}
C#

IronOCRのアプローチ:

// Multi-frame TIFF: one method call, no temp files, no manual GC
using IronOcr;

public List<string> ProcessMultiFrameTiff(string tiffPath)
{
    var ocr = new IronTesseract();

    using var input = new OcrInput();
    input.LoadImageFrames(tiffPath);  // Loads all frames natively — no temp files

    var result = ocr.Read(input);

    // Pages map directly to TIFF frames
    return result.Pages.Select(page => page.Text).ToList();
}
C#

30行が8行に凝縮されました。 テンポラリファイルなし、Bitmap フレームイテレーションなし、GC.Collect() 呼び出しなし。 LoadImageFrames は中間ファイルを書きこまずに任意の大きさのマルチフレーム TIFF を処理します。 TIFFおよびGIF入力ガイドでは、大規模なドキュメントに対するフレームの選択的読み込み(インデックス範囲指定)および進行状況コールバックについて解説しています。

Dockerコンテナのデプロイ準備

開発者の Windows マシン上で動作する Tesseract .NET SDK のコードは、ベースイメージが Linux の場合、Docker のビルドまたは実行ステップで失敗します。 この修正は Dockerfile の微調整ではありません。ネイティブバイナリは Windows 専用であり、Linux ではまったく読み込むことができません。 IronOCR の Linux サポートは、Dockerfile に apt-get の小さな追加を必要とするだけで、アプリケーションコードには何も変更を必要としません。

Tesseract.NET SDK へのアプローチ:

# Dockerfile attempt — fails at runtime on Linux base image
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
# This base image is Linux (Debian) by default
# Tesseract.Net.SDK's Windows native DLLs cannot load here
# Application throws DllNotFoundException on first OCR call

WORKDIR /app
COPY --from=build /app/publish .

# Even copying the Windows tessdata folder has no effect —
# the P/Invoke DLL cannot be loaded regardless of file placement
COPY tessdata/ ./tessdata/

ENTRYPOINT ["dotnet", "MyApp.dll"]
# Runtime error: DllNotFoundException: Unable to load DLL 'libtesseract'
# なし fix available within Tesseract.Net.SDK — requires replacing the library
Text

IronOCRのアプローチ:

# Dockerfile for IronOCR on Linux — add one apt-get line, nothing else changes
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base

# Required system dependency for IronOCR on Debian/Ubuntu base images
RUN apt-get update && apt-get install -y libgdiplus \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY --from=build /app/publish .

# なし tessdata folder — language data is bundled with the IronOcr NuGet packages
# なし platform check code — IronOCR runs identically on Windows and Linux

ENTRYPOINT ["dotnet", "MyApp.dll"]
Text

1 行の apt-get。tessdata フォルダーはありません。 アプリケーション内にプラットフォーム依存のコードは含まれていません。 開発者の Windows マシン上で動作するアプリケーションバイナリは、変更を加えることなく、この Linux コンテナ内でも動作します。 Docker デプロイメントガイド には、Alpine ベースのイメージ(apkapt-get の代わりに使用)や、マルチステージビルドの最適化、ライセンスキー用の環境変数設定が説明されています。 Linux 導入ガイドでは、ベアメタル Linux および WSL2 のシナリオについて解説しています。

Tesseract .NET SDK API から IronOCR へのマッピングリファレンス

Tesseract .NET SDKIronOCR相当値ノート
Install-Package Tesseract.Net.SDKdotnet add package IronOcrIronOCRは、.NET Framework 4.6.2 以降および .NET 5~9 を対象としています。
using Patagames.Ocr;using IronOcr;単一のネームスペース
using Patagames.Ocr.Enums;(not needed)Enums は IronOcr の namespace にあります
OcrApi.Create()new IronTesseract()IronTesseractはスレッドセーフです。 シングルトンとして使用
api.Init(Languages.English)ocr.Language = OcrLanguage.Englishプロパティへの代入であり、メソッド呼び出しではありません
api.Init(言語.英語)言語.ドイツ語)ocr.Language = OcrLanguage.English + OcrLanguage.German
api.GetTextFromImage(path)ocr.Read("path.jpg").Text直接またはOcrInput 経由
api.GetTextFromImage(path) (非同期)await ocr.ReadAsync(input)本当の非同期 — Task.Run ラッパーが不要
OcrImage.FromFile(path)input.LoadImage(path)OcrInputOcrImage を置き換えます
OcrImage.FromBitmap(bitmap)input.LoadImage(bitmap)
new MemoryStream(bytes)OcrImage.FromBitmapinput.LoadImage(bytes)バイト配列の直接サポート
api.SetImage(img); api.GetText()ocr.Read(input).TextOcrInputRead に渡されます
api.GetMeanConfidence()result.Confidenceパーセンテージを返します; also available per-word
api.SetRectangle(x, y, w, h)input.LoadImage(path, new CropRectangle(x, y, w, h))地域ベースの OCR は CropRectangle 経由
api.SetVariable("tessedit_char_whitelist", x)ocr.Configuration.WhiteListCharacters = x
api.SetVariable("tessedit_char_blacklist", x)ocr.Configuration.BlackListCharacters = x
ビットマップフレームの反復処理 + 一時ファイルinput.LoadImageFrames(tiffPath)ネイティブのマルチフレーム TIFF サポート
(synchronous only)result.SaveAsSearchablePdf("out.pdf")Tesseract.NET SDKには同等の機能はありません
(no structured output)result.Pages, result.Words, result.Lines単語レベルの座標と信頼度
GC.Collect() 回避策(not needed)IronOCRは内部でメモリを管理します
プラットフォームチェック: IsOSPlatform(Windows)(remove entirely)IronOCRはクロスプラットフォームです
Tessdataフォルダ管理(remove entirely)NuGet パッケージに同梱されている言語

一般的な移行の問題と解決策

課題 1: プロジェクトのターゲットフレームワークの不一致

Tesseract.NET SDK: Tesseract.Net.SDK を取り除き IronOcr を追加後も、プロジェクトは古い要件から net45 または net472 をターゲットにしています。 IronOCR は net462 および以降をサポートしているため、net45 プロジェクトはパッケージがクリーンにリストアされる前にターゲットフレームワークを更新する必要があります。

解決策: IronOCR を追加する前に .csproj ファイル内の <TargetFramework> を更新します。 段階的な移行期間中に新旧両方のランタイムをサポートする必要がある場合は、マルチターゲティングを使用してください:

<!-- Single modern target (preferred) -->
<TargetFramework>net8.0</TargetFramework>

<!-- Multi-targeting during phased migration — supports both simultaneously -->
<TargetFrameworks>net462;net8.0</TargetFrameworks>
XML

IronOCRは、各ターゲットに対して適切なアセンブリを自動的に特定します。 同じ dotnet add package IronOcr コマンドは両方に対して機能します。 .NET OCRライブラリページには、サポートされているすべてのターゲットフレームワークが記載されています。

課題 2: 静的 OcrApi フィールドが DI シングルトンに置き換えられました

Tesseract.NET SDK: レガシーコードは単一の OcrApi インスタンスを静的フィールドとして登録します(Global.asax、静的サービスロケーター、またはシングルトンラッパークラスにおいて)。 このパターンが必要だったのは、OcrApi がスレッドセーフでなかったためです — スレッド間で一つのインスタンスを共有すると競合状態を引き起こすため、静的フィールドはロックで保護されるか、実際にはフィールド名にもかかわらずリクエストごとに再作成されていました。

解決策: IronTesseract を DI コンテナを通じて真のスレッドセーフシングルトンとして登録します。 ロックを削除し、静的フィールドを削除し、リクエストごとの再作成をすべて削除してください:

// Remove: private static OcrApi _instance; / private static readonly object _lock = new();

// Replace with DI registration in Program.cs
builder.Services.AddSingleton<IronTesseract>();

// In consuming classes — constructor injection
public class DocumentProcessor
{
    private readonly IronTesseract _ocr;
    public DocumentProcessor(IronTesseract ocr) => _ocr = ocr;

    public async Task<string> ProcessAsync(string path)
    {
        using var input = new OcrInput();
        input.LoadImage(path);
        var result = await _ocr.ReadAsync(input);
        return result.Text;
    }
}
C#

課題 3: デプロイ後に Tessdata フォルダーが見つからない

Tesseract.NET SDK: IronOCRへの移行後も、チームによってはCI/CDパイプラインにtessdataのデプロイ手順を残したままにしている場合があります。 ビルドスクリプトおよびデプロイメントマニフェストで参照される tessdata/ フォルダーはもう存在しません — それは古い SDK の言語モデル管理の一部でした。 スクリプトは、存在しなくなったフォルダーをコピーまたは検証しようとすると失敗します。

解決策: デプロイスクリプトからすべての tessdata 参照、.csproj コピーターゲット、Docker COPY コマンド、および CI/CD パイプラインステップを削除します。 IronOCRの言語データは、NuGetパッケージに同梱されています。 dotnet restore を実行すると、言語データが利用可能になります。 これ以外の情報は不要です:

# Remove from CI/CD pipeline
# BEFORE (delete these lines):
# - cp -r tessdata/ $DEPLOY_PATH/tessdata/
# - test -f $DEPLOY_PATH/tessdata/eng.traineddata

# AFTER: nothing — language data is in the NuGet package restore output
dotnet restore   # Downloads IronOcr and any IronOcr.Languages.* packages
dotnet publish   # Includes language data automatically
SHELL

多言語ガイドでは、オフラインまたはエアギャップ環境での展開向けに、特定の言語パックを NuGet パッケージとしてインストールする方法について解説しています。

問題 4: BadImageFormatException の 32/64 ビット不一致について

Tesseract.NET SDK: このSDKには、x86およびx64用のWindowsネイティブバイナリが別々に同梱されています。 AnyCPUをターゲットにしたプロジェクトは、プロセスアーキテクチャによっては誤ったバイナリに解決されることがあります。 エラーはランタイムに BadImageFormatException または DllNotFoundException として表面化し、プロセスアーキテクチャが出力フォルダー内のネイティブ DLL と一致しない場合に発生します。

解決策: IronOCR は各プラットフォームに対応する正しいネイティブバイナリをNuGetパッケージ内でバンドルし、パッケージレイアウトのruntimes/フォルダーを通じて自動的に正しいバイナリを解決します。 Platform ターゲット設定なし、アーキテクチャ条件付きコピーコマンドなし、x64 サブフォルダーを管理する必要なし:

<!-- Remove architecture-specific build configurations from .csproj -->
<!-- BEFORE: Conditional native DLL copy based on Platform target -->
<!--
<ItemGroup Condition="'$(Platform)' == 'x64'">
  <Content Include="$(SolutionDir)libs\x64\*.dll">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
</ItemGroup>
-->

<!-- AFTER: Nothing. IronOCR resolves the correct binary automatically. -->
XML

課題 5: 構成文字列の移行

Tesseract.NET SDK: Tesseract エンジン変数は、Tesseract API リファレンスからの生の文字列キーを使用して api.SetVariable(string name, string value) 経由で設定されます(例:"tessedit_pageseg_mode")。 これらは型指定のない文字列であり、IDEの自動補完機能は利用できません。 タイプミスはサイレントエラーを引き起こします。つまり、変数が無視されるだけで、例外は発生しません。

解決策: IronOCR は ocr.Configuration 上で型付きプロパティとしてエンジンの構成を公開します。 タイプミスはコンパイル時のエラーになります:

// Before: untyped string variables, silent failures on typos
api.SetVariable("tessedit_char_whitelist", "0123456789");
api.SetVariable("tessedit_pageseg_mode", "7");

// After: typed properties, compile-time validation, IDE completion
ocr.Configuration.WhiteListCharacters = "0123456789";
ocr.Configuration.PageSegmentationMode = TesseractPageSegmentationMode.SingleLine;
C#

IronTesseract API リファレンスには、すべての構成プロパティとその型、および許容される値が記載されています。

課題 6: 長時間実行されるバッチジョブの進捗報告

Tesseract.NET SDK: IProgress<t> を使用して進捗を報告するバッチ処理コードはジョブレベルで動作します(ファイルごとにカウンターを増加させる)しかし、単一のドキュメント内では報告できません — GetTextFromImage() 内にはコールバックメカニズムがありません。 500ページのドキュメントの場合、ドキュメント全体が完了するまで進捗バーは動かないままになります。

解決策: IronOCR は OcrInput 上の OcrProgress イベントを通じて組み込みの進捗追跡を提供します。 ページごとの進行状況が更新されるため、長文の複数ページにわたるドキュメントでも正確な進行状況バーを表示できます:

// IronOCR: page-level progress tracking for multi-page documents
using IronOcr;

var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadPdf("large-archive.pdf");

// Subscribe to page-level progress events
input.OcrProgress += (sender, e) =>
{
    Console.WriteLine($"Processing page {e.CurrentPage} of {e.TotalPages} " +
                      $"({e.ProgressPercent:F0}%)");
};

var result = ocr.Read(input);
Console.WriteLine($"Complete: {result.Pages.Count} pages extracted");
C#

進捗追跡ガイドでは、ブラウザクライアントへのリアルタイム進捗プッシュを実現するための、.NET Core SignalRとの統合について解説しています。

Tesseract .NET SDK 移行チェックリスト

移行前

コードに手を加える前に、コードベース全体で Tesseract .NET SDK の使用状況をすべて確認してください:

# Find all files referencing Patagames namespace
grep -rl "Patagames" --include="*.cs" .

# Find all OcrApi instantiation points
grep -rn "OcrApi.Create" --include="*.cs" .

# Find tessdata references in project and build files
grep -rn "tessdata" --include="*.cs" --include="*.csproj" --include="*.yaml" --include="*.yml" .

# Find platform guard checks that can be removed after migration
grep -rn "IsOSPlatform.*Windows" --include="*.cs" .

# Find Task.Run wrappers around synchronous OCR calls
grep -rn "Task.Run" --include="*.cs" . | grep -i "ocr\|image\|text"

# Count distinct OcrApi.Create() call sites to estimate migration scope
grep -c "OcrApi.Create" $(find . -name "*.cs")
SHELL

OcrApi.Create() 呼び出しサイトの件数を記録する — 各サイトはシングルトンとしての注入置き換えの候補です。 近代化のために try/finally 廃棄パターンをメモします。 Application_Start、または静的コンストラクタ初期化で Program.cs に移行するものを識別します。

コードの移行

  1. すべての .csproj ファイルで <TargetFramework>net8.0 (またはターゲットのモダンランタイム)に更新します
  2. 各プロジェクトで dotnet remove package Tesseract.Net.SDK を実行します
  3. dotnet remove package PdfiumViewer (または同等の PDF レンダリングパッケージ)が存在する場合は実行します
  4. 各プロジェクトで dotnet add package IronOcr を実行します
  5. IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";Program.cs もしくはホストビルダーに追加します
  6. DI コンテナーで IronTesseract をシングルトンとして登録します: services.AddSingleton<IronTesseract>()
  7. すべての using Patagames.Ocr; および using Patagames.Ocr.Enums;using IronOcr; で置換します
  8. OcrApi.Create() + api.Init(Languages.X) をコンストラクタに注入された IronTesseract に置き換えます
  9. using (var api = OcrApi.Create()) { ... を置き換えてください blocks withusing var input = new OcrInput()` 宣言
  10. api.GetTextFromImage(path)ocr.Read(input).Text または await ocr.ReadAsync(input) に置き換えます
  11. Task.Run(() => ) を直接 await ocr.ReadAsync(input) に置き換えます
  12. api.GetMeanConfidence()result.Confidence に置き換えます
  13. ビットマップフレームイテレーションTIFFループをinput.LoadImageFrames(tiffPath) に置き換えます
  14. api.SetVariable("tessedit_char_whitelist", x)ocr.Configuration.WhiteListCharacters = x に置き換えます
  15. プロジェクトから tessdata フォルダを削除し、tessdata へのすべてのデプロイメントスクリプトの参照を削除してください

移行後

  • プロジェクトをnet8.0 を対象にコンパイルし、ビルド出力にPatagames の参照が残っていないことを確認してください。
  • アプリケーションを Linux ホストまたは Linux Docker コンテナで実行し、DllNotFoundException がないことを確認します
  • 本番環境の文書から抽出した代表的なサンプル(10~20件)を用いて、OCRテキストの出力が移行前の出力と一致していることを確認する
  • 複数ページの TIFF 処理をテストし、ページ数が元のフレーム数と一致することを確認する
  • ReadAsync() を使用して ASP.NET Core エンドポイントで負荷テストを実行し、スレッドプールメトリックがブロックなしであることを確認します
  • DI コンテナが IronTesseract をシングルトンとして解決することを確認します(リクエスト間で同じインスタンス)
  • tessdataのコピー手順が削除されたため、CI/CDパイプラインがエラーなしで完了することを確認してください
  • Linuxベースイメージ上でDockerイメージのビルドとコンテナの実行をテストする
  • 複数ページのドキュメント(PDFまたはTIFF)において、進行状況イベントが正しく発火することを確認する
  • 正常な文書に対して、信頼度スコアが想定範囲内にあることを確認してください

IronOCRへの移行の主なメリット

**.NETのアップグレードの障害は解消されました。**移行前は、.NET Framework 4.xから.NET 8へのサービス移行計画は、OCRレイヤーで頓挫していました。 移行後、OCRサービスは同じパッケージ参照から、.NET Framework 4.6.2、.NET 6、.NET 8、および.NET 9上でコンパイルおよび実行されます。 アップグレードパスは確保されています。 OCR専用に別個のレガシーランタイム環境を維持していたチームは、単一の最新ランタイム環境に統合することができます。

コンテナーデプロイメントは妥協なしで動作します。 Linux ベースイメージでの DllNotFoundException は排除されました。 開発者の Windows ワークステーションで動作する同じアプリケーションバイナリが Debian または Alpine コンテナ内で、Dockerfile に 1 行の apt-get ラインを追加するだけで実行されます。Kubernetes デプロイメント、Azure Container Apps、および Linux ノードプールの AWS ECS タスクはすべて、Windows コンテナライセンス、より大きなイメージサイズ、またはアーキテクチャ条件付きコードパスなしで動作します。 Docker 導入ガイドおよび Azure ガイドには、各ターゲット環境における正確な設定方法が記載されています。

非同期ファーストパイプラインはスレッドプールの圧力を排除します。 同期 OCR を非同期メソッドでラップする Task.Run の回避策は ReadAsync() に置き換えられます。 ASP.NET Coreのリクエストスレッドは、OCR処理中にブロックされるのではなく解放されます。 高同時実行環境下では、これは単にOCRエンドポイントだけでなく、アプリケーション全体においてリクエストのスループット向上とレイテンシの低減に直結します。

メモリ消費は同時性に比例して減少します。 以前は並行要求ごとに 1 つの OcrApi インスタンスを作成していたサービス — 各インスタンスが 40–100 MB の言語データをロード — は、今そのデータを単一の IronTesseract インスタンスに一度ロードします。 同時リクエスト数が10件の場合、単一の固定負荷と比較して400~1000 MBの差が生じます。 この削減効果はコンテナリソースのメトリクスに即座に反映され、ポッドのメモリ制限の縮小、ポッド密度の向上、およびクラウドインフラコストの削減を可能にします。

最新の C# パターンが .NET Framework の儀式を置き換えます。 try/finally 廃棄ガード、入れ子になった using ブロック、TIFF フレーム間の GC.Collect() 呼び出し — これらすべてが消え去ります。 using var input = new OcrInput() はすべてのリソース管理パターンです。 コードレビューは短めです。 OCRサービスへの新規開発者の導入にかかる時間が短縮されます。OcrResult APIリファレンスには、構造化データ、信頼度スコア、検索可能なPDF出力など、結果オブジェクトモデル全体が記載されており、従来のSDKにおける手動での結果処理パターンを置き換えます。

**商用サポートにより、個人開発者への依存から解放されます。**Tesseract.NET SDKは個人開発者によって運営されており、SLA(サービスレベル契約)や組織的な継続性の保証はありません。 IronOCRは、専用のサポートチャネル、文書化されたセキュリティ情報開示プロセス、および企業の調達要件を満たすライセンス条項を備えた商用企業であるIron Softwareによって開発されています。 IronOCR ライセンシングページ は、サポートティアと永久ライセンスモデル($999 から)をカバーしており、Patagames SDK の料金と、モダンに進化する .NET スタックでの Windows 専用インフラの隠れたコストの両方を置き換えます。

ご注意: PDFiumとTesseractはそれぞれの所有者の登録商標です。 このサイトは、Chromium ProjectやGoogleから提携、承認、提供されていません。 すべての製品名、ロゴ、およびブランドは各所有者の所有物です。 比較は情報提供のみを目的としており、執筆時点で公開されている情報を反映しています。

関連する記事

Key in blue circle

無料の30日間トライアルキーをすぐに入手してください。

Your trial license will be sent to your email address

制限なし。100% ロック解除済み。クレジットカード不要。

bullet_checkedクレジットカードやアカウントの作成は不要です。制限なし。100% ロック解除済み。クレジットカード不要。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
義務のない相談を受ける
下記のフォームを記入するか、sales@ironsoftware.comにメールしてください。
あなたの詳細は常に守秘されます。
世界中の数百万人のエンジニアから信頼されています。
ライセンスはより安く
あなたの無料30日間の試用キーをすぐに入手。
クレジットカードやアカウントの作成は不要です。