メインコンテンツへスキップ
このシナリオの結果として、編集可能なDocumentが得られます。 このシナリオでは、Document画像を元の書式を保ったまま認識し、データを編集可能なファイル形式で保存します。その結果、Documentの編集可能なバージョンを取得でき、誤りの確認や修正を簡単に行えます。また、テキストの全部または一部をコピーして再利用することもできます。 Documentはいくつかの処理ステップを経ますが、その一部は他の一般的なシナリオとはやや異なります。
  1. スキャン画像または写真の前処理
スキャナーやデジタルカメラで取得した画像は、光学認識を行う前に多少の調整が必要になる場合があります。たとえば、ノイズの多い画像やテキスト行がゆがんだ画像では、光学認識を正しく行うために補正が必要になります。
  1. Document構造と書式を完全に復元する認識
Documentを認識する際には、Documentのさまざまなレイアウト要素 (テキスト、表、画像、区切り線など) が識別されます。Document合成の過程ではDocumentの論理構造が復元され、ページ合成によってDocumentの書式 (フォント、スタイルなど) も完全に復元されます。
  1. 編集可能な形式へのエクスポート
認識されたDocumentは、RTF や DOCX などの編集可能な形式で保存されます。

シナリオの実装

このトピックで提供するコードサンプルは、Windows 専用です。
以下では、ABBYY FineReader Engine 12 を使用してDocumentを変換するための推奨手順について詳しく説明します。ここで提案する方法では、この用途に最適な処理設定を使用します。
ABBYY FineReader Engine を使用するには、まず Engine オブジェクトを作成する必要があります。Engine オブジェクトは ABBYY FineReader Engine のオブジェクト階層における最上位のオブジェクトであり、さまざまなグローバル設定、一部の処理メソッド、およびその他のオブジェクトを作成するためのメソッドを提供します。Engineオブジェクトを作成するには、InitializeEngine関数を使用します。Engineオブジェクトを読み込むその他の方法 (Win) も参照してください。

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // FREngine.dll へのフルパス、Customer Project ID、
        // および該当する場合はオンライン ライセンス トークンファイルへのパスとオンライン ライセンス パスワードを使用して、これらの変数を初期化します
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // FREngine.dll ライブラリを読み込む
        dllHandle = LoadLibraryEx(enginePath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
           
        try
        {
            if (dllHandle == IntPtr.Zero)
            {
                throw new Exception("読み込めません: " + enginePath);
            }
            IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine");
            if (initializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("InitializeEngine 関数が見つかりません");
            }
            IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine");
            if (deinitializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("DeinitializeEngine 関数が見つかりません");
            }
            IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow");
            if (dllCanUnloadNowPtr == IntPtr.Zero)
            {
                throw new Exception("DllCanUnloadNow 関数が見つかりません");
            }
            // ポインターをデリゲートに変換する
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // InitializeEngine 関数を呼び出す
            // オンライン ライセンス ファイルへのパスとオンライン ライセンス パスワードを渡す
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // FREngine.dll ライブラリを解放する
            engine = null;
            // FreeLibrary 呼び出し前にすべてのオブジェクトを削除する
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Kernel32.dll 関数
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags);
    private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);
    // FREngine.dll 関数
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate int InitializeEngine(string customerProjectId, string licensePath, 
        string licensePassword, string tempFolder, string dataFolder, bool isSharedCPUCoresMode, 
        ref FREngine.IEngine engine);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DeinitializeEngine();
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DllCanUnloadNow();
    // プライベート変数
    private FREngine.IEngine engine = null;
    // FREngine.dll へのハンドル
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

C++ (COM)

