How to Build a Powerful Document Imaging Workflow
Using ImageGear Professional and Barcode Xpress.
Integrating ImageGear Professional and Barcode Xpress
Barcode indexing is a common step in most electronic document workflows. Document retrieval requires the ability to scan a page for the presence of barcodes and then return the value of each barcode on the page. By combining the power of ImageGear and Barcode Xpress, application developers have the ability to open 100 different document image formats and then recognize and decode any 1D or 2D barcode found in the document. The remainder of this document describes how to pass image data from ImageGear Professional to Barcode Xpress and then return the values of any barcodes found on the page.
Sample Code Introduction
This whitepaper tutorial
uses the sample code in the "Getting Started" section of the ImageGear Professional
help file as a starting point. ImageGear Professional is a very powerful tool that is
capable of working with many types of files and compression techniques. These
capabilities are not always active; rather, ImageGear uses a modular system to
allow developers to only utilize the capabilities needed for their particular
application. The goal of this whitepaper is to provide a basic introduction to
using Barcode Xpress in conjunction with ImageGear Professional. Therefore we
will not add any additional ImageGear modules, so certain image formats may not
open with the sample code. The onOpenDocument()
function will inform the user
when a file was unable to be opened. To provide feedback to the user on this
error, we will make the following change to the function from the Getting
Started guide:
Replace:
//ErrorReport
With:
LPCSTR error = "ImageGear was unable to open the file"; MessageBox(NULL, error, "Error", MB_OK);
It is recommended that you build in your own error checking code to better handle this situation if you are not going to implement all of the file types supported by ImageGear Professional.
Adding Barcode Xpress
Next, we need to add in the Barcode Xpress components to the ImageGear sample project. Right click on the project name and select "Properties." Open Configuration Properties -> C/C++ -> General, and add the location of "BarcodeXpress8_Events.h" (Typically "C:\Users\Public\Documents\Accusoft\BarcodeXpress\V8.0\Samples\ActiveX-COM\VC++\VS2008\Include")
Then add the following lines to stdafx.h:
#import "Accusoft.BarcodeXpress8.ActiveX.dll"
#include "BarcodeXpress8_Events.h"
These lines of code import the ActiveX control and include the header file containing all of the commands available to us.
In IGSampleView.h, add the following code to the class variables to set up the pointers we will use later on:
private:
CBarcodeXpress* m_ppIBarcodeXpress;
IBarcodeXpressPtr pBarcodeX;
Adding the Trigger
Now open up the Resource View by going to View -> Other Windows -> Resource View. Expand the Menu folder and open IDR_MAINFRAME. Add a new item called "Barcode" and a sub item called "Scan".
Assign the new menu item an ID of "ID_SCANBARCODES".
Then open the Class View and right click on CIGSAMPLEView and select properties. Open up Events (the lightning bolt, fourth from the left). Scroll down to ID_SCANBARCODES and expand it. In the COMMAND drop down menu, select "<Add> OnScanbarcodes"
Add the following code:
m_ppIBarcodeXpress = new CBarcodeXpress(this, 1);
pBarcodeX = m_ppIBarcodeXpress->pBarcodeXpress;
findBarcodes();
The first line initializes the pointer to point at the BarcodeXpress COM object.
The second line sets up the pointer that we’ll be using to do our work.
The third line references the function that will do all of the hard work. We’ll set this one up in a minute.
Scanning for Barcodes
In the class view, right click on CIGSampleView and select Add->Add function.
Declare a function with a return type of "void" and a name "findBarcodes".
Finally, we will write the code to pass a DIB to Barcode Xpress to scan for barcodes and save the value of each barcode found in the image. We have added comments to the code to explain what is going on in each step:
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 is capable of reading over 100 different image formats and Barcode Xpress supports the greatest number of barcode formats on the market. By combining these two tools, your document imaging solution could read more barcodes from more images than ever before.
Find out more about Barcode Xpress or ImageGear Professional product features and download an unlimited trial version at www.accusoft.com/barcodexpress.htm or www.accusoft.com/ig-pro.htm. Try your own images on our latest barcode web demo at http://demos.accusoft.com/barcodexpressdemo. Please contact us at info@accusoft.com for more information.
About the Author
Tyler Lubeck has been working with computers on Windows, iOS and Android platforms for almost a decade. While working as an intern at Accusoft during the summer of 2012, he made coding and quality assurance improvements for a major software development toolkit, ImageGear Professional. He quality assured and corrected C#, C++, VB6 and Delphi code samples, ported C#, C++ code samples to Visual Studio 2012, investigated and resolved coding defects, and improved product documentation. He is currently pursuing a Bachelor of Science degree in Computer Science at Tufts University with an expected graduation date of 2015.