Common Vision Blox 14.0
ZXBarcode

Common Vision Blox Foundation Package Tool


 C-Style 

 C++ 

 .Net API (C#, VB, F#) 

 Python 
 ZXBarcode.dll      Stemmer.Cvb.Foundation.ZxBarcode    

Introduction

Common Vision Blox ZXBarcode is a simple and lightweight barcode and matrix code reader based on zxing-cpp (which is a fork of the zxing project).

ZXBarcode invariable requires monochrome input with 8 bits per pixel. Any other image data will need to be converted to match this description prior to passing it to the functions of the ZXBarcode library (for color images a shortcut exists by selecting a suitable image plane for processing). zxing-cpp (and therefore ZXBarcode) is capable of reading a number of different code types - for details refer to the Feature overview.

In case of 1D codes, the codes must be visible more or less upright (give or take about 30°) in the image to be read successfully (rotated by - roughly - 180° is not a problem). DataMatrix and PDF417 codes should not be significantly bent or distorted, otherwise reading is bound to fail.

ZXBarcode is classified as a Common Vision Blox tool because its functions are provided in a DLL, thus providing optimum flexibility when integrating the functions in other applications. Its classification as a tool does not imply any restrictions in terms of quality or functions, but is merely intended as a guide as to the type of programming required.

Feature Overview

Image Processing Tool for reading barcodes and matrix codes

  • Available as DLL
  • Reads the following barcode types (sample images are available in the library documentation):
    • Codabar,
    • Code 39
    • Code 93
    • Code 128
    • EAN 8
    • EAN 13
    • Interleaved 2 of 5 (a.k.a. ITF)
    • RSS 14
    • RSS Expanded
    • UPC-A
    • UPC-E
    • UPC-EAN Extension
  • Reads the following matrix code types (sample images are available in the library documentation):
    • Aztex
    • Datamatrix
    • Maxicode
    • PDF 417
    • QR
  • is available as part of the CVB Foundation Package

ZXBarcode API


ZXBarcode.dll

General information regarding the ZXBarcode functions

VPAT and Datatype

The exported functions can initially be differentiated according to the manner in which they access the image data. Functions without a particular suffix in their names (e.g. AriLog8to8) use linear image access. This makes them suitable for all image sources which allocate a linear memory for a plane of the image (e.g. b/w cameras).

If a function name is given the suffix »VPAT« (e.g. AriLogVPAT), the function can also be used with a non-linear memory (e.g. multi-tap cameras).

Functions can also be differentiated in terms of the type of their input and output images. »8to8« in the name means that both the input images and the output image have an 8-bit data type (e.g. AriLog8to8). The suffix »8to16« means that the input images have a depth of 8 bits, while the output image is 16 bits in depth.

Handling of the Image Object

If the function receives an existing and compatible output image this image will be used. Otherwise a new image will be created internally. Normally the function should create the output image itself, because this is the easiest way and the procedure is not very time critical. But sometimes it might be necessary to use already existing images instead.

When an output image is created within the function, the user must release it with the ReleaseImage function of the Image DLL. If the image is not released, a memory leak will occur.

If you use an existing image as input please internally a ShareImage is done and you have to release twice with ReleaseImage - first for the ShareImage and for your existing image. In any way if you are not sure please check the ReferenceCounter of your image object using the RefCount function of the Image DLL.

Sample program code

A brief example is provided below in form of an excerpt from the Visual C++ tutorial program »VCZXBarcode« under %cvb%Tutorial:

void CVCZXReaderDlg::OnBnClickedRead()
{
ReadOneOrMultiple([](IMG img, cvbdim_t plane, cvbdim_t left, cvbdim_t top, cvbdim_t right, cvbdim_t bottom,
TZXBinarizerMode binarizerMode, TZXReaderMode readerMode, TZXBarcodeFormats formats, cvbres_t& hres)
{
ResultVectorType retval(1);
hres = ZXReadCode(img, plane, left, top, right, bottom,
binarizerMode, readerMode, formats, retval[0]);
if (FAILED(hres))
retval.resize(0);
return retval;
});
}
void CVCZXReaderDlg::OnBnClickedReadall()
{
static const size_t MaxCount =64; //increase as needed
ReadOneOrMultiple([](IMG img, cvbdim_t plane, cvbdim_t left, cvbdim_t top, cvbdim_t right, cvbdim_t bottom,
TZXBinarizerMode binarizerMode, TZXReaderMode readerMode, TZXBarcodeFormats formats, cvbres_t& hres)
{
size_t codeCount = MaxCount;
ResultVectorType retval(codeCount);
hres = ZXReadMultipleCodes(img, plane, left, top, right, bottom,
binarizerMode, readerMode, formats, codeCount, retval.data());
retval.resize(codeCount);
return retval;
});
}
void CVCZXReaderDlg::ReadOneOrMultiple(ReaderFunctionType ReaderFunction)
{
// determine area of interest
double x0, y0, x1, y1, x2, y2;
x0 = y0 = x1 = y1 = x2 = y2 =0.0;
m_cvDisp.GetSelectedArea(&x0,&y0,&x1,&y1,&x2,&y2);
cvbdim_t left = static_cast<cvbdim_t>(std::min(x0, std::min(x1, x2)));
cvbdim_t top = static_cast<cvbdim_t>(std::min(y0, std::min(y1, y2)));
cvbdim_t right = static_cast<cvbdim_t>(std::max(x0, std::max(x1, x2)));
cvbdim_t bottom = static_cast<cvbdim_t>(std::max(y0, std::max(y1, y2)));
// determine call parameters
TZXBinarizerMode binarizer;
if (IsDlgButtonChecked(IDC_RADIOHISTO))
binarizer = ZXB_Histogram;
else if (IsDlgButtonChecked(IDC_RADIOHYBRID))
binarizer = ZXB_Hybrid;
TZXReaderMode reader;
if (IsDlgButtonChecked(IDC_RADIONORMAL))
reader = ZXRM_Default;
else if (IsDlgButtonChecked(IDC_RADIOTRYHARDER))
reader = ZXRM_TryHarder;
if (IsDlgButtonChecked(IDC_CODABAR))
formats = formats | ZXBF_Codabar;
if (IsDlgButtonChecked(IDC_CODE39))
formats = formats | ZXBF_Code39;
if (IsDlgButtonChecked(IDC_CODE93))
formats = formats | ZXBF_Code93;
if (IsDlgButtonChecked(IDC_CODE128))
formats = formats | ZXBF_Code128;
if (IsDlgButtonChecked(IDC_EAN8))
formats = formats | ZXBF_Ean8;
if (IsDlgButtonChecked(IDC_EAN13))
formats = formats | ZXBF_Ean13;
if (IsDlgButtonChecked(IDC_ITF))
formats = formats | ZXBF_Interleaved2of5;
if (IsDlgButtonChecked(IDC_RSS14))
formats = formats | ZXBF_Rss14;
if (IsDlgButtonChecked(IDC_RSSEXPANDED))
formats = formats | ZXBF_RssExpanded;
if (IsDlgButtonChecked(IDC_UPCA))
formats = formats | ZXBF_UpcA;
if (IsDlgButtonChecked(IDC_UPCE))
formats = formats | ZXBF_UpcE;
if (IsDlgButtonChecked(IDC_UPCEAN))
formats = formats | ZXBF_UpcEanExtension;
if (IsDlgButtonChecked(IDC_AZTEC))
formats = formats | ZXBF_Aztec;
if (IsDlgButtonChecked(IDC_DATAMATRIX))
formats = formats | ZXBF_Datamatrix;
if (IsDlgButtonChecked(IDC_MAXICODE))
formats = formats | ZXBF_Maxicode;
if (IsDlgButtonChecked(IDC_PDF417))
formats = formats | ZXBF_Pdf417;
if (IsDlgButtonChecked(IDC_QR))
formats = formats | ZXBF_Qr;
// read
double time =0.0;
cvbres_t hres =0;
TWStartStopWatch(m_timer,0);
auto resultlist = ReaderFunction(reinterpret_cast<IMG>(m_cvDisp.GetImage()),0, left, top, right, bottom,
binarizer, reader, formats, hres);
TWReadStopWatch(m_timer,0,&time);
m_cvDisp.RemoveAllOverlayObjects();
m_cvDisp.RemoveAllLabels();
//display results
CString s;
s.Format(_T("read time:\%.3f ms; read\%d codes; return value:\%d"), time, resultlist.size(), CVC_ERROR_FROM_HRES(hres));
m_cvDisp.SetStatusUserText(s);
int overlayIndex =0;
std::for_each(resultlist.begin(), resultlist.end(),[&](const TZXResult& result)
{
CString s;
s += result.FormatName;
s += _T(":");
s += result.Text;
for (int i =0; i <4;++i)
{
if ((result.PositionX[i]==0.0)&&(result.PositionY[i]==0.0))
continue;
POINT pos[2];
pos[0].x = static_cast<int>(result.PositionX[i]);
pos[0].y = static_cast<int>(result.PositionY[i]);
pos[1].x =5;
pos[1].y =5;
if (i ==0)
m_cvDisp.AddLabel(s, FALSE, 255, overlayIndex++, pos[0].x, pos[0].y);
else
m_cvDisp.AddOverlayObject(_T("Crosshair"), _T(""), FALSE, FALSE, 255, 255, FALSE, i, reinterpret_cast<long*>(pos), nullptr);
}
});
m_cvDisp.Refresh();
}
TZXBinarizerMode
TZXBarcodeFormats
TZXReaderMode
ZXB_Hybrid
ZXB_Histogram
ZXBF_Qr
ZXBF_RssExpanded
ZXBF_Interleaved2of5
ZXBF_Code39
ZXBF_None
ZXBF_Datamatrix
ZXBF_Pdf417
ZXBF_UpcE
ZXBF_Ean13
ZXBF_UpcEanExtension
ZXBF_Code93
ZXBF_Codabar
ZXBF_Maxicode
ZXBF_Rss14
ZXBF_UpcA
ZXBF_Code128
ZXBF_Aztec
ZXBF_Ean8
ZXRM_TryHarder
ZXRM_Default
void * IMG
cvbbool_t TWReadStopWatch(TIMEWATCH hTimeWatch, short Index, double *pElapsedTime)
cvbbool_t TWStartStopWatch(TIMEWATCH hTimeWatch, short Index)
cvbres_t ZXReadCode(IMG imageIn, cvbdim_t plane, cvbdim_t left, cvbdim_t top, cvbdim_t right, cvbdim_t bottom, TZXBinarizerMode binarizerMode, TZXReaderMode readerMode, TZXBarcodeFormats barcodeFormats, TZXResult &result)
cvbres_t ZXReadMultipleCodes(IMG imageIn, cvbdim_t plane, cvbdim_t left, cvbdim_t top, cvbdim_t right, cvbdim_t bottom, TZXBinarizerMode binarizerMode, TZXReaderMode readerMode, TZXBarcodeFormats barcodeFormats, size_t &maxResults, TZXResult *results)