// これらの変数を FREngine.dll へのパス、FineReader Engine の Customer Project ID、
// および該当する場合はオンライン ライセンス トークンとオンライン ライセンス パスワードへのパスで初期化してください
wchar_t* FreDllPath;
wchar_t* CustomerProjectId;
wchar_t* LicensePath;  // オンライン ライセンスを使用しない場合は、これらの変数に空の文字列を割り当ててください
wchar_t* LicensePassword;
// FREngine.dll のハンドル
static HMODULE libraryHandle = 0;
// グローバル FineReader Engine オブジェクト
FREngine::IEnginePtr Engine;
void LoadFREngine()
{
    if( Engine != 0 ) {
    // 読み込み済み
    return;
    }
    // ステップ 1: FREngine.dll を読み込む
    if( libraryHandle == 0 ) {
        libraryHandle = LoadLibraryEx( FreDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
        if( libraryHandle == 0 ) {
            throw L"ABBYY FineReader Engine の読み込み中にエラーが発生しました";
        }
    }
    // ステップ 2: Engine オブジェクトを取得する
    typedef HRESULT ( STDAPICALLTYPE* InitializeEngineFunc )( BSTR, BSTR, BSTR, BSTR, 
        BSTR, VARIANT_BOOL, FREngine::IEngine** );
    InitializeEngineFunc pInitializeEngine =
    ( InitializeEngineFunc )GetProcAddress( libraryHandle, "InitializeEngine" );
    if( pInitializeEngine == 0 || pInitializeEngine( CustomerProjectId, LicensePath, 
        LicensePassword, L"", L"", VARIANT_FALSE, &Engine ) != S_OK ) {
    UnloadFREngine();
    throw L"ABBYY FineReader Engine の読み込み中にエラーが発生しました";
    }
}
ABBYY FineReader Engine では、このシナリオに最適なすべての処理設定を、Engine オブジェクトの LoadPredefinedProfile メソッドを使って読み込めます。このメソッドは、入力パラメーターとしてプロファイル名を受け取ります。詳しくは、プロファイルの操作 を参照してください。ABBYY FineReader Engine では、このシナリオ向けに 2 種類の設定が用意されています。

プロファイル名

説明

DocumentConversion_Accuracy

この設定は精度重視で最適化されています:

  • 最高品質。フォントスタイルの検出と、Documentの論理構造の完全な合成を有効にします。

DocumentConversion_Normal

この設定は処理速度重視で最適化されています:

  • 最高品質。フォントスタイルの検出と、Documentの論理構造の完全な合成を有効にします。
  • 画像の向きは補正されません。
  • Document解析処理が高速化されます。

C#

// 定義済みプロファイルを読み込む
engine.LoadPredefinedProfile("DocumentConversion_Normal");

C++ (COM)

// 定義済みプロファイルを読み込む
Engine->LoadPredefinedProfile( L"DocumentConversion_Normal" );
処理設定を変更する場合は、適切な Parameter オブジェクトを使用してください。詳しくは、以下の 特定のタスク向けの追加最適化 を参照してください。
ABBYY FineReader Engine には、複数ページのDocumentを処理できる FRDocument オブジェクトが用意されています。このオブジェクトを使用すると、元のテキスト、段組み、フォント、スタイルなどを保持したまま、Documentの論理構造を維持できます。1 つのDocumentの画像を読み込んで前処理するには、FRDocument オブジェクトを作成し、そこに画像を追加する必要があります。方法は次のいずれかです。
  • Engine オブジェクトの CreateFRDocumentFromImage メソッドを使用して FRDocument オブジェクトを作成します。このメソッドは FRDocument オブジェクトを作成し、指定したファイルから画像を読み込みます。
  • Engine オブジェクトの CreateFRDocument メソッドを使用して FRDocument オブジェクトを作成し、その後、作成した FRDocument オブジェクトにファイルから画像を追加します (FRDocument オブジェクトの AddImageFileAddImageFileWithPassword、または AddImageFileWithPasswordCallback メソッドを使用します) 。

C#

// 画像ファイルから FRDocument オブジェクトを作成する
FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );

C++ (COM)

