Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to Build a Powerful Document Imaging Workflow

30 Nov 2012 1  
Using ImageGear Professional and Barcode Xpress.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

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")

 

Figure 1: Adding additional components.

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".

 

Figure 2: Add a new menu item

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".

 

Figure 3: Adding a new function

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here