在此情境中,ABBYY FineReader Engine 用於讀取條碼。例如,為了自動分隔文件、供文件管理系統處理,或為文件建立索引與分類,可能都需要讀取條碼。
此情境也可作為其他情境的一部分使用。例如,以高速生產型掃描器掃描的文件可藉由條碼進行分隔,或是為長期保存而準備的文件,可根據其條碼值存入歸檔文件管理系統中。
從文字中擷取條碼時,系統可偵測所有條碼,也可僅偵測特定類型且具有特定值的條碼。系統可以取得條碼值並計算其校驗碼。若要以最快速度和最佳品質取得條碼辨識結果:
使用最佳解析度為 300 dpi 的彩色圖片。
使用設定檔調整辨識速度 (詳見 使用設定檔 ) 。
辨識出的條碼值可儲存為最便於後續處理的格式,例如 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,
// 以及(如適用)Online License 權杖和 Online License 密碼填入這些變數
wchar_t * FreDllPath;
wchar_t * CustomerProjectId;
wchar_t * LicensePath; // 若不使用 Online License,請將這些變數設為空字串
wchar_t * LicensePassword;
// FREngine.dll 的 HANDLE
static HMODULE libraryHandle = 0 ;
// 全域 FineReader Engine 物件
FREngine ::IEnginePtr Engine;
void LoadFREngine ()
{
if ( Engine != 0 ) {
// 已載入
return ;
}
// 第一步:載入 FREngine.dll
if ( libraryHandle == 0 ) {
libraryHandle = LoadLibraryEx ( FreDllPath, 0 , LOAD_WITH_ALTERED_SEARCH_PATH );
if ( libraryHandle == 0 ) {
throw L"載入 ABBYY FineReader Engine 時發生錯誤" ;
}
}
// 第二步:取得 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 方法,選取最適合的設定。此方法會接受所用設定檔的名稱作為輸入參數。如需設定檔的詳細資訊,請參閱 使用設定檔 。 ABBYY FineReader Engine 支援此情境的 2 種設定: Profile name Description BarcodeRecognition_Accuracy 僅擷取條碼 (不會偵測文字、圖片或表格) 。此設定已針對準確度最佳化。 <Warning> 此設定檔需要授權中包含 Barcode Autolocation 模組。 </Warning> BarcodeRecognition_Speed 僅擷取條碼 (不會偵測文字、圖片或表格) 。此設定已針對處理速度最佳化。 <Warning> 此設定檔需要授權中包含 Barcode Autolocation 模組。 </Warning>
// 載入預先定義的設定檔
engine . LoadPredefinedProfile ( "BarcodeRecognition_Speed" );
// 載入預先定義的設定檔
Engine -> LoadPredefinedProfile ( L"BarcodeRecognition_Speed" );
如果您想變更處理所使用的設定,請使用對應的參數物件。如需更多資訊,請參閱下方的 其他最佳化 一節。
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 只會偵測含有條碼的區塊,不會偵測其他區塊。您可以透過 Layout 物件存取已辨識的條碼區塊;它是 FRPage 物件的子物件,而 FRPage 物件代表文件中的一個頁面。 若要讀取特定類型的條碼,請指定 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 常數指定為其中一個參數。例如,在此情境中可匯出為 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 。
以下是說明檔中可供您參考的章節,您可以在其中找到關於為各個處理階段設定參數的其他資訊:
擷取並讀取條碼
使用已辨識的條碼值
BarcodeBlock Object 此物件的 Text 和 BarcodeText Properties 包含透過辨識取得的條碼值。此物件的其他 Properties 可用來取得條碼類型、方向及其他參數。
匯出
基本使用情境實作