// 画像ファイルから FRDocument オブジェクトを作成する
FREngine::IFRDocumentPtr frDocument = Engine->CreateFRDocumentFromImage( L"C:\\MyImage.tif", 0 );
読み込んだ DocumentConversion_Normal プロファイルによる画像の前処理には、向きの検出は含まれていません。画像の向きを自動的に検出する場合は、追加のパラメーターを設定し、対応するオブジェクトを前処理関数に渡す必要があります。詳しくは、以下の 特定のタスク向けの追加最適化 を参照してください。
Documentを認識するには、FRDocument オブジェクトの解析メソッドと認識メソッドを使用することをお勧めします。このオブジェクトには、Documentの解析、認識、合成を行うためのさまざまなメソッドが用意されています。Documentの解析、認識、合成を 1 回で実行できる最も便利なメソッドは、Process メソッドです。このメソッドは、マルチプロセッサおよびマルチコアシステムの並列処理機能も最も効率的に活用します。一方、PreprocessAnalyzeRecognize、および Synthesize の各メソッドを使用して、前処理、解析、認識、合成を順に実行することもできます。

C#

// ドキュメントを分析、認識、合成します
// 追加のパラメーターは処理プロファイルで設定されるため不要です
frDocument.Process( null );

C++ (COM)

// ドキュメントを分析、認識、合成します
// 追加のパラメーターは処理プロファイルで設定されるため不要です
frDocument->Process( 0 );
認識したDocumentを保存するには、FRDocument オブジェクトの Export メソッドを使用し、パラメーターの 1 つとして FileExportFormatEnum 定数を指定します。対応するエクスポート オブジェクトを使用すると、エクスポートの既定のパラメーターを変更できます。詳しくは、以下の 特定のタスク向けの追加最適化 を参照してください。FRDocument オブジェクトの使用が完了したら、このオブジェクトが使用していたすべてのリソースを解放してください。IFRDocument::Close メソッドを使用します。

C#

// 認識したドキュメントを編集可能な形式(たとえば RTF)で保存します
frDocument.Export( "C:\\MyText.rtf", FREngine.FileExportFormatEnum.FEF_RTF, null );
// FRDocument オブジェクトを解放します
frDocument.Close();

C++ (COM)

// 認識したドキュメントを編集可能な形式(たとえば RTF)で保存します
frDocument->Export( L"C:\\MyText.rtf", FREngine::FEF_RTF, 0 );
// FRDocument オブジェクトを解放します
frDocument->Close();
ABBYY FineReader Engine での作業が完了したら、Engine オブジェクトをアンロードする必要があります。そのためには、エクスポート関数 DeinitializeEngine を使用します。

C#

public class EngineLoader : IDisposable
{
    // FineReader Engine をアンロードする
    public void Dispose()
    {
        if (engine == null)
        {
            // Engine はロードされていない
            return;
        }
        engine = null;
        // FreeLibrary を呼び出す前にすべてのオブジェクトを削除する
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        int hresult = deinitializeEngine();
 
        hresult = dllCanUnloadNow();
        if (hresult == 0)
        {
            FreeLibrary(dllHandle);
        }
        dllHandle = IntPtr.Zero;
        initializeEngine = null;
        deinitializeEngine = null;
        dllCanUnloadNow = null;
        // クリーンアップ後に例外をスローする
        Marshal.ThrowExceptionForHR(hresult);
    }
    // Kernel32.dll の関数
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags);
    private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);
    // FREngine.dll の関数
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate int InitializeEngine( string customerProjectId, string LicensePath, string LicensePassword, , , , ref FREngine.IEngine engine);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DeinitializeEngine();
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DllCanUnloadNow();
    // プライベート変数
    private FREngine.IEngine engine = null;
    // FREngine.dll へのハンドル
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

C++ (COM)

