Building Python Barcode Extension with DBR 5.0 on Windows
DBR 5.x is a big leap comparing to version 4.x. A lot of code has been refactored and optimized. This tutorial aims to help developers get familiar with new APIs, and learn how to build a Python barcode application using Dynamsoft Barcode Reader SDK 5.0.
Prerequisites
- Dynamsoft Barcode Reader 5.0 for Windows
- Python 2.7.0
- OpenCV 2.4.10
- Windows 10
- USB webcam
Python Barcode Extension
Create dbr.c and include three header files.
#include <Python.h>
#include "DynamsoftBarcodeReader.h"
#include <ndarraytypes.h>
DBR 5.x defines all data structures with one header file, which is more readable than multiple header files in DBR 4.x.
Define Python methods and initialize Python module:
static PyMethodDef Methods[] =
{
{"create", create, METH_VARARGS, NULL},
{"destroy", destroy, METH_VARARGS, NULL},
{"initLicense", initLicense, METH_VARARGS, NULL},
{"decodeFile", decodeFile, METH_VARARGS, NULL},
{"decodeBuffer", decodeBuffer, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC
initdbr(void)
{
(void) Py_InitModule("dbr", Methods);
}
Set a global DBR handler:
#define DBR_NO_MEMORY 0
#define DBR_SUCCESS 1
void* hBarcode = NULL;
/**
* Create DBR instance
*/
static int createDBR()
{
if (!hBarcode) {
hBarcode = DBR_CreateInstance();
if (!hBarcode)
{
printf("Cannot allocate memory!\n");
return DBR_NO_MEMORY;
}
}
return DBR_SUCCESS;
}
/**
* Destroy DBR instance
*/
static void destroyDBR()
{
if (hBarcode) {
DBR_DestroyInstance(hBarcode);
}
}
Set a valid DBR license:
static PyObject *
initLicense(PyObject *self, PyObject *args)
{
if (!createDBR())
{
return NULL;
}
char *pszLicense;
if (!PyArg_ParseTuple(args, "s", &pszLicense)) {
return NULL;
}
int ret = DBR_InitLicenseEx(hBarcode, pszLicense);
return Py_BuildValue("i", ret);
}
Detect barcodes from an image that captured by OpenCV API:
static PyObject *
decodeBuffer(PyObject *self, PyObject *args)
{
if (!createDBR())
{
return NULL;
}
PyObject *o;
int iFormat;
if (!PyArg_ParseTuple(args, "Oi", &o, &iFormat))
return NULL;
PyObject *ao = PyObject_GetAttrString(o, "__array_struct__");
if ((ao == NULL) || !PyCObject_Check(ao)) {
PyErr_SetString(PyExc_TypeError, "object does not have array interface");
return NULL;
}
PyArrayInterface *pai = (PyArrayInterface*)PyCObject_AsVoidPtr(ao);
if (pai->two != 2) {
PyErr_SetString(PyExc_TypeError, "object does not have array interface");
Py_DECREF(ao);
return NULL;
}
// Get image information
char *buffer = (char*)pai->data; // The address of image data
int width = pai->shape[1]; // image width
int height = pai->shape[0]; // image height
int size = pai->strides[0] * pai->shape[0]; // image size = stride * height
// Initialize Dynamsoft Barcode Reader
int iMaxCount = 0x7FFFFFFF;
SBarcodeResultArray *pResults = NULL;
DBR_SetBarcodeFormats(hBarcode, iFormat);
DBR_SetMaxBarcodesNumPerPage(hBarcode, iMaxCount);
// Detect barcodes
int iRet = DBR_DecodeBufferEx(hBarcode, buffer, width, height, width * 3, IPF_RGB_888, &pResults);
// Wrap results
PyObject *list = createPyResults(pResults);
Py_DECREF(ao);
return list;
}
How to Build the Extension
Set Visual Studio environment:
- Visual Studio 2010 (VS10): SET VS90COMNTOOLS=%VS100COMNTOOLS%
- Visual Studio 2012 (VS11): SET VS90COMNTOOLS=%VS110COMNTOOLS%
- Visual Studio 2013 (VS12): SET VS90COMNTOOLS=%VS120COMNTOOLS%
- Visual Studio 2015 (VS14): SET VS90COMNTOOLS=%VS140COMNTOOLS%
If you are using Visual Studio 2015, use the following command:
SET VS90COMNTOOLS=%VS140COMNTOOLS%
Add the header file directories of DBR 5.0 and NumPy to setup.py:
from distutils.core import setup, Extension
module_dbr = Extension('dbr',
sources = ['dbr.c'],
include_dirs=["F:\\Python27\\Lib\\site-packages\\numpy\\core\\include\\numpy", 'e:\\Program Files (x86)\\Dynamsoft\\Barcode Reader 5.0\\Components\\C_C++\\Include'],
library_dirs=['e:\\Program Files (x86)\\Dynamsoft\Barcode Reader 5.0\\Components\\C_C++\\Lib'],
libraries=['DBRx86'])
setup (name = 'DynamsoftBarcodeReader',
version = '1.0',
description = 'Python barcode extension',
ext_modules = [module_dbr])
Build the Python extension:
python setup.py build install
Copy Dynamsoft\Barcode Reader 5.0\Components\C_C++\Redist\DynamsoftBarcodeReaderx86.dll to Python27\Lib\site-packages
A Simple Python Barcode Reader
Create camera.py.
Import OpenCV and DBR:
import cv2
import dbr
Open the default camera:
vc = cv2.VideoCapture(0)
Set a trial or full SDK license. With an invalid license, the SDK will return an incomplete result:
dbr.initLicense("t0260NQAAALGw+aCAePXdOS3p1xkqT5hesExKVpEe7NiIhkdlUz/Jvx8km3ItI0ykUcmeP67BYVlJ2PDW++bjSYmDLmyMgOmmvc0mdvhlSy500kqnLoBAL+TybcdAP42b5p5WehK9Gsmweqi+ydK6B0KaUNQMDJZ1DrnhDXZ209pfpJoVybPk/CMcDKXaF2oRLKEOYVscXTF6mbiWUnMP5lj4OdTvFa0eVRcE0q9BckiqYgUZLK4L6DVgRXWRL5nRPtvEtd+qZe6psu0JZ7HEPhsbodfAVH2G436z1QahLGJXdQCoQv8UQ/quGQP2wCWemfueeKJ4Y6WsvEvmkUpizbTOE3Njjaw=")
Capture a frame:
rval, frame = vc.read();
Read barcodes:
results = dbr.decodeBuffer(frame, formats)
if (len(results) > 0):
print(get_time())
print("Total count: " + str(len(results)))
for result in results:
print("Type: " + result[0])
print("Value: " + result[1] + "\n")
How to Run the App
- Connect a USB webcam to your PC.
- Run camera.py:
python camera.py