このシナリオでは、ABBYY FineReader Engine を使用してバーコードを読み取ります。バーコードの読み取りは、たとえば文書の自動仕分け、Document Management System による文書処理、文書のインデックス作成や分類のために必要になる場合があります。
このシナリオは、他のシナリオの一部として使用することもできます。たとえば、高速プロダクションスキャナーでスキャンした文書をバーコードで仕分けしたり、長期保管用に準備した文書を、バーコード値に基づいてアーカイブ用の Document Management System に格納したりできます。
文書からバーコードを抽出する際、システムはすべてのバーコードを検出することも、特定の種類かつ特定の値を持つバーコードのみを検出することもできます。また、バーコードの値を取得して、そのチェックサムを計算することもできます。バーコード認識で最高の速度と品質を得るには、次の点に注意してください。
-
最適な解像度である 300 dpi のカラー画像を使用します。
-
プロファイルを使用して認識速度を調整します (詳細は Working with Profiles を参照してください) 。
認識したバーコード値は、後続の処理に最も適した形式で保存できます。たとえば、TXT に保存できます。
このトピックで提供されるコードサンプルは、Windows 固有です。
以下では、このシナリオで ABBYY FineReader Engine 12 を使用する推奨方法について詳しく説明します。ここで推奨する方法では、このシナリオに最も適していると考えられる処理設定を使用します。
ステップ 1. ABBYY FineReader Engine の読み込み
ABBYY FineReader Engine を使用するには、まず Engine オブジェクトを作成する必要があります。Engine オブジェクトは ABBYY FineReader Engine のオブジェクト階層における最上位のオブジェクトであり、各種グローバル設定、一部の処理メソッド、およびその他のオブジェクトを作成するためのメソッドを提供します。Engineオブジェクトを作成するには、InitializeEngine関数を使用します。Engineオブジェクトを読み込む他の方法 (Win) も参照してください。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 の読み込み中にエラーが発生しました";
}
}
このシナリオに最適な設定は、Engine オブジェクトの LoadPredefinedProfile メソッドを使用して選択できます。このメソッドは、使用する設定プロファイル名を入力パラメーターとして受け取ります。プロファイルの詳細については、Working with Profiles を参照してください。ABBYY FineReader Engine は、このシナリオ向けに 2 種類の設定をサポートしています。| プロファイル名 | 説明 |
|---|
| BarcodeRecognition_Accuracy | バーコードのみを抽出します (テキスト、画像、表は検出されません) 。この設定は精度重視で最適化されています。 <Warning> このプロファイルを使用するには、ライセンスで Barcode Autolocation モジュールを利用可能にしておく必要があります。 </Warning> |
| BarcodeRecognition_Speed | バーコードのみを抽出します (テキスト、画像、表は検出されません) 。この設定は処理速度重視で最適化されています。 <Warning> このプロファイルを使用するには、ライセンスで Barcode Autolocation モジュールを利用可能にしておく必要があります。 </Warning> |
// 定義済みプロファイルを読み込む
engine.LoadPredefinedProfile("BarcodeRecognition_Speed");
// 定義済みプロファイルを読み込む
Engine->LoadPredefinedProfile( L"BarcodeRecognition_Speed" );
処理に使用する設定を変更する場合は、対応する Parameter オブジェクトを使用してください。詳細については、以下の Additional optimization セクションを参照してください。
ABBYY FineReader Engine には、複数ページの文書を処理するための FRDocument オブジェクトが用意されています。文書の画像を読み込んで前処理するには、FRDocument オブジェクトを作成し、そこに画像を追加する必要があります。方法は次のいずれかです。// 画像ファイルから FRDocument オブジェクトを作成する
FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );
// 画像ファイルを開いて FRDocument オブジェクトを作成する
FREngine::IFRDocumentPtr frDocument = Engine->CreateFRDocumentFromImage( L"C:\\MyImage.tif", 0 );
BarcodeRecognition プロファイルが読み込まれている場合は、FRDocument オブジェクトの Process メソッドを使用して、バーコードだけを抽出できます。この場合、ABBYY FineReader Engine が検出するのはバーコードを含むブロックのみで、その他のブロックは検出されません。認識されたバーコードブロックには、文書のページを表す FRPage オブジェクトのサブオブジェクトである Layout オブジェクトからアクセスできます。特定の種類のバーコードを読み取るには、BarcodeParams オブジェクトで適切なパラメーターを指定し、上記のいずれかの関数に BarcodeParams オブジェクトをパラメーターとして渡します。// BarcodeRecognition プロファイルが読み込まれている場合、
// バーコードが仕様に準拠していれば、
// 処理メソッドに追加のパラメーターを渡す必要はありません
frDocument.Process( null );
// 特定の種類のバーコードを読み取る必要がある場合
// DocumentProcessingParams オブジェクトを作成します
FREngine.IDocumentProcessingParams dpp = engine.CreateDocumentProcessingParams();
// 必要なパラメーターを指定します
dpp.PageProcessingParams.PageAnalysisParams.BarcodeParams.Type = ( int )FREngine.BarcodeTypeEnum.BT_Code39;
// これらのパラメーターでバーコードを認識します
frDocument.Process( dpp );
// BarcodeRecognition プロファイルが読み込まれている場合、
// バーコードが仕様に準拠していれば、
// 処理メソッドに追加のパラメーターを渡す必要はありません
frDocument->Process( 0 );
// 特定の種類のバーコードを読み取る必要がある場合
// DocumentProcessingParams オブジェクトを作成します
FREngine::IDocumentProcessingParamsPtr params = Engine->CreateDocumentProcessingParams();
// 必要なパラメーターを指定します
params->PageProcessingParams->PageAnalysisParams->BarcodeParams->Type = FREngine::BT_Code39;
// これらのパラメーターでバーコードを認識します
frDocument->Process( params );
認識されたバーコードの値をファイルに保存するには、FRDocument オブジェクトの Export メソッドを使用し、FileExportFormatEnum 定数をパラメーターの 1 つとして指定します。このシナリオでは、たとえば TXT 形式にエクスポートできます。対応するエクスポートオブジェクトを使用して、エクスポートの既定のパラメーターを変更することもできます。詳細については、以下の 特定のタスク向けの追加最適化 を参照してください。FRDocument オブジェクトの使用が完了したら、このオブジェクトで使用していたすべてのリソースを解放してください。IFRDocument::Close メソッドを使用します。// 認識されたバーコードを任意の形式(例: TXT)で保存します
frDocument.Export( "C:\\barcodes.txt", FREngine.FileExportFormatEnum.FEF_TextUnicodeDefaults, null );
// FRDocument オブジェクトを解放します
frDocument.Close();
// 認識されたバーコードを任意の形式(例: TXT)で保存します
frDocument->Export( L"C:\\barcodes.txt", FREngine::FEF_TextUnicodeDefaults, 0 );
// FRDocument オブジェクトを解放します
frDocument->Close();
ステップ 6. ABBYY FineReader Engine のアンロード
ABBYY FineReader Engine での作業が完了したら、Engine オブジェクトをアンロードする必要があります。これを行うには、エクスポート関数 DeinitializeEngine を使用します。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;
}
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"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 を参照してください。
以下は、各処理段階のパラメーター設定に関する追加情報を参照できるヘルプファイル内のセクションです。
- バーコードの抽出と読み取り
- BarcodeParams オブジェクト
このオブジェクトでは、バーコードの解析および読み取りのパラメーターを設定できます。
- バーコードの認識
バーコード認識における特殊なケースを説明し、バーコードを扱う際のヒントを紹介します。
- バーコードの種類
ABBYY FineReader Engine 12 でサポートされているバーコードの一覧と、その簡単な説明です。
- FRDocument オブジェクト
バーコードの値以外にも、文書に含まれるほかの情報を抽出する必要がある場合があります。その場合は、FRDocument オブジェクトのメソッドを使用できます。
- PageProcessingParams オブジェクト
このオブジェクトでは、文書全体に対する解析および認識のパラメーターを設定できます。このオブジェクトを使用すると、バーコードの値を認識するかどうかを指定できます。バーコード読み取りのパラメーターには、PageAnalysisParams サブオブジェクトの BarcodeParams プロパティおよび DetectBarcodes プロパティからアクセスできます。
- Layout と Blocks の操作
バーコードブロックを手動でマークし、その解析および読み取りのパラメーターを指定することもできます。このセクションでは、ブロックの操作について詳しく説明します。
- 認識されたバーコード値の操作
- BarcodeBlock オブジェクト
このオブジェクトの Text プロパティおよび BarcodeText プロパティには、認識によって取得されたバーコードの値が格納されます。このオブジェクトのその他のプロパティを使用すると、バーコードの種類、向き、その他のパラメーターを取得できます。
- エクスポート
基本的な使用シナリオの実装