void UnloadFREngine()
{
 if( libraryHandle == 0 ) {
  return;
 }
 // Engine オブジェクトを解放する
 Engine = 0;
 // FineReader Engine を終了する
 typedef HRESULT ( STDAPICALLTYPE* DeinitializeEngineFunc )();
 DeinitializeEngineFunc pDeinitializeEngine =
  ( DeinitializeEngineFunc )GetProcAddress( libraryHandle, "DeinitializeEngine" );
 if( pDeinitializeEngine == 0 || pDeinitializeEngine() != S_OK ) {
  throw L"Error while unloading ABBYY FineReader Engine";
 }
 // これで FREngine.dll ライブラリを安全に解放できる
 FreeLibrary( libraryHandle );
 libraryHandle = 0;
}

必要なリソース

FREngineDistribution.csv ファイルを使用すると、アプリケーションの動作に必要なファイルのリストを自動的に作成できます。このシナリオで処理するには、列 5 (RequiredByModule) で次の値を選択します。 Core Core.Resources Opening Opening, Processing Processing Processing.OCR Processing.OCR, Processing.ICR Processing.OCR.NaturalLanguages Processing.OCR.NaturalLanguages, Processing.ICR.NaturalLanguages Export Export, Processing 標準シナリオを変更する場合は、それに応じて必要なモジュールも変更してください。また、インターフェイス言語、認識言語、およびアプリケーションで使用する追加機能も指定する必要があります (たとえば、PDF ファイルを開く必要がある場合は Opening.PDF、CJK languages のテキストを認識する必要がある場合は Processing.OCR.CJK を指定します) 。詳細については、Working with the FREngineDistribution.csv File を参照してください。

特定のタスク向けの追加の最適化

以下は、Documentを編集可能な形式に変換する各段階での設定のカスタマイズに関する追加情報を含むヘルプトピックの概要です。
  • スキャン - Windows のみ
    • スキャン
      Documentをスキャンするための ABBYY FineReader Engine のシナリオの説明です。
  • 認識
    • 前処理、解析、認識、および合成のパラメーターの調整
      解析、認識、および合成のパラメーターオブジェクトを使用してDocument処理をカスタマイズします。
    • 手書き文字を認識する
      DocumentConversion_*** プロファイルには、手書き文字や手書きの活字体の認識は含まれていません。手書き文字を認識する必要がある場合は、PageAnalysisParams オブジェクトの DetectHandwritten プロパティを TRUE に設定します。
    • PageProcessingParams Object
      このオブジェクトでは、解析および認識のパラメーターをカスタマイズできます。このオブジェクトを使用すると、検出する画像およびテキストの特性 (反転画像、向き、バーコード、認識言語、認識エラーの許容範囲) を指定できます。
    • SynthesisParamsForPage Object
      このオブジェクトには、合成時にページの書式を復元するためのパラメーターが含まれています。
    • SynthesisParamsForDocument Object
      このオブジェクトでは、Document合成 (構造および書式の復元) をカスタマイズできます。
    • MultiProcessingParams Object - Linux および Windows で実装
      大量の画像を処理する場合、同時処理が役立つことがあります。この場合、画像のオープンと前処理、レイアウト解析、認識、エクスポートの各処理で負荷がプロセッサ コアに分散されるため、処理を高速化できます。
      読み取りモード (同時または逐次) は、MultiProcessingMode プロパティを使用して設定します。RecognitionProcessesCount プロパティは、起動できるプロセス数を制御します。
  • エクスポート
    • エクスポート パラメーターの調整
      エクスポート パラメーター オブジェクトを使用してDocumentのエクスポートをカスタマイズします。
    • RTFExportParams Object
      このオブジェクトでは、RTF/DOCX/ODT 保存形式のパラメーターをカスタマイズできます。
    • HTMLExportParams Object
      このオブジェクトでは、HTML 形式へのエクスポートをカスタマイズできます。
    • PPTExportParams Object
      PPTX 保存形式のパラメーターをカスタマイズするためのオブジェクト。

関連項目

基本的な利用シナリオの実装