Click here to Skip to main content
16,004,678 members
Articles / All Topics

How to Make Python Barcode Extension on Linux

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
4 Jan 2016CPOL 6.1K  
How to Make Python Barcode Extension on Linux

This article is an entry in our Microsoft Azure IoT Contest. Articles in this section are not required to be full articles so care should be taken when voting.

Probably you have read the article – Wrapping C/C++ Methods of Dynamsoft Barcode SDK for Python, which illustrates how to make Python extension on Windows. In this post, I’ll share how to make Python barcode extension on Ubuntu with Dynamsoft Barcode SDK for Linux.

Getting Started

Three Steps to Build Python Extension

Referring to the tutorial – Python Programming/Extending with C, you just need three steps to build a simple Python extension:

  1. Create a C source file:
    C++
    #include <Python.h>
    
    static PyObject*
    show(PyObject* self, PyObject* args)
    {
        const char* content;
    
        if (!PyArg_ParseTuple(args, "s", &content))
            return NULL;
    
        printf("%s!\n", content);
    
        Py_RETURN_NONE;
    }
    
    static PyMethodDef Methods[] =
    {
         {"show", show, METH_VARARGS, "Print input"},
         {NULL, NULL, 0, NULL}
    };
    
    PyMODINIT_FUNC
    inithelloworld(void)
    {
         (void) Py_InitModule("helloworld", Methods);
    }
  2. Create a Python file:
    Python
    from distutils.core import setup, Extension
    
    module_helloworld = Extension('helloworld', sources = ['helloworld.c'])
    
    setup (name = 'Dynamsoft',
            version = '1.0',
            description = 'First module',
            ext_modules = [module_helloworld])
  3. Make the extension with the following command:
    python setup.py build

The module helloworld.so is generated under build/lib.linux-<version>. Change to the subdirectory and create a Python script:

Python
from helloworld import *
show("My first Python module")

Run the script as follows:

Python
$python test.py
My first Python module!

Wrapping C/C++ SDK for Python

Download Dynamsoft Barcode Reader for Linux.

Extract the package:

tar -xzf dbr-4.0.0-pre-alpha.tar.gz

Create a symbolic link for the shared library:

Python
sudo ln -s $(DynamsoftBarcodeReader)/Redist/libDynamsoftBarcodeReaderx64.so 
		/usr/lib/libDynamsoftBarcodeReaderx64.so

Write C code to invoke Barcode APIs:

C++
#include <Python.h>
#include "If_DBR.h"
#include "BarcodeFormat.h"
#include "BarcodeStructs.h"
#include "ErrorCode.h"

// Barcode format
const char * GetFormatStr(__int64 format)
{
    if (format == CODE_39)
        return "CODE_39";
    if (format == CODE_128)
        return "CODE_128";
    if (format == CODE_93)
        return "CODE_93";
    if (format == CODABAR)
        return "CODABAR";
    if (format == ITF)
        return "ITF";
    if (format == UPC_A)
        return "UPC_A";
    if (format == UPC_E)
        return "UPC_E";
    if (format == EAN_13)
        return "EAN_13";
    if (format == EAN_8)
        return "EAN_8";
    if (format == INDUSTRIAL_25)
        return "INDUSTRIAL_25";
    if (format == QR_CODE)
        return "QR_CODE";
    if (format == PDF417)
        return "PDF417";
    if (format == DATAMATRIX)
        return "DATAMATRIX";

    return "UNKNOWN";
}

static PyObject *
initLicense(PyObject *self, PyObject *args)
{
    char *license;
    if (!PyArg_ParseTuple(args, "s", &license)) {
    return NULL;
    }
    printf("License: %s\n", license);
    int ret = DBR_InitLicense(license);
    return Py_BuildValue("i", ret);
}

static PyObject *
decodeFile(PyObject *self, PyObject *args)
{
    char *pFileName;
    if (!PyArg_ParseTuple(args, "s", &pFileName)) {
        return NULL;
    }

    // Dynamsoft Barcode Reader: init
    __int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX);
    int iMaxCount = 0x7FFFFFFF;
    ReaderOptions ro = {0};
    pBarcodeResultArray pResults = NULL;

    ro.llBarcodeFormat = llFormat;
    ro.iMaxBarcodesNumPerPage = iMaxCount;

    // Decode barcode image
    int ret = DBR_DecodeFile(pFileName, &ro, &pResults);
    printf("DecodeFile ret: %d\n", ret);

    if (ret == DBR_OK) {
        int count = pResults->iBarcodeCount;
        pBarcodeResult* ppBarcodes = pResults->ppBarcodes;
        pBarcodeResult tmp = NULL;

        PyObject* list = PyList_New(count);
        PyObject* result = NULL;
        int i = 0;
        for (; i < count; i++)
        {
            tmp = ppBarcodes[i];
            result = PyString_FromString(tmp->pBarcodeData);
            PyList_SetItem(list, i, Py_BuildValue("iN", (int)tmp->llFormat, result));
        }
        // release memory
        DBR_FreeBarcodeResults(&pResults);
        return list;
    }

    return Py_None;
}

static PyMethodDef Methods[] =
{
     {"initLicense", initLicense, METH_VARARGS, NULL},
     {"decodeFile", decodeFile, METH_VARARGS, NULL},
     {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initdbr(void)
{
     (void) Py_InitModule("dbr", Methods);
}

Create setup.py:

Python
from distutils.core import setup, Extension

module_dbr = Extension('dbr', 
                        sources = ['dbr.c'], 
                        include_dirs=['<Dynamsoft Barcode Reader SDK>/Include'],
                        library_dirs=['<Dynamsoft Barcode Reader SDK>/Redist'],
                        libraries=['DynamsoftBarcodeReaderx64'])

setup (name = 'DynamsoftBarcodeReader',
        version = '1.0',
        description = 'Python barcode extension',
        ext_modules = [module_dbr])

Build the Python barcode extension dbr.so:

Python
python setup.py build

If you want to clean the build files, you can use the following command:

Python
python setup.py clean --all

Install the extension:

Python
sudo python setup.py install

Write a Python script for testing:

Python
import os.path
import sys
from dbr import *

formats = {
	0x3FFL: "OneD",
	0x1L  : "CODE_39",
	0x2L  : "CODE_128",
	0x4L  : "CODE_93",
	0x8L  : "CODABAR",
	0x10L : "ITF",
	0x20L : "EAN_13",
	0x40L : "EAN_8",
	0x80L : "UPC_A",
	0x100L: "UPC_E",
	0x200L: "INDUSTRIAL_25",
	0x2000000L: "PDF417",
	0x8000000L: "DATAMATRIX",
	0x4000000L: "QR_CODE"
}	

if __name__ == "__main__":
	license = open('license.txt', 'r')
	license_content = license.readline().strip()
	ret = initLicense(license_content)
	if (ret != 0):
		print "invalid license"
		sys.exit(0)

	barcode_image = raw_input("Enter the barcode file: ");
	if not os.path.isfile(barcode_image):
		print "It is not a valid file."
	else:

		results = decodeFile(barcode_image);
		print "Total count: " + str(len(results))
		for result in results:
			print "barcode format: " + formats[result[0]]
			print "barcode value: " + result[1] + "\n*************************"

Run the script:

Python
python test.py

python barcode reader

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Writer Dynamsoft
Canada Canada
Xiao Ling is A technical content writer at Dynamsoft, the leading company of document capture and image processing SDKs.
He is in charge of managing Dynamsoft blog site codepool.biz and Dynamsoft GitHub community.

Comments and Discussions

 
-- There are no messages in this forum --