如何构建强大的文档成像工作流程
使用 ImageGear Professional 和 Barcode Xpress。
集成 ImageGear Professional 和 Barcode Xpress
条形码索引是大多数电子文档工作流程中的常见步骤。文档检索需要能够扫描页面以查找条形码是否存在,然后返回页面上每个条形码的值。通过结合 ImageGear 和 Barcode Xpress 的强大功能,应用程序开发人员能够打开 100 种不同的文档图像格式,然后识别和解码文档中找到的任何一维或二维条形码。本文档的其余部分将介绍如何将图像数据从 ImageGear Professional 传递到 Barcode Xpress,然后返回页面上找到的任何条形码的值。
示例代码简介
本白皮书教程以 ImageGear Professional 帮助文件“入门”部分中的示例代码为起点。ImageGear Professional 是一个非常强大的工具,能够处理多种文件类型和压缩技术。这些功能并非始终处于激活状态;相反,ImageGear 使用模块化系统,允许开发人员仅使用其特定应用程序所需的功能。本白皮书的目标是提供一个关于将 Barcode Xpress 与 ImageGear Professional 结合使用的基本介绍。因此,我们不会添加任何额外的 ImageGear 模块,因此某些图像格式可能无法通过示例代码打开。onOpenDocument()
函数将在无法打开文件时通知用户。为了对此错误向用户提供反馈,我们将对“入门”指南中的函数进行以下更改:
替换
//ErrorReport
有了
LPCSTR error = "ImageGear was unable to open the file"; MessageBox(NULL, error, "Error", MB_OK);
建议您构建自己的错误检查代码,以便在不实现 ImageGear Professional 支持的所有文件类型的情况下更好地处理这种情况。
添加 Barcode Xpress
接下来,我们需要将 Barcode Xpress 组件添加到 ImageGear 示例项目中。右键单击项目名称并选择“属性”。打开“配置属性”->“C/C++”->“常规”,然后添加“BarcodeXpress8_Events.h”的位置(通常是“C:\Users\Public\Documents\Accusoft\BarcodeXpress\V8.0\Samples\ActiveX-COM\VC++\VS2008\Include”)
然后将以下行添加到 stdafx.h
#import "Accusoft.BarcodeXpress8.ActiveX.dll"
#include "BarcodeXpress8_Events.h"
这些代码行导入 ActiveX 控件并包含包含我们可用的所有命令的头文件。
在 IGSampleView.h 中,将以下代码添加到类变量中,以设置我们将稍后使用的指针
private:
CBarcodeXpress* m_ppIBarcodeXpress;
IBarcodeXpressPtr pBarcodeX;
添加触发器
现在,通过转到“视图”->“其他窗口”->“资源视图”来打开资源视图。展开“菜单”文件夹并打开 IDR_MAINFRAME。添加一个名为“Barcode”的新项和一个名为“Scan”的子项。
为新菜单项分配 ID “ID_SCANBARCODES”。
然后打开类视图,右键单击 CIGSAMPLEView 并选择“属性”。打开“事件”(闪电图标,从左起第四个)。向下滚动到 ID_SCANBARCODES 并展开它。在“COMMAND”下拉菜单中,选择“<添加> OnScanbarcodes”
添加以下代码
m_ppIBarcodeXpress = new CBarcodeXpress(this, 1);
pBarcodeX = m_ppIBarcodeXpress->pBarcodeXpress;
findBarcodes();
第一行初始化指针以指向 BarcodeXpress COM 对象。
第二行设置我们将用于进行工作的指针。
第三行引用将完成所有繁重工作的函数。我们将在稍后设置它。
扫描条形码
在类视图中,右键单击 CIGSampleView 并选择“添加”->“添加函数”。
声明一个返回类型为“void”且名称为“findBarcodes”的函数。
最后,我们将编写代码,将 DIB 传递给 Barcode Xpress 以扫描条形码,并将图像中找到的每个条形码的值保存起来。我们在代码中添加了注释来解释每一步的操作。
void CIGSampleView::findBarcodes(void)
{
//This will allow us to get the HIGEAR from the main window
CIGSampleDoc* pDoc = GetDocument();
//We'll use this local HIGEAR to scan for barcodes, but we'll assign it later
HIGEAR myhIGear = (HIGEAR)NULL;
//This variable is used to collect errors from the ImageGear functions
AT_ERRCOUNT nErrCount = 0;
//These variables will be used to determine the size of the image
AT_DIMENSION nWidth, nHeight;
UINT nBpp;
//These variables are used to export the DIB from the HIGEAR for use by BarcodeXpress
AT_INT nDibSize;
AT_DIB_EXPORT_OPTIONS Options;
LPAT_DIB hDib;
//This variable will hold the number of barcodes found by BarcodeXpress
int numBarcodes;
//These variables are used to format a message about the data in the barcodes
TCHAR dataFormat[] = _T(" Barcode #%1!d!\n\r Code Name: %2!s!\n\r Value: %3!s!\n\rX Position: %4!d!\n\rY Position: %5!d!\n\r Height: %6!d! %n Width: %7!d! %n Confidence: %8!d! %n%n");
TCHAR dataFormatShort[] = _T(" Barcode #%1!d!\n\r Code Name: %2!s!\n\r Value: %3!s! \n\r Confidence: %4!d! %n%n");
CString totalData, data;
//These variables are used to display the time it took for BarcodeXpress to run
LARGE_INTEGER start, end, freq;
INT64 ticks;
CString timeStr = _T("");
double ms;
//First, we'll make sure that we're receiving a HIGEAR from the main window.
if(IG_image_is_valid(pDoc->hIGear))
{
//Then, we'll assign it to our local copy and get its dimensions
myhIGear = pDoc->hIGear;
nErrCount = IG_image_dimensions_get(myhIGear, &nWidth, &nHeight, &nBpp);
//If we successfully get the dimensions, we'll supply them to BarcodeXpress as the area to scan, assuming we want to scan the entire image
if (nErrCount == 0)
{
pBarcodeX->ReaderAreaHeight = nHeight;
pBarcodeX->ReaderAreaWidth = nWidth;
pBarcodeX->ReaderAreaX = 0;
pBarcodeX->ReaderAreaY = 0;
}
//This block of code takes the supplied HIGEAR and extracts the information into a DIB
memset(&Options, 0, sizeof(AT_DIB_EXPORT_OPTIONS));
Options.Format = IG_DIB_EXPORT_FORMAT_IG_LEGACY;
Options.UseAlpha = FALSE;
nErrCount = IG_image_DIB_export_size_calc(myhIGear, &nDibSize, &Options);
HGLOBAL handleDib = GlobalAlloc(GHND, nDibSize);
hDib = (LPAT_DIB)GlobalLock(handleDib);
nErrCount = IG_image_DIB_export(myhIGear, hDib, nDibSize, &Options);
GlobalUnlock(handleDib);
hDib = NULL;
//Since we're about to start scan the hDib, we'll start our timer
QueryPerformanceCounter(&start);
//Scan the hDib
pBarcodeX->AnalyzehDib((long)handleDib);
//End the timer and determine how long it took
QueryPerformanceCounter(&end);
QueryPerformanceFrequency(&freq);
ticks = (end.QuadPart - start.QuadPart);
ms = (double)(1000*ticks) / (double)(freq.QuadPart);
timeStr.AppendFormat(_T("MilliSeconds Elapsed: %g"), ms );
//Clean up after yourself
GlobalFree(handleDib);
//Determine how many barcodes BarcodeXpress found
numBarcodes = pBarcodeX->NumBarcodes;
for( int i = 0; i < numBarcodes; i++)
{
//For each of the barcodes found, we'll extract the information
//and put it in to a string
pBarcodeX->GetBarcode(i);
//To output more information, change the first parameter
//and uncomment the four lines
data.FormatMessage( dataFormatShort /*dataFormat*/,
i,
(LPCTSTR)pBarcodeX->BarcodeCodeName,
(LPCTSTR) pBarcodeX->BarcodeResult,
//pBarcodeX->BarcodeX,
//pBarcodeX->BarcodeY,
//pBarcodeX->BarcodeH,
//pBarcodeX->BarcodeW,
pBarcodeX->Confidence
);
totalData += data;
data = "";
}
//Combine the data string and the time string and present a
//dialog with the information
totalData += timeStr;
MessageBox(totalData, _T("Barcode Information"));
}
}
ImageGear Professional 能够读取 100 多种不同的图像格式,而 Barcode Xpress 支持市场上最多的条形码格式。通过结合这两种工具,您的文档成像解决方案将能够从比以往更多的图像中读取更多的条形码。
在 www.accusoft.com/barcodexpress.htm 或 www.accusoft.com/ig-pro.htm 了解更多关于 Barcode Xpress 或 ImageGear Professional 产品功能的信息,并下载无限制的试用版。在 http://demos.accusoft.com/barcodexpressdemo 上使用您自己的图像进行测试,这是一个最新的条形码在线演示。请联系 info@accusoft.com 获取更多信息。
关于作者
Tyler Lubeck 近十年来一直在 Windows、iOS 和 Android 平台上从事计算机工作。在 2012 年夏天在 Accusoft 实习期间,他为主要的软件开发工具包 ImageGear Professional 进行了编码和质量保证方面的改进。他对 C#、C++、VB6 和 Delphi 代码示例进行了质量保证和纠正,将 C#、C++ 代码示例移植到 Visual Studio 2012,调查并解决了编码缺陷,并改进了产品文档。他目前正在塔夫茨大学攻读计算机科学理学学士学位,预计将于 2015 年毕业。