Quantcast
Channel: Barcode – Dynamsoft Developers
Viewing all 145 articles
Browse latest View live

How to Create Java Barcode Reader on Linux with JNI

$
0
0

A few days ago, Dynamsoft Labs released Barcode Reader SDK for Linux. The SDK package provides two shared libraries for C/C++ programming. If you want to write code with high-level programming languages such as Java, you need to create a wrapper. In this post, I will illustrate how to build a simple Java barcode reader on Ubuntu with JNI (Java Native Interface) from scratch.

Installing Dynamsoft Barcode Reader for Linux

To download Dynamsoft Barcode Reader SDK, you can visit the overview page and click v4.0.0-pre-alpha.tar.gz.

Extract the package with the command:

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

Installing Eclipse and CDT for Ubuntu

To conveniently write Java and C/C++ code on Linux, I prefer using Eclipse and CDT. You can navigate Window > Preferences > Install/Update > Available Software Sites to add CDT URL.

eclipse CDT

Navigate Help > Install New Software > Work with to install CDT.

CDT installation

How to Implement Java Barcode Reader on Ubuntu with JNI

Create a Class DBRJNI with some native methods:

public class DBRJNI {

                static {

                                System.loadLibrary("dbr");

                }

                public native int initializeLicense(String license);

                public native ArrayList<BarcodeResult> readBarcode(String fileName);

}

Create a folder jni for writing C/C++ code in your project root directory. Generate a header file corresponding to the Class DBRJNI with the following command:

javah -o DBRJNI.h -classpath ../bin com.dynamsoft.DBRJNI

You will see the following unresolved issues:

jni error

To solve the problem, open project properties and add the Java include path (/usr/lib/jvm/java-7-openjdk-amd64/include) to Preprocessor Include Paths.

jni include path

Create DBRJNI.cpp to add function implementations:

JNIEXPORT jint JNICALL Java_com_dynamsoft_DBRJNI_initializeLicense(JNIEnv *env,

                                jobject obj, jstring license)

{

                const char *pszLicense = env->GetStringUTFChars(license, 0);

                int ret = DBR_InitLicense(pszLicense);

                // release license native string

                env->ReleaseStringUTFChars(license, pszLicense);

                return ret;

}

JNIEXPORT jobject JNICALL Java_com_dynamsoft_DBRJNI_readBarcode(JNIEnv *env,

                                jobject obj, jstring fileName)

{

                const char *pszFileName = env->GetStringUTFChars(fileName, 0);

                __int64 llFormat = OneD | QR_CODE | PDF417 | DATAMATRIX;

                int iMaxCount = 0x7FFFFFFF;

                ReaderOptions ro = { 0 };

                ro.llBarcodeFormat = llFormat;

                ro.iMaxBarcodesNumPerPage = iMaxCount;

                pBarcodeResultArray paryResult = NULL;

                int iRet = DBR_DecodeFile(pszFileName, &ro, &paryResult);

                if (iRet != DBR_OK) {

                                printf("Failed to read barcode: %s\n", DBR_GetErrorString(iRet));

                                return NULL;

                }

                if (paryResult->iBarcodeCount == 0)

                                {

                                                printf("No barcode found");

                                                DBR_FreeBarcodeResults(&paryResult);

                                                return 0;

                                }

                for (int iIndex = 0; iIndex < paryResult->iBarcodeCount; iIndex++)

                                {

                                                printf("Barcode %d:\n", iIndex + 1);

                                                printf("    Page: %d\n", paryResult->ppBarcodes[iIndex]->iPageNum);

                                                printf("    Type: %s\n", GetFormatStr(paryResult->ppBarcodes[iIndex]->llFormat));

                                                printf("    Value: %s\n", paryResult->ppBarcodes[iIndex]->pBarcodeData);

                                                printf("    Region: {Left: %d, Top: %d, Width: %d, Height: %d}\n\n",

                                                                paryResult->ppBarcodes[iIndex]->iLeft, paryResult->ppBarcodes[iIndex]->iTop,

                                                                paryResult->ppBarcodes[iIndex]->iWidth, paryResult->ppBarcodes[iIndex]->iHeight);

                                }

                                DBR_FreeBarcodeResults(&paryResult);

// release filename native string

                env->ReleaseStringUTFChars(fileName, pszFileName);

                return NULL;

}

Create a makefile:

CC=gcc 
CCFLAGS=-c -Wall -Werror -fpic -lstdc++
JNI_INCLUDE=/usr/lib/jvm/java-7-openjdk-amd64/include
CLASS_PATH=../bin
#DBRLIB_PATH=~/Dynamsoft/BarcodeReader4.0/Redist
#LDFLAGS=-L$(DBRLIB_PATH) -Wl,-rpath=$(DBRLIB_PATH)

ifeq ($(shell getconf LONG_BIT), 32)
	DBRLIB=-lDynamsoftBarcodeReaderx86
	LIBNAME=libDynamsoftBarcodeReaderx86.so
else
	DBRLIB=-lDynamsoftBarcodeReaderx64
	LIBNAME=libDynamsoftBarcodeReaderx64.so
endif

TARGET=libdbr.so
OBJECT=DBRJNI.o
SOURCE=DBRJNI.cpp

$(TARGET): $(OBJECT)
	$(CC) -shared -o $(TARGET) $(OBJECT) $(LDFLAGS) $(DBRLIB)
	$(shell sudo ln -s ~/Dynamsoft/BarcodeReader4.0/Redist/$(LIBNAME) /usr/lib/$(LIBNAME))

$(OBJECT): $(SOURCE)
	$(CC) $(CCFLAGS) -I$(JNI_INCLUDE) $(SOURCE) 
#DBRJNI.h : 
#	javah -o DBRJNI.h -classpath $(CLASS_PATH) com.dynamsoft.DBRJNI

# the clean target
.PHONY : clean
clean: 
	sudo rm -f $(OBJECT) $(TARGET) /usr/lib/$(LIBNAME)

If you don’t use the command $(shell sudo ln -s) to creates a symbolic link, you will see the following error:

/usr/bin/ld: cannot find -lDynamsoftBarcodeReaderx64

Build libdbr.so with make:

makefile

In order to correctly load the shared library that generated under the jni folder, specify the VM arguments in Run Configurations:

-Djava.library.path=jni

java lib path for eclipse

Test the Java barcode program with a few lines of code:

                static {

                                System.loadLibrary("dbr");

                }

                public native int initializeLicense(String license);

                public native ArrayList<BarcodeResult> readBarcode(String fileName);

                public static void main(String[] args) {

                                // invoke the native method

                                DBRJNI barcodeReader = new DBRJNI();

                                int ret = barcodeReader.initializeLicense("<DBR License>");

                                System.out.println("Initialize license: " + ret);

                                barcodeReader.readBarcode("<Image File>");

                }

jni barcode result

Source Code

https://github.com/dynamsoftsamples/java-barcode-reader-for-linux


How to Make Node Barcode Reader Addon on Linux

$
0
0

If you want to make a Web barcode reader app using node.js, you may find a node barcode module with npm or build it yourself. Node addons are the bridge between C/C++ libraries and JavaScript. In this tutorial, I will illustrate how to create node barcode addon on Ubuntu with DBR (Dynamsoft Barcode Reader for Linux).

Download & Installation

If you want to use the latest node version, do not install node and npm with the apt-get utility, which only fetches the old version and will cause the error – ‘FunctionCallbackInfo’ does not name a type:

node-gyp build error

Install Node

Download the latest node package: node-v5.3.0-linux-x64.tar.gz.

Extract the node package as follows:

tar -xzf node-v5.3.0-linux-x64.tar.gz

Open .bashrc:

nano ~/.bashrc

Export node path and save .bashrc:

export PATH=$(YOUR_HOME)/Downloads/node-v5.3.0-linux-x64/bin:$PATH

Install node-gyp:

npm install -g node-gyp

Install DBR

Download v4.0.0-pre-alpha.tar.gz.

Extract the dbr package:

tar -xzf v4.0.0-pre-alpha.tar.gz

To find the shared library when building the project with make, create a symbolic link of barcode shared library:

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

How to Make Node Barcode Addon

Create binding.gyp and specify the paths of DBR header files and shared libraries:

{
  "targets": [
    {
      "target_name": "dbr",
      "sources": [ "dbr.cc" ],
      "include_dirs" : [
        "$(DynamsoftBarcodeReader)/Include"
      ],
      "libraries": [
        "-lDynamsoftBarcodeReaderx64", "-L$(DynamsoftBarcodeReader)/Redist"
      ]
    }
  ]
}

Create dbr.cc using the sample code provided by Dynamsoft Barcode Reader SDK:

#include <node.h>
#include "If_DBR.h"
#include "BarcodeFormat.h"
#include "BarcodeStructs.h"
#include "ErrorCode.h"

using namespace v8;

// 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";
}

void DecodeFile(const FunctionCallbackInfo<Value>& args) {

	Isolate* isolate = Isolate::GetCurrent();
	HandleScope scope(isolate);

	// convert v8 string to char *
	String::Utf8Value fileName(args[0]->ToString());
	String::Utf8Value license(args[1]->ToString());
	char *pFileName = *fileName;
	char *pszLicense = *license;
	// Dynamsoft Barcode Reader: init
	__int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX);
	int iMaxCount = 0x7FFFFFFF;
	ReaderOptions ro = {0};
	pBarcodeResultArray pResults = NULL;

	// Initialize license
	if (pszLicense)
	{
		printf("license: %s\n", pszLicense);
		DBR_InitLicense(pszLicense);
	}
	else
		DBR_InitLicense("AC4561856D63EF392F46D7454052372D");

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

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

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

		// javascript callback function
		Local<Function> cb = Local<Function>::Cast(args[2]);
		const unsigned argc = 1;

		// array for storing barcode results
		Local<Array> barcodeResults = Array::New(isolate);

		for (int i = 0; i < count; i++)
		{
			tmp = ppBarcodes[i];

			Local<Object> result = Object::New(isolate);
			result->Set(String::NewFromUtf8(isolate, "format"), Number::New(isolate, tmp->llFormat));
			result->Set(String::NewFromUtf8(isolate, "value"), String::NewFromUtf8(isolate, tmp->pBarcodeData));

			barcodeResults->Set(Number::New(isolate, i), result);
		}

		// release memory
		DBR_FreeBarcodeResults(&pResults);

		Local<Value> argv[argc] = { barcodeResults };
		cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);
	}
}

void Init(Handle<Object> exports) {
	NODE_SET_METHOD(exports, "decodeFile", DecodeFile);
}

NODE_MODULE(dbr, Init)

Automatically generate the project build files:

node-gyp configure

Build the project to produce dbr.node:

node-gyp build

Write a test dbr.js which loads SDK license and invokes native reader methods:

var dbr = require('./build/Release/dbr');
var readline = require('readline');
var fs = require('fs');

fs.readFile('./license.txt', 'utf8', function (err, data) {
  if (err) throw err;
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  var license = data.trim();
  rl.question("Please input a barcode image path: ", function(answer) {

    dbr.decodeFile(
      answer, license,
      function(msg){
        var result = null;
        for (index in msg) {
          result = msg[index]
          console.log(result['format']);
          console.log(result['value']);
          console.log("##################");
        }
      }
    );

    rl.close();
  });
});

Run the script:

node dbr.js

linux node barcode reader

Source Code

https://github.com/dynamsoftsamples/node-barcode-addon-for-linux

How to Make Python Barcode Extension on Linux

$
0
0

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:
    #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:
    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:

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

Run the script as follows:

$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:

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

Write C code to invoke Barcode APIs:

#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:

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 setup.py build

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

python setup.py clean --all

Install the extension:

sudo python setup.py install

Write a Python script for testing:

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 test.py

python barcode reader

Source Code

https://github.com/dynamsoftsamples/python-barcode-extension-for-linux

 

Making Online Barcode Reader on Linux with Node.js

$
0
0

Previously, I shared an article How to Make Node Barcode Reader Addon on Linux, which illustrates how to create a node barcode addon by wrapping Dynamsoft Barcode Reader SDK on Linux. Since Node.js was born for developing network programs, let’s take a glimpse of how to create a Web barcode reader using the node barcode addon.

Getting Started

I assume you have successfully built the dbr.so using node-gyp. If not, please read the relevant post before taking the following steps.

Basic Steps of Reading Barcode Online

  1. Upload barcode images or transfer image URLs to a Web server.
  2. Save barcode images to designated folder on the Web server.
  3. Decode barcode images and send results back to Web clients.

Install Express and Formidable

Express is a Web framework for Node.js. To install Express:

npm install express --save

Formidable is a node.js module for parsing form data. To install Formidable:

npm install formidable --save

Initialization

var formidable = require('formidable');
var util = require('util');
var express = require('express');
var fs = require('fs');
var app = express();
var path = require('path');
var dbr = require('./build/Release/dbr');
var http = require('http');

Load Static Resources in Express

Create a static HTML page index.htm with CSS files and JavaScript files:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Dynamsoft Barcode Reader Nodejs Demo</title>
    <link type="text/css" rel="stylesheet" href="assets/css/style.css" />

    <script type="text/javascript" src="assets/js/jquery-1.11.2.js"></script>
</head>

<body>
    <div id="wrapper">
        <div id="dbr-nodejs">
            <h1>
                Dynamsoft Barcode Reader Nodejs Demo</h1>
            <!--<form action="">-->
            <div class="step step1">
                <div id="fileUpload" class="getFile">
                    <span class="num">1</span>
                    <h4>
                        Upload from local:</h4>
                    <input type="file" id="fileToUpload" onchange="fileSelected();" />
                    <input type="text" readonly="readonly" id="filename" />
                    <input type="button" />
                    <a class="clickSwitch" href="javascript:void(0);">or, Specify an URL</a>
                </div>
                <div id="fileDownload" class="hidden getFile">
                    <span class="num">1</span>
                    <h4>
                        Specify an URL:</h4>
                    <input type="text" id="imageURL"/>
                    <!--<input type="button"/>-->
                    <a class="clickSwitch" href="javascript:void(0);">or, Upload from local</a>
                </div>
            </div>
            <div class="step step2">
                <span class="num">2</span>
                <h4>
                    Barcode Types:</h4>
                <ul class="barcodeType">
                    <li class="on">
                        <label for="chkLinear">
                            <input id="chkLinear" name="BarcodeType" type="checkbox" checked="true" value="0x3FF">
                            <span>Linear</span><br />
                            <div class="imgWrapper">
                                <img src="assets/images/oned.gif" width="90" alt="Barcode Type Linear" /></div>
                        </label>
                    </li>
                    <li>
                        <label for="chkQRCode">
                            <input id="chkQRCode" name="BarcodeType" type="checkbox" value="0x4000000">
                            <span>QRCode</span><br />
                            <div class="imgWrapper">
                                <img src="assets/images/qr.gif" width="60" alt="Barcode Type QRCode" /></div>
                        </label>
                    </li>
                    <li>
                        <label for="chkPDF417">
                            <input id="chkPDF417" name="BarcodeType" type="checkbox" value="0x2000000">
                            <span>PDF417</span><br />
                            <div class="imgWrapper">
                                <img src="assets/images/pdf417.gif" width="100" height="38" alt="Barcode Type PDF417" /></div>
                        </label>
                    </li>
                    <li>
                        <label for="chkDataMatrix">
                            <input id="chkDataMatrix" name="BarcodeType" type="checkbox" value="0x8000000">
                            <span>DataMatrix</span><br />
                            <div class="imgWrapper">
                                <img src="assets/images/dm.gif" width="60" alt="Barcode Type DataMatrix" /></div>
                        </label>
                    </li>
                </ul>
            </div>
            <div class="step step3">
                <span class="num">3</span> <a id="readBarcode" name="RecgabtnCssBarcode" onclick="doReadBarcode();">
                </a>
                <div id="resultBox">
                </div>
            </div>
            <!--</form>-->
        </div>
    </div>

</body>
</html>

Create server.js and specify the resource directory in express.static:

app.use(express.static(__dirname));

Parse Form and Save Uploaded Files with Formidable

var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
            var dir = 'uploads';
            var flag = fields.uploadFlag;
            var barcodeType = parseInt(fields.barcodetype);

            fs.readFile(files.fileToUpload.path, function(err, data) {
                        // save file from temp dir to new dir
                        var fileName = path.join(__dirname, dir, files.fileToUpload.name);
                        fs.writeFile(fileName, data, function(err) {
                            if (err) throw err;

                            decodeBarcode(res, license, fileName, barcodeType);
                        });
             });

});

Download Files with Node.js

                    var tmpFileName = path.join(__dirname, dir, 'tmp.jpg');
                    var tmp = fs.createWriteStream(tmpFileName);
                    var url = fields.fileToDownload;
                    console.log('url: ' + url);
                    http.get(url, function(response) {
                        response.pipe(tmp);
                        tmp.on('finish', function() {
                            tmp.close(function() {
                                decodeBarcode(res, license, tmpFileName, barcodeType);
                            });
                        });
                    });

Read Barcode Images in Node.js

function decodeBarcode(res, license, fileName, barcodeType) {
    // read barcode using dbr
    dbr.decodeFile(
        license, fileName, barcodeType,
        function(msg) {
            var response = 'Totol count: ' + msg.length;
            var result = null;
            for (index in msg) {
                result = msg[index]
                response += '<p>' + result['format'] + ': ';
                response += result['value'] + '<p>';
            }
            res.send(response);
        }
    );
}

Test Online Barcode Reader

Run server.js:

node server.js

Visit http://localhost:2016/index.htm:

node barcode reader

Source Code

https://github.com/dynamsoftsamples/node-barcode-addon-for-linux

How to Dockerize Nodejs Barcode Reader on Linux

$
0
0

If you want to get a Node.js application into a Docker container from scratch, it’s recommended to read the official guide – Dockerizing a Node.js web app.  It is useful, but not enough for a complicated case. In this post, I’m going to share what problems I have encountered while Dockerizing the Node.js barcode reader app using Dynamsoft Barcode Reader for Linux.

Nodejs Barcode Addon and App

If you have no idea how to use the Dynamsoft Barcode Reader SDK to create a Node.js barcode addon, please fork the repository on GitHub.

Dockerize the Node.js App

According to the official tutorial, I created the Dockerfile like this:

FROM node:latest

RUN mkdir -p /usr/src/dbr
WORKDIR /usr/src/dbr 

# Install app dependencies
# If you want to download relevant Node.js modules when building the Docker image, uncomment following lines.
#COPY package.json /usr/src/dbr 
#RUN npm install 

COPY libDynamsoftBarcodeReaderx64.so ./
RUN ln -s /usr/src/dbr/libDynamsoftBarcodeReaderx64.so /usr/lib/libDynamsoftBarcodeReaderx64.so

COPY . ./

EXPOSE 2016

CMD [ "npm", "start" ]

Select the matched Node.js version

In the official tutorial, the image used in Dockerfile is argon:

FROM node:argon

Here is mine:

FROM node:latest

What is the difference? Visit the docker-library on GitHub, you will see the detailed descriptions about the Dockerfiles. The argon version is based on v4.2, whereas the latest version is based on v5.5.

nodejs dockerfile

I created the addon using v5.x. When I tried to load the addon using the argon image, I got the following exceptions:

return process.dlopen(module, path._makeLong(filename));

                 ^

Error: Module version mismatch. Expected 46, got 47.

    at Error (native)

    at Object.Module._extensions..node (module.js:460:18)

    at Module.load (module.js:356:32)

    at Function.Module._load (module.js:311:12)

    at Module.require (module.js:366:17)

at require (module.js:385:17)

Remember to check whether the Node.js version of building your addon and app matches the version installed in Docker image when you get the similar error.

Copy shared libraries to Docker image

Firstly, you have to copy libDynamsoftBarcodeReaderx64.so from <Dynamsoft> /BarcodeReader4.0/Redist/ to your project which contains the Dockerfile:

cp <Dynamsoft>/BarcodeReader4.0/Redist/ libDynamsoftBarcodeReaderx64.so <project>/libDynamsoftBarcodeReaderx64.so

copy so to project folder

Because the Node.js barcode reader app relies on libDynamsoftBarcodeReaderx64.so, you need to use the Docker instruction “COPY <src> <dest>“ to add the shared library to the filesystem of the container:

COPY libDynamsoftBarcodeReaderx64.so /usr/lib/libDynamsoftBarcodeReaderx64.so

Note: the <src> must be inside the context of the build. If you change the instruction like “COPY <Dynamsoft> /BarcodeReader4.0/Redist/libDynamsoftBarcodeReaderx64.so /usr/lib/libDynamsoftBarcodeReaderx64.so”, you will see the error message “no such file or directory”.

Alternatively, you can copy the so file to the project folder and generate a symlink:

COPY libDynamsoftBarcodeReaderx64.so ./
RUN ln -s /usr/src/dbr/libDynamsoftBarcodeReaderx64.so

Bundle your project

Add all files of your project to the Docker image:

RUN mkdir -p /usr/src/dbr
WORKDIR /usr/src/dbr

COPY . ./

Expose the port

We need to map the port in order to access the Web app.

EXPOSE 2016

Define the command to run the barcode reader

CMD [ "npm", "start" ]

Build Docker Image

sudo docker build -t dynamsoft/dbr .

Run the Image

sudo docker run -p 2016:2016 dynamsoft/dbr
# Or run in background
sudo docker run -p 2016:2016 -d dynamsoft/dbr

node barcode reader

Docker Repository of Nodejs Barcode Reader

https://hub.docker.com/r/dynamsoft/dbr/

How to Make PHP Barcode Reader with Windows COM Object

$
0
0

Dynamsoft Barcode Reader for Windows includes dynamic-link libraries for C/C++, DotNET and COM. If you want to use high-level programming languages such as Python, PHP, Java, Ruby and so on to create barcode reader apps with Dynamsoft Barcode Reader, you could either make a C/C++ wrapper as an extension or use COM objects. To create a PHP extension on Windows, you can refer to the sample code on Dynamsoft GitHub repository. Nevertheless, when making PHP extension, many developers suffered from the issue of PHP version number mismatch. Therefore, using COM in PHP seems to be more convenient.

This article has been posted on CodeProject.

COM Registration

The installer of Dynamsoft Barcode Reader will automatically register COM DLLs. If you want to distribute the DLLs to other Windows PCs directly, do not forget to manually register them:

regsvr32 DynamsoftBarcodeReaderCtrlx86.dll
regsvr32 DynamsoftBarcodeReaderCtrlx64.dll

  To unregister COMs:

regsvr32 /u DynamsoftBarcodeReaderCtrlx86.dll
regsvr32 /u DynamsoftBarcodeReaderCtrlx64.dll

File Uploading with JavaScript & PHP

Use the FormData interface to wrap selected file and send it using XMLHttpRequest.

var fd = new FormData();

var file = document.getElementById('fileToUpload').files[0];

fd.append('fileToUpload', file);    

fd.append('uploadFlag', uploadFlag);

fd.append('barcodetype', getSelectedBarcodeTypes());

var xhr = new XMLHttpRequest();

xhr.addEventListener("load", uploadComplete, false);

xhr.upload.addEventListener("progress", uploadProgress, false);

xhr.addEventListener("error", uploadFailed, false);

xhr.addEventListener("abort", uploadCanceled, false);

xhr.open("POST", "readbarcode.php");

xhr.send(fd);

Save the temporary uploaded file to a folder:

// get current working directory

$root = getcwd();

// tmp dir for receiving uploaded barcode images

$tmpDir = $root . "/uploads/";

if (!file_exists($tmpDir)) {

                    mkdir($tmpDir);

}

$target_file = $tmpDir . $tmpname;

if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file))

{    

                    readBarcode($target_file, $btype);                                                                                                 

                    unlink($target_file);

}

else {

                    echo "Fail to upload file.";            

}

PHP Barcode Reader with COM Objects

Create COM objects in PHP:

$this->m_reader = new COM("DBRCtrl.BarcodeReader");
$this->m_option = new COM("DBRCtrl.ReaderOptions");

Initialize license:

$this->m_reader->InitLicense($key);

Set barcode formats and reader options:

$this->m_option->BarcodeFormats = $format;              
$this->m_reader->ReaderOptions =$this->m_option;

Decode barcode image:

$this->m_reader->DecodeFile($filename);

Get results:

$this->m_resultArray = $this->m_reader->Barcodes;

Running PHP Barcode Reader on Nginx

First, you have to open php.ini to confirm whether the PHP extension %php%\ext\php_com_dotnet.dll is enabled:

extension=php_com_dotnet.dll

Open %nginx%\confg\ nginx.conf and uncomment the PHP configurations:

location ~ \.php$ {

            root           html;

            fastcgi_pass   127.0.0.1:9000;

            fastcgi_index  index.php;

            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;

            include        fastcgi_params;

        }

Specify the SCRIPT_FILENAME. For example:

fastcgi_param  SCRIPT_FILENAME %nginx%/html/$fastcgi_script_name;

Copy all PHP scripts to %nginx%/html/.

Run Nginx and PHP CGI:

%nginx%\nginx
%php%\php-cgi.exe -b 127.0.0.1:9000 -c %php%\php.ini

Visit localhost:8080/index.php and try to read a barcode image:

 nginx 413 error

There is an error: 413 Request Entity Too Large! The size of the uploaded image is about 20M. You may also encounter the issue if uploading big files. To avoid the problem, you can change the default entity size in nginx.conf:

client_max_body_size 30M;

Try to read the barcode image again:

 php size error

Still failed! According to the warning, you should also change the PHP limitation. Open php.ini and edit the following line:

post_max_size 30M;

Try one more time:

 php barcode result

How to Build Node.js Barcode Reader on Windows, Linux and Mac

$
0
0

Dynamsoft Barcode Reader provides C/C++ shared libraries for Windows, Linux, and Mac. The ultimate benefit is that any high-level programming languages, such as JavaScript, Python, Java, Ruby, PHP and so on, are capable of wrapping C/C++ APIs using an extension or an addon. No matter which programming language you are familiar with, the SDK will expedite the coding work of barcode reader app with a few lines of code.

This article has been posted on CodeProject.

Node.js Barcode Addon

Node.js Addons are dynamically-linked shared objects written in C/C++. If you have never touched this part before, you’d better follow the official tutorial to get started.

Create Addon

Create dbr.cc and add a method DecodeFile:

#include <node.h>
#include <string.h>
#include "If_DBR.h"
#include "BarcodeFormat.h"
#include "BarcodeStructs.h"
#include "ErrorCode.h"

using namespace v8;

void DecodeFile(const FunctionCallbackInfo<Value>& args) {

}

void Init(Handle<Object> exports) {
	NODE_SET_METHOD(exports, "decodeFile", DecodeFile);
}

NODE_MODULE(dbr, Init)

Parse parameters that passed from JavaScript:

Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
String::Utf8Value license(args[0]->ToString());
String::Utf8Value fileName(args[1]->ToString());
char *pFileName = *fileName;
char *pszLicense = *license;
__int64 llFormat = args[2]->IntegerValue();
Local<Function> cb = Local<Function>::Cast(args[3]);

Decode barcode image:

int iMaxCount = 0x7FFFFFFF;
ReaderOptions ro = {0};
pBarcodeResultArray pResults = NULL;
ro.llBarcodeFormat = llFormat;
ro.iMaxBarcodesNumPerPage = iMaxCount;

DBR_InitLicense(pszLicense);
// Decode barcode image
int ret = DBR_DecodeFile(pFileName, &ro, &pResults);

Convert barcode formats to String:

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";
}

Convert results to v8 object:

	    Local<Array> barcodeResults = Array::New(isolate);

		for (int i = 0; i < count; i++)
		{
			tmp = ppBarcodes[i];

			Local<Object> result = Object::New(isolate);
			result->Set(String::NewFromUtf8(isolate, "format"), String::NewFromUtf8(isolate, GetFormatStr(tmp->llFormat)));
			result->Set(String::NewFromUtf8(isolate, "value"), String::NewFromUtf8(isolate, tmp->pBarcodeData));

			barcodeResults->Set(Number::New(isolate, i), result);
		}

Build Addon

Prerequisites:

Install node-gyp:

npm install -g node-gyp

Create binding.gyp for multiplatform compilation:

{
  "targets": [
    {
      'target_name': "dbr",
      'sources': [ "dbr.cc" ],
      'conditions': [
          ['OS=="linux"', {
            'defines': [
              'LINUX_DBR',
            ],
            'include_dirs': [
                "/home/xiao/Dynamsoft/BarcodeReader4.0/Include"
            ],
            'libraries': [
                "-lDynamsoftBarcodeReaderx64", "-L/home/xiao/Dynamsoft/BarcodeReader4.0/Redist"
            ],
            'copies': [
            {
              'destination': 'build/Release/',
              'files': [
                '/home/xiao/Dynamsoft/BarcodeReader4.0/Redist/libDynamsoftBarcodeReaderx64.so'
              ]
            }]
          }],
          ['OS=="win"', {
            'defines': [
              'WINDOWS_DBR',
            ],
            'include_dirs': [
                "F:\Program Files (x86)\Dynamsoft\Barcode Reader 4.1\Components\C_C++\Include"
            ],
            'libraries': [
                "-lF:\Program Files (x86)\Dynamsoft\Barcode Reader 4.1\Components\C_C++\Lib\DBRx64.lib"
            ],
            'copies': [
            {
              'destination': 'build/Release/',
              'files': [
                'F:\Program Files (x86)\Dynamsoft\Barcode Reader 4.1\Components\C_C++\Redist\DynamsoftBarcodeReaderx64.dll'
              ]
            }]
          }],
          ['OS=="mac"', {
            'defines': [
              'MAC_DBR',
            ],
            'include_dirs' : [
                "/Applications/Dynamsoft/Barcode\ Reader\ 4.1/Include"
            ],
            'libraries': [
                "-lDynamsoftBarcodeReader"
            ]
          }]
      ]
    }
  ]
}

Replace the DBR Installation Directory with yours.

Configure the building environment:

node-gyp configure

Probably you will see the following error when configuring the environment on Mac:

error: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

Here is the solution:

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

Build the project:

node-gyp build

Online Barcode Reader

You have successfully built the Node barcode reader module. Now it is time to create a simple barcode reader app.

Install Express and Formidable:

npm install express
npm install formidable

Create a simple Website using Express:

var formidable = require('formidable');
var util = require('util');
var express = require('express');
var fs = require('fs');
var app = express();
var path = require('path');
var dbr = require('./build/Release/dbr');
var http = require('http');

fs.readFile('./license.txt', 'utf8', function(err, data) {

  app.use(express.static(__dirname));
  app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
    res.header("Access-Control-Allow-Headers", "X-Requested-With, content-type");
    res.header("Access-Control-Allow-Credentials", true);
    next();
  });

  var server = app.listen(2016, function() {
    var host = server.address().address;
    var port = server.address().port;
    console.log('listening at http://%s:%s', host, port);
  });
});

Use Formidable to extract the image data from Form.

app.post('/upload', function(req, res) {
    var form = new formidable.IncomingForm();
    form.parse(req, function(err, fields, files) {
      var dir = 'uploads';

      fs.mkdir(dir, function(err) {
        var flag = fields.uploadFlag;
        var barcodeType = parseInt(fields.barcodetype);

        console.log('flag: ' + flag);

        if (flag === '1') { // read barcode image file
          fs.readFile(files.fileToUpload.path, function(err, data) {
            // save file from temp dir to new dir
            var fileName = path.join(__dirname, dir, files.fileToUpload.name);
            console.log(fileName);
            fs.writeFile(fileName, data, function(err) {
              if (err) throw err;

            });
          });

        } else { // read barcode image url
          var tmpFileName = path.join(__dirname, dir, 'tmp.jpg');
          var tmp = fs.createWriteStream(tmpFileName);
          var url = fields.fileToDownload;
          console.log('url: ' + url);
          http.get(url, function(response) {
            response.pipe(tmp);
            tmp.on('finish', function() {
              tmp.close(function() {

              });
            });
          });
        }
      });

    });
  });

Import the barcode module to decode the image file.

decodeBarcode(res, license, tmpFileName, barcodeType);

Run the app:

node server.js

Visit http://localhost:2016/index.htm:

node barcode reader

Source Code

https://github.com/yushulx/nodejs-barcode-for-win-linux-mac

How to Make PHP Barcode Reader on Linux

$
0
0

When developing a web barcode reader app in PHP, you can either use some JavaScript barcode libraries to recognize barcode images on client-side or read the barcode images on server-side with some PHP extensions that capable of reading 1D and 2D barcode. In this post, I will demonstrate how to create a PHP barcode reader with DBR (Dynamsoft Barcode Reader for Linux) on Ubuntu 14.04.

How to Make PHP Extension with C Source Code and Shared Library

Install DBR.

To build PHP extension, you need to use the source code. Before download, you have to check which PHP version used:

php –v

Download the corresponding source code of PHP.

Extract the package and change to the ext folder. Here is mine:

cd ~/Downloads/php-5.5.9/ext

Create an extension dbr:

./ext_skel --extname=dbr

Change directory to dbr:

cd dbr

Edit config.m4 to configure the paths of include and library:

PHP_ARG_ENABLE(dbr, whether to enable dbr support,

dnl Make sure that the comment is aligned:

[  --enable-dbr           Enable dbr support])

if test "$PHP_DBR" != "no"; then

  PHP_ADD_LIBRARY_WITH_PATH(DynamsoftBarcodeReaderx64, /home/xiao/Dynamsoft/BarcodeReader4.0/Redist, DBR_SHARED_LIBADD) 

  PHP_ADD_INCLUDE(/home/xiao/Dynamsoft/BarcodeReader4.0/Include)

  PHP_SUBST(DBR_SHARED_LIBADD)

  PHP_NEW_EXTENSION(dbr, dbr.c, $ext_shared)

fi

Edit dbr.c:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_dbr.h"

#include "If_DBR.h"
#include "BarcodeFormat.h"
#include "BarcodeStructs.h"
#include "ErrorCode.h"
#include <stdbool.h>

/* If you declare any globals in php_dbr.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(dbr)
*/

/* True global resources - no need for thread safety here */
static int le_dbr;

/* {{{ dbr_functions[]
 *
 * Every user visible function must have an entry in dbr_functions[].
 */
const zend_function_entry dbr_functions[] = {
	PHP_FE(DecodeBarcodeFile,	NULL)		/* For testing, remove later. */
	PHP_FE_END	/* Must be the last line in dbr_functions[] */
};
/* }}} */

/* {{{ dbr_module_entry
 */
zend_module_entry dbr_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
	STANDARD_MODULE_HEADER,
#endif
	"dbr",
	dbr_functions,
	PHP_MINIT(dbr),
	PHP_MSHUTDOWN(dbr),
	PHP_RINIT(dbr),		/* Replace with NULL if there's nothing to do at request start */
	PHP_RSHUTDOWN(dbr),	/* Replace with NULL if there's nothing to do at request end */
	PHP_MINFO(dbr),
#if ZEND_MODULE_API_NO >= 20010901
	PHP_DBR_VERSION,
#endif
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_DBR
ZEND_GET_MODULE(dbr)
#endif

/* {{{ PHP_INI
 */
/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
    STD_PHP_INI_ENTRY("dbr.global_value",      "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_dbr_globals, dbr_globals)
    STD_PHP_INI_ENTRY("dbr.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_dbr_globals, dbr_globals)
PHP_INI_END()
*/
/* }}} */

/* {{{ php_dbr_init_globals
 */
/* Uncomment this function if you have INI entries
static void php_dbr_init_globals(zend_dbr_globals *dbr_globals)
{
	dbr_globals->global_value = 0;
	dbr_globals->global_string = NULL;
}
*/
/* }}} */

/* {{{ PHP_MINIT_FUNCTION
 */
PHP_MINIT_FUNCTION(dbr)
{
	/* If you have INI entries, uncomment these lines 
	REGISTER_INI_ENTRIES();
	*/
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(dbr)
{
	/* uncomment this line if you have INI entries
	UNREGISTER_INI_ENTRIES();
	*/
	return SUCCESS;
}
/* }}} */

/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(dbr)
{
	return SUCCESS;
}
/* }}} */

/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
PHP_RSHUTDOWN_FUNCTION(dbr)
{
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(dbr)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "dbr support", "enabled");
	php_info_print_table_end();

	/* Remove comments if you have entries in php.ini
	DISPLAY_INI_ENTRIES();
	*/
}
/* }}} */

// 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";
}

PHP_FUNCTION(DecodeBarcodeFile)
{
	array_init(return_value);

	// Get Barcode image path
	char* pFileName = NULL;
	int barcodeType = 0;
	int iLen = 0;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &pFileName, &iLen, &barcodeType) == FAILURE) {
        RETURN_STRING("Invalid parameters", true);
    }
	
	// Dynamsoft Barcode Reader: init
	__int64 llFormat = barcodeType > 0 ? barcodeType : (OneD | QR_CODE | PDF417 | DATAMATRIX);
	int iMaxCount = 0x7FFFFFFF;
	int iIndex = 0;
	ReaderOptions ro = {0};
	pBarcodeResultArray pResults = NULL;
	int iRet = -1;
	char * pszTemp = NULL;

	// Initialize license
	iRet = DBR_InitLicense("84D34246FC1BC4BDD4078D71FCB5A3AA");
	printf("DBR_InitLicense ret: %d\n", iRet);
	ro.llBarcodeFormat = llFormat;
	ro.iMaxBarcodesNumPerPage = iMaxCount;

	// Decode barcode image
	int ret = DBR_DecodeFile(pFileName, &ro, &pResults);
	if (ret == DBR_OK)
	{
		int count = pResults->iBarcodeCount;
		pBarcodeResult* ppBarcodes = pResults->ppBarcodes;
		pBarcodeResult tmp = NULL;
		char result[2048] = {0};
		int i = 0;
		if (count == 0)
		{
			add_next_index_string(return_value, "No Barcode detected", true);
		}

		// loop all results
		for (; i < count; i++)
		{
			char barcodeResult[1024];

			// A barcode result.
			tmp = ppBarcodes[i];
			{
				// Working with PHP array: http://php.net/manual/en/internals2.variables.arrays.php
				zval *tmp_array;
				// Initialize zval
				MAKE_STD_ZVAL(tmp_array);
				array_init(tmp_array);
				// Add format & value to an array
				add_next_index_string(tmp_array, GetFormatStr(tmp->llFormat), true);
				add_next_index_string(tmp_array, tmp->pBarcodeData, true);
				// Add result to returned array
				add_next_index_zval(return_value, tmp_array);
			}
		}

		// Dynamsoft Barcode Reader: release memory
		DBR_FreeBarcodeResults(&pResults);
	}
	else
	{
		add_next_index_string(return_value, "No Barcode detected", true);
	}

}

To build PHP extension independently, you need to use phpize, which is a shell script to prepare PHP extension for compiling. Install the dev package as follows:

sudo apt-get install php5-dev

Build the extension with following commands:

phpize
./configure
make

C90 does not support the boolean data type. If you see the error “unknown type name ‘bool’”, please include the header file:

#include <stdbool.h>

A shared library dbr.so is generated under folder modules:

php extension generated

Simple PHP Barcode Reader

Create reader.php:

<?php
$filename = "/home/xiao/Dynamsoft/BarcodeReader4.0/Images/AllSupportedBarcodeTypes.tif";
if (file_exists($filename)) {
  echo "Barcode file: $filename \n";
  $resultArray = DecodeBarcodeFile($filename, 0);
  if (is_array($resultArray[0])) {
	$resultCount = count($resultArray);
	echo "Total count: $resultCount\n";
	for($i = 0; $i < $resultCount ; $i++) {
		$result = $resultArray[$i];
        	echo "Barcode format: $result[0], value: $result[1]\n";
	}
  }
  else {
    echo "$resultArray[0]";
  }
} else {
    echo "The file $filename does not exist";
}
?>

Install the PHP Barcode extension:

sudo make install

To load the custom extension, you have to add the library path (e.g. /usr/lib/php5/20121212/dbr.so ) into php.ini:

locate php.ini

php.ini path

You may ask which php.ini file should be used? The answer is that you can modify any php.ini file or make it yourself. When executing PHP script, you can designate the php.ini file. I picked php.ini-production and then added the following line:

extension=/usr/lib/php5/20121212/dbr.so

Test the simple PHP barcode reader:

php -c /usr/share/php5/php.ini-production reader.php

linux php barcode reader

Source Code

https://github.com/dynamsoftlabs/linux-php-barcode-reader-


How to Build Cross-platform Desktop Barcode App with Electron

$
0
0

Building desktop applications is not as easy as building web applications because it is platform-related. You may need to learn C# for Windows, C/C++ for Linux, and Swift for Mac. For Java developers, it is convenient to create universal desktop applications in Swing and JavaFX. What about web developers, who have never learned server-side programming languages? Thanks to Electron, which combines Chromium and Node.js. It enables web developers to use HTML, CSS, and JavaScript to build cross-platform desktop applications.

Making Native Desktop Barcode Reader with Electron

Get the source code of Electron Quick Start:

git clone https://github.com/atom/electron-quick-start

Here are the basic files used by Electron applications:

  • index.htm – A web page to render.
  • main.js – Starts the app and creates a browser window to render HTML.
  • package.json – Points to the app’s main file and lists its details and dependencies.

You just need to change the code in index.htm. In contrast to web client development, you can now integrate node JavaScript code to HTML page. To read barcodes, require the module built yourself using node-gyp:

<script type="text/javascript">
        function fileSelected() {
            var count = document.getElementById('fileToUpload').files.length;
            if (count > 0) {
                var file = document.getElementById('fileToUpload').files[0];
                document.getElementById('filename').value = file.name;
            }
        }
        function getSelectedBarcodeTypes() {
        	  var vType = 0;
        	  var barcodeType = document.getElementsByName("BarcodeType");
            for (i = 0; i < barcodeType.length; i++) {
                if (barcodeType[i].checked == true)
                    vType = vType | (barcodeType[i].value * 1);
            }
            return vType;
        }
        function doReadBarcode() {
            var dbr = require('../build/Release/dbr');
            var fileName = document.getElementById('fileToUpload').files[0].path;
            var barcodeType = 0;
            dbr.decodeFile(
                "3160E70D97D76437446DB71BD7B8FB32", fileName, getSelectedBarcodeTypes(),
                function(msg) {
                    var response = 'Totol count: ' + msg.length;
                    var result = null;
                    for (index in msg) {
                        result = msg[index]
                        response += '<p>' + result['format'] + ': ';
                        response += result['value'] + '<p>';
                    }
                    document.getElementById('resultBox').innerHTML = response;
                }
            );
        }
    </script>

If you have no idea how to build the barcode module using Dynamsoft Barcode Reader SDK, please read the post – How to Build Node.js Barcode Reader on Windows, Linux and Mac.

Probably you will see the error message “Uncaught Error: A dynamic link library (DLL) initialization routine failed” when loading node module:

A dynamic link library initialization routine failed

The reason is that Electron uses a different V8 version from official Node. To fix the issue, you have to manually specify the location of Electron’s headers when building native modules:

# check electron version
electron –v

# rebuild the native node module
node-gyp rebuild --target=0.36.7 --arch=x64 --dist-url=https://atom.io/download/atom-shell

Install dependencies:

npm install

Start the barcode reader application:

npm start

Electron Barcode Reader on Windows, Linux and Mac

Windows

electron windows barcode reader

Linux

electron linux barcode reader

Mac

electron mac barcode reader

Source Code

https://github.com/yushulx/nodejs-barcode-for-win-linux-mac/tree/master/electron

 

How to Build C/C++ Barcode Reader App for Raspberry Pi

$
0
0

I have been playing Pi Emulator for a while. It is time to get my hands dirty on the real Pi device. In this post, I would share how to build my first C/C++ barcode reader application on Raspberry Pi.

Configure Static IP Address on Raspbian Jessie

By default, the Pi system configures DHCP for network access. In my company, I can only use static IP address, and thus, I have to manually set it up.

When searching Google for how to configure static IP address on Raspberry Pi, I found an answer:

  1. Open /etc/network/interfaces.
  2. Change “iface eth0 inet dhcp” to “iface eth0 inet static”.

The answer is correct but only works for Raspbian Wheezy, which is an older version of Raspberry Pi Linux OS. You don’t need to touch the file on Raspbian Jessie. Here is the right way:

  1. Open /etc/dhcpcd.conf.
  2. Add the static IP configuration:
    interface eth0
    static routers=192.168.8.2
    static domain_name_servers=8.8.8.8
    static ip_address=192.168.8.51

Reboot the device to make the setting work.

Build Barcode Reader App on Raspberry Pi

Dynamsoft Barcode Reader is now available for Raspberry Pi. I made a little bit of change to the sample code that included in the SDK.

Copy source files to Raspberry Pi with SCP. Here is the project structure:

raspberry pi barcode project

This is the only method that needed to read the barcode image:

iRet = DBR_DecodeFile(pszImageFile, &ro, &paryResult);

Build the project:

cd samples/c
make

Test it with a barcode image:

./BarcodeReaderDemo ../../AllSupportedBarcodeTypes.tif

RaspberryPi barcode reader result

Pretty easy! If you are interested in the barcode SDK for Raspberry Pi, please contact support@dynamsoft.com to get a trial version. The library libDynamsoftBarcodeReader.so is not publicly available yet.

Source Code

https://github.com/dynamsoftlabs/raspberrypi-barcode-reader

How to Build Node.js Barcode Reader on Raspberry Pi

$
0
0

Node.js is available for all platforms including IoT devices like Raspberry Pi. In this post, I will demonstrate how to quickly create an online barcode reader on Raspberry Pi using Node.js and Dynamsoft Barcode Reader SDK.

Node.js for Raspberry Pi

If you flashed Rasbian Jessie, the latest Linux ROM for Raspberry Pi, you might have noticed that Node.js is pre-installed by default. Nevertheless, the Node version is out of date. To get new features of Node.js, download the latest version.

Here are the steps to install Node.js for Raspberry Pi:

  1. Remove the pre-installed Node.js:
    sudo apt-get remove node
  2. Check Pi hardware information:
    uname –m
    armv7l
  3. Download the matched Node version for ARM.
  4. Extract the package:
    tar –xf node-v4.4.1-linux-armv7l.tar.xz
  5. Add the bin path to ~/.bashrc:
    vim ~/.bashrc
    export PATH=$PATH:/home/pi/node-v4.4.0-linux-armv7l/bin
    source ~/.bashrc
  6. Check whether Node can work:
    node –v
    v4.4.0

Building Online Barcode Reader

Get barcode SDK. The Dynamsoft Barcode Reader SDK for Raspberry Pi is not publicly available yet. To get a trial version, contact support@dynamsoft.com.

Extract the package and generate a symbolic link:

sudo ln -s <DynamsoftBarcodeReader>/lib/libDynamsoftBarcodeReader.so /usr/lib/libDynamsoftBarcodeReader.so

Install node-gyp for building Node C/C++ addons:

npm install -g node-gyp

Create dbr.cc and binding.gyp:

        
    // dbr.cc
    Isolate* isolate = Isolate::GetCurrent();
	HandleScope scope(isolate);

	// convert v8 string to char *
	String::Utf8Value license(args[0]->ToString());
	String::Utf8Value fileName(args[1]->ToString());
	char *pFileName = *fileName;
	char *pszLicense = *license;
	// Dynamsoft Barcode Reader: init
	__int64 llFormat = args[2]->IntegerValue();
	int iMaxCount = 0x7FFFFFFF;
	ReaderOptions ro = {0};
	pBarcodeResultArray pResults = NULL;

	// Initialize license
	if (pszLicense && (strcmp(pszLicense, "null") !=0) )
	{
		printf("license: %s\n", pszLicense);
		DBR_InitLicense(pszLicense);
	}
	else {
		#ifdef LINUX_DBR
				printf("Linux dbr license\n");
				DBR_InitLicense("<license>");
		#endif
	}

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

	// Decode barcode image
	int ret = DBR_DecodeFile(pFileName, &ro, &pResults);
// binding.gyp
{
  "targets": [
    {
      'target_name': "dbr",
      'sources': [ "dbr.cc" ],
      'conditions': [
          ['OS=="linux"', {
            'defines': [
              'LINUX_DBR',
            ],
            'include_dirs': [
                "/home/pi/Desktop/dbr/include"
            ],
            'libraries': [
                "-lDynamsoftBarcodeReader", "-L/home/pi/Desktop/dbr/lib"
            ]
          }]
      ]
    }
  ]
}

Build dbr.so:

node-gyp build

Install Node modules express and formidable for rapidly making a Web project:

npm install express formidable

Use the barcode module in server.js:

var dbr = require('./build/Release/dbr');

dbr.decodeFile(

    license, fileName, barcodeType,

    function(msg) {

        var response = 'Totol count: ' + msg.length;

        var result = null;

        for (index in msg) {

            result = msg[index]

            response += '<p>' + result['format'] + ': ';

            response += result['value'] + '<p>';

        }

        res.send(response);

    }

);

Start the server:

node server.js

Visit http://localhost:2016/index.htm:

raspberry pi node.js barcode reader

Source Code

https://github.com/dynamsoftlabs/raspberry-pi-nodejs-barcode-reader-

 

Raspberry Pi Barcode Scanner with Webcam and Python

$
0
0

Previously, I shared an article describing how to create an online barcode reader using Node.js, which turned Raspberry Pi into a web server. Today, I want to do another experiment – turning Raspberry Pi into a barcode scanner with a USB webcam. For taking HD video and photo, you can choose Raspberry Pi camera module.

Raspberry Pi Webcam

How to Use Webcam with Raspberry Pi

To check whether the Linux system can identify the USB webcam, use the following commands:

lsusb
ls /dev/video*

linux webcam detection

Install fswebcam:

sudo apt-get install fswebcam

Take a picture from webcam:

fswebcam test.jpg

Raspberry Pi webcam capture

If the webcam can work well, you can take the next step.

Building Custom C/C++ Extension for Python

Contact support@dynamsoft.com to get the download link of Dynamsoft Barcode Reader C/C++ SDK for Raspberry Pi.

Extract the package and generate the symbolic link:

sudo ln -s $(DynamsoftBarcodeReader)/lib/libDynamsoftBarcodeReader.so /usr/lib/libDynamsoftBarcodeReader.so

Create dbr.c in which you need to glue Dynamsoft Barcode Reader APIs to Python native code:

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);
    
    {
        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:

from distutils.core import setup, Extension

module_dbr = Extension('dbr', 
                        sources = ['dbr.c'], 
                        include_dirs=['/home/pi/Desktop/dbr/include'],
                        library_dirs=['/home/pi/Desktop/dbr/lib'],
                        libraries=['DynamsoftBarcodeReader'])

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

Build and install the Python module:

python setup.py build
sudo python setup.py install

Python custom extension install

Installing OpenCV on Raspbian Jessie

To capture images from a webcam, we can use OpenCV. Read the excellent article that demonstrates how to install OpenCV on Raspbian Jessie.

Opencv for Raspberry Pi

Barcode Scanner in Python

Create cam_reader.py:

cv2.namedWindow("preview")
	vc = cv2.VideoCapture(0)
	cache = ""
	results = None

	if vc.isOpened(): # try to get the first frame
		initLicense("64E4EE3532B813C8EA8EA5F34E7B4528")
		rval, frame = vc.read()
	else:
	    rval = False

	while rval:
	    cv2.imshow("preview", frame)
	    rval, frame = vc.read()

	    key = cv2.waitKey(20)
	    if key == ord('c'):
			cache = getImageName()
			cv2.imwrite(cache, frame)
			results = decodeFile(cache)
			print "Total count: " + str(len(results))
			for result in results:
				print "barcode format: " + formats[result[0]]
				print "barcode value: " + result[1] + "\n*************************"
	    elif key == 27:
	    	break

	cv2.destroyWindow("preview")

Run the script:

python cam_reader.py

Capture and read barcode by pressing key ‘C’.

Raspberry Pi Barcode Scanner Result

Source Code

https://github.com/dynamsoftlabs/webcam-barcode-scanner-for-pi

Mobile 1D/2D Barcode Reader Using HTML5 and ASP.NET

$
0
0

On mobile platforms, HTML5 is not only supported by web browsers, such as Safari, Firefox, Opera, Chrome, but also web view UI component that used for building native apps. The benefit is apparent that any developer who is familiar with web programming could easily create excellent mobile apps for Android and iOS. Dynamsoft Barcode Reader SDK provides .NET APIs for Windows. You can implement a barcode reading module on server-side (IIS), and detect barcode images that captured from any mobile devices using HTML5. The article will illustrate how to make a mobile barcode reader based on B/S (Browser/Server) architecture.

This article has been posted on CodeProject.

Getting Started with Mobile Barcode Reader

Invoking Mobile Device Camera in HTML5 on Mobile Devices

To access mobile device camera in HTML5, you just need one line of code:

<input type="file" name="fileToUpload" id="fileToUpload" style="display: none;" accept="image/*" />

Click “Grab Image”, the native camera app will be brought to the front-end:

html5 mobile barcode reader ui

After taking a photo and switching back, you can get the image data as follows:

var file = e.target.files[0], imageType = /image.*/;


if (!file.type.match(imageType))

{

alert('The uploaded file is not supported.');

return;

}


btnGrab.disabled = true;

btnRead.disabled = true;


loadImage(e.target.files[0],

function (img) {


$("#divBorder").empty();

$('#divBorder').attr('min-height', '1px');

document.getElementById('divBorder').appendChild(img);


btnGrab.disabled = false;

btnRead.disabled = false;

});

 

Uploading Captured Images Using JavaScript

Convert the image data to Base64 string:

function scanBarcode() {

var base64 = orgCanvas.toDataURL('image/jpeg', 0.7);

var data = base64.replace(/^data:image\/(png|jpeg|jpg);base64,/, "");

var imgData = JSON.stringify({

Base64Data: data,

BarcodeType: getBarcodeFormat().toString(),

MultiBarcodes: document.getElementById('chkMultiBarcodes').checked

});



readBarcodeRequest(imgData);

}

 

Send the JSON data to web server using XMLHttpRequest:

function readBarcodeRequest(data) {

xhr = new XMLHttpRequest();



xhr.addEventListener("load", uploadComplete, false);



xhr.addEventListener("error", uploadFailed, false);



xhr.addEventListener("abort", uploadCanceled, false);



xhr.upload.addEventListener('progress',uploadProgress, false);



xhr.open("POST", "MobilecamBarcodeReader.ashx");

xhr.setRequestHeader('Content-Type', 'application/json');

xhr.send(data);

}

 

Handling Base64 Data in ASP.NET

Get the stream data with StreamReader:

context.Request.InputStream.Position = 0;

string jsonString;

using (var inputStream = new StreamReader(context.Request.InputStream))

{

jsonString = inputStream.ReadToEnd();

}

 

Convert the string to JSON object:

var postData = JsonConvert.DeserializeObject<PostData>(@jsonString);

if (postData == null) return;

var iMaxNumbers = postData.MultiBarcodes ? 100 : 1;

 

Reading Barcode on IIS Server-side

Specify a valid license to make the detection API work:

public static BarcodeResult[] GetBarcode(string strImgBase64, Int64 format, int iMaxNumbers)

{

var reader = new Dynamsoft.Barcode.BarcodeReader();

var options = new ReaderOptions

{

MaxBarcodesToReadPerPage = iMaxNumbers,

BarcodeFormats = (BarcodeFormat) format

};



reader.ReaderOptions = options;

reader.LicenseKeys = "<license>";

return reader.DecodeBase64String(strImgBase64);

}



var strResult = "";

BarrecodeReaderRepo.Barcode(postData.Base64Data, postData.BarcodeType, iMaxNumbers, ref strResult);



strResult += DateTime.Now;

context.Response.Write(strResult);

You can use Base64 string, byte array or file name as the input.

html5 mobile barcode reader result

Demo

Online Barcode Reader

Sample Code

Download

 

The post Mobile 1D/2D Barcode Reader Using HTML5 and ASP.NET appeared first on Code Pool.

Real-time Webcam Barcode Detection with OpenCV and C++

$
0
0

Dynamsoft Barcode Reader C++ SDK is available for Windows, Linux, and Mac (iOS and Android editions are coming soon). I have shared an article that illustrates how to build webcam barcode reader in Python. In this tutorial, I’ll use a different C++ API to implement barcode scanner applications for Windows and Raspberry Pi with a webcam.

Prerequisites

Windows

Raspberry Pi

Getting Started with Webcam Barcode Reader

How to capture frame from webcam using OpenCV

       VideoCapture cap(0);
       if (!cap.isOpened())
              return -1;
       Mat frame;
       for (;;)
       {
              cap >> frame; // Get a new frame from camera
              imshow(windowName, frame); // Display the new frame
              if (waitKey(30) >= 0)
                     break;
       }

How to initialize Dynamsoft Barcode Reader

       CBarcodeReader reader;
       reader.InitLicense("38B9B94D8B0E2B41660D13B593BE6EF9");
       __int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX);
       int iMaxCount = 0x7FFFFFFF;
       ReaderOptions ro = { 0 };
       ro.llBarcodeFormat = llFormat;
       ro.iMaxBarcodesNumPerPage = iMaxCount;
       reader.SetReaderOptions(ro);

How to pre-process camera frame buffer

The barcode API only takes DIB (device-independent bitmap) structure as the input data, and thus, you have to re-construct the buffer wrapped in Mat:

       int elemSize = image.elemSize();
       int size = image.total() * elemSize;
       // Get image data
       char *imageData = (char *)image.data;

       // Combine header info and image data
       int width = image.cols, height = image.rows;
       char *total = (char *)malloc(size + 40);

       if (!total)
       {
              printf("Failed to allocate memory");
              return;
       }

       memset(total, 0, size + 40);
       BITMAPINFOHEADER bitmap_info = { 40, width, height, 0, 24, 0, size, 0, 0, 0, 0 };
       memcpy(total, &bitmap_info, 40);

       char *data = total + 40;
       // Reverse the image buffer from bottom to top
       width *= 3;

       for (int i = 1; i <= height; i++)
       {
              memcpy(data, imageData + width * (height - i), width);
              data += width;
       }

Reading barcode image buffer on Windows

       int iRet = reader.DecodeBuffer((unsigned char*)total, size + 40);

       char * pszTemp = (char*)malloc(4096);
       if (iRet != DBR_OK && iRet != DBRERR_LICENSE_EXPIRED && iRet != DBRERR_QR_LICENSE_INVALID &&
              iRet != DBRERR_1D_LICENSE_INVALID && iRet != DBRERR_PDF417_LICENSE_INVALID && iRet != DBRERR_DATAMATRIX_LICENSE_INVALID)
       {
              sprintf(pszTemp, "Failed to read barcode: %s\r\n", DBR_GetErrorString(iRet));
              printf(pszTemp);
              free(pszTemp);
              free(total);
              return;
       }

       pBarcodeResultArray paryResult = NULL;
       reader.GetBarcodes(&paryResult);

       if (paryResult->iBarcodeCount > 0)
       {
              for (int iIndex = 0; iIndex < paryResult->iBarcodeCount; iIndex++)
              {
                     sprintf(pszTemp, "Barcode %d:\r\n", iIndex + 1);
                     printf(pszTemp);
                     sprintf(pszTemp, "    Page: %d\r\n", paryResult->ppBarcodes[iIndex]->iPageNum);
                     printf(pszTemp);
                     sprintf(pszTemp, "    Type: %s\r\n", GetFormatStr(paryResult->ppBarcodes[iIndex]->llFormat));
                     printf(pszTemp);
                     char *pszTemp1 = (char*)malloc(paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
                     memset(pszTemp1, 0, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
                     memcpy(pszTemp1, paryResult->ppBarcodes[iIndex]->pBarcodeData, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength);
                     sprintf(pszTemp, "    Value: %s\r\n", pszTemp1);
                     printf(pszTemp);
                     free(pszTemp1);
                     sprintf(pszTemp, "    Region: {Left: %d, Top: %d, Width: %d, Height: %d}\r\n\r\n",
                           paryResult->ppBarcodes[iIndex]->iLeft, paryResult->ppBarcodes[iIndex]->iTop,
                           paryResult->ppBarcodes[iIndex]->iWidth, paryResult->ppBarcodes[iIndex]->iHeight);
                     printf(pszTemp);
              }
       }

       free(pszTemp);
       reader.FreeBarcodeResults(&paryResult);
       free(total);

webcam barcode scanner in C/C++

Reading barcode image buffer on Linux

Porting the source code from Windows to Linux is a little bit tricky because DIB structure is not defined on Linux platform. We can define it ourselves:

typedef unsigned long       DWORD;
typedef long LONG;
typedef unsigned short      WORD;

typedef struct tagBITMAPINFOHEADER {
      DWORD biSize;
        LONG  biWidth;
          LONG  biHeight;
            WORD  biPlanes;
              WORD  biBitCount;
                DWORD biCompression;
                  DWORD biSizeImage;
                    LONG  biXPelsPerMeter;
                      LONG  biYPelsPerMeter;
                        DWORD biClrUsed;
                          DWORD biClrImportant;

} BITMAPINFOHEADER;

Build the source code:

g++ -ggdb -I$(DynamsoftBarcodeReader)/include -o barcodereader barcodereader.cpp -lDynamsoftBarcodeReader `pkg-config --libs opencv`

Source Code

https://github.com/dynamsoftlabs/cplusplus-webcam-barcode-reader

The post Real-time Webcam Barcode Detection with OpenCV and C++ appeared first on Code Pool.

Webcam Barcode Scanner with HTML5 and Web Browser

$
0
0

As Internet connection speed getting faster, more and more people tend to embrace cloud service. Any desktop applications could be transformed to cloud applications with better maintainability, security, and stability. End-users can use web browsers to get connected with social friends, store tons of personal data, watch live video, edit documents, publish blog posts and even write code. As a programmer, if you are still developing desktop applications, it is time to think about how to turn your apps into web services. In this article, we will take a glimpse of how to make webcam barcode scanner with Dynamic Barcode Reader SDK work and web technologies.

This article has been posted on CodeProject.

webcam barcode scanner

Implementation of Webcam Barcode Scanner

  1. Open Visual Studio to create a new web project.
  2. Click References to import Dynamsoft.BarcodeReader.dll.
  3. Create a C# class BarrecodeReaderRepo to handle barcode detection on the server-side:
    using System;
    using System.Drawing;
    using System.IO;
    using Dynamsoft.Barcode;
    
    namespace BarcodeDLL
    {
        public class BarrecodeReaderRepo
        {
            private static readonly char CSep = Path.DirectorySeparatorChar;
            private static readonly string StrPath = AppDomain.CurrentDomain.BaseDirectory + "Images";
            private static readonly string CollectFolder = StrPath + CSep + "Collect";
    
            public static string Barcode(string strImgBase64, Int64 iformat, int iMaxNumbers, ref string strResult)
            {
                if (string.IsNullOrEmpty(strImgBase64.Trim())) throw new Exception("No barcode exist.");
    
                return DoBarcode(strImgBase64, iformat, iMaxNumbers, ref strResult);
            }
    
            private static string DoBarcode(string strImgBase64, Int64 format, int iMaxNumbers, ref string strResult)
            {
                strResult = "";
                var strResturn = "[";
    
                var listResult = GetBarcode(strImgBase64, format, iMaxNumbers);
    
                if (listResult == null || listResult.Length == 0)
                {
                    strResult = "No barcode found. ";
                    return "[]";
                }
                strResult = "Total barcode(s) found: " + listResult.Length + "<br/>";
                var i = 1;
                foreach (var item in listResult)
                {
                    strResult = strResult + "&nbsp&nbspBarcode " + i + ":<br/>";
                    strResult = strResult + "&nbsp&nbsp&nbsp&nbspType: " + item.BarcodeFormat + "<br/>";
                    strResult = strResult + "&nbsp&nbsp&nbsp&nbspValue: " + item.BarcodeText + "<br/>";
                    strResult = strResult + "&nbsp&nbsp&nbsp&nbspRegion: {Left: " + item.ResultPoints[0].X
                                + ", Top: " + item.ResultPoints[0].Y
                                + ", Width: " + item.BoundingRect.Width
                                + ", Height: " + item.BoundingRect.Height + "}<br/>";
                    i++;
                }
                strResturn = strResturn.Substring(0, strResturn.Length - 1);
                strResturn += "]";
                return strResturn;
            }
    
            public static BarcodeResult[] GetBarcode(string strImgBase64, Int64 format, int iMaxNumbers)
            {
                var reader = new Dynamsoft.Barcode.BarcodeReader();
                var options = new ReaderOptions
                {
                    MaxBarcodesToReadPerPage = iMaxNumbers,
                    BarcodeFormats = (BarcodeFormat) format
                };
    
                reader.ReaderOptions = options;
                reader.LicenseKeys = "693C401F1CC972A511F060EA05D537CD";
                return reader.DecodeBase64String(strImgBase64);
            }
        }
    }
    
  4. Create a Generic Handler WebcamBarcodeReader.ashx to process the HTTP request. Parse stream to get the base64 string, and then pass it to BarrecodeReaderRepo:
    public class WebcamBarcodeReader : IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                try
                {
                    // 1. Get Base64 Stream
                    context.Request.InputStream.Position = 0;
                    string jsonString;
                    using (var inputStream = new StreamReader(context.Request.InputStream))
                    {
                        jsonString = inputStream.ReadToEnd();
                    }
                    var postData = JsonConvert.DeserializeObject<PostData>(@jsonString);
                    
                    if (postData == null) return;
                    
                    // 2. reader barcode and output result
                    var strResult = "";
                    BarrecodeReaderRepo.Barcode(postData.Base64Data, postData.BarcodeType, 10, ref strResult);
                    if (strResult.IndexOf("No barcode found", StringComparison.Ordinal) == -1)
                    {
                        strResult = "|" + strResult; 
                    }
    
                    strResult += DateTime.Now;
                    context.Response.Write(strResult);
                }
                catch (Exception exp)
                {
                    context.Response.Write("Error: " + exp.Message);
                }
            }
    
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
    
            public class PostData
            {
                public string Base64Data { get; set; }
                public int BarcodeType { get; set; }
            }
        }
  5. Create an element <video></video>. Open a webcam in a web page with the HTML5 API getUserMedia:
    function toggleCamera() {
        var videoSource = videoSelect.value;
        var constraints = {
            video: {
                optional: [{
                    sourceId: videoSource
                }]
            }
        };
    
        startCamera(constraints);
    }
    
    // Start camera preview on <video></video>
    function successCallback(stream) {
        window.stream = stream;
        videoElement.src = window.URL.createObjectURL(stream);
        videoElement.play();
    }
    
    function errorCallback(error) {
        console.log("Error: " + error);
    }
    
    function startCamera(constraints) {
        if (navigator.getUserMedia) {
            navigator.getUserMedia(constraints, successCallback, errorCallback);
        } else {
            console.log("getUserMedia not supported");
        }
    }
  6. How to send preview images to the remote server? Keep drawing frames on a hidden canvas. Convert the canvas data to base64 string and send it in Ajax. If there is nothing detected, use the method setTimeout to send the preview data for detection again:
    context.drawImage(videoElement, 0, 0, width, height);
    // convert canvas to base64
    var base64 = dbrCanvas.toDataURL('image/png', 1.0);
    var data = base64.replace(/^data:image\/(png|jpeg|jpg);base64,/, "");
    var imgData = JSON.stringify({
        Base64Data: data,
        BarcodeType: getBarcodeFormat()
    });
    $.ajax({
        url: 'WebcamBarcodeReader.ashx',
        dataType: 'json',
        data: imgData,
        type: 'POST',
        complete: function (result) {
            console.log(result);
            if (isPaused) {
                return;
            }
            var barcode_result = document.getElementById('dbr');
            var aryResult;
            aryResult = result.responseText.split('|');
    
            // display barcode result
            if (result.responseText.indexOf("No barcode") == -1) {
                resetButtonGo();
                barcode_result.innerHTML = result.responseText.substring(aryResult[0].length + 1);
            }
            else {
                barcode_result.innerHTML = result.responseText;
                setTimeout(scanBarcode, 200);
            }
        }
    });

Online Demo

Try it now!

Sample Code

Download

 

The post Webcam Barcode Scanner with HTML5 and Web Browser appeared first on Code Pool.


Barcode Scanner Optimization for Raspberry Pi

$
0
0

Although we have successfully ported Dynamsoft Barcode Reader SDK to Raspberry Pi, the performance is not as good as I expected. In my previous article, I demonstrated how to integrate the SDK into a barcode scanner application, in which the detection code works with webcam frame in the same thread. Apparently, it will block UI if the algorithm costs too much time. In this post, I will do three things: optimize the code with thread, beautify the code with clang-format, and make the webcam barcode scanner auto-launched after the system booted.

raspberry pi webcam barcode scanner

Webcam Barcode Scanner Optimization

Move barcode detection code to thread

To avoid blocking the UI thread, we should move the heavy work to a worker thread. The UI thread continuously writes frame to the shared buffer. In the meantime, the worker thread loads the shared buffer after every detection work is done.

Create mutex for locking the shared resource:

pthread_mutex_t image_mutex;

int res = pthread_mutex_init(&image_mutex, NULL);
if (res) {
    perror("Mutex initialization failed");
    exit(EXIT_FAILURE);
}

pthread_mutex_lock(&image_mutex);
memcpy(imageData.data, (char *)frame.data, size);
pthread_mutex_unlock(&image_mutex);

pthread_mutex_destroy(&image_mutex);

Create a thread function and a thread using pthread:

void *thread_function(void *arg) {
  int width, height, size, elemSize;
  char *buffer;
  // Get frame info
  pthread_mutex_lock(&image_mutex);
  width = imageData.width;
  height = imageData.height;
  elemSize = imageData.elemSize;
  size = imageData.size;
  buffer = (char *)malloc(size);
  pthread_mutex_unlock(&image_mutex);

  while (isDBRWorking) {
    // Get the frame buffer
    pthread_mutex_lock(&image_mutex);
    memcpy(buffer, imageData.data, size);
    pthread_mutex_unlock(&image_mutex);

    // Decode barcode
  }
  free(buffer);
  printf("Thread is over. \n");
}

isDBRWorking = true;
pthread_t dbr_thread;
res = pthread_create(&dbr_thread, NULL, thread_function, NULL);
if (res) {
    perror("Thread creation failed");
}

Beautify C/C++ code with clang-format

Install clang-format:

sudo apt-get install clang-format-3.7

Beautify the code with Google style:

clang-format-3.7 –style=Google barcodereader.cpp > output.cpp

Auto-launch barcode scanner after booting Raspberry Pi

Assume you want to create a robot with webcam and Raspberry Pi for barcode detection. There is no display screen connected, and you want to automatically launch the barcode scanning application once the Pi system booted. How to make it?

  1. Set boot option with Console Autologin:
    sudo raspi-config

    rpi boot option
    rpi auto login

  1. Create a shell script run_barcode_scanner.sh:
    /home/pi/<project-directory>/barcodereader
  1. Edit /etc/profile:
    sudo vim /etc/profile
    
    # Add the following line to the end of the file
    . /home/pi/run_barcode_scanner.sh
  1. Reboot system to automatically launch webcam barcode scanner:
    sudo reboot

Source Code

https://github.com/dynamsoftlabs/cplusplus-webcam-barcode-reader/blob/no-display/RaspberryPi/barcodereader.cpp

The post Barcode Scanner Optimization for Raspberry Pi appeared first on Code Pool.

How to Make Android Barcode Reader with Barcode SDK

$
0
0

When building mobile barcode scanning apps for Android or iOS, developers could either choose open source SDKs – ZXing and ZBar, or some commercial mobile barcode SDKs. If you are an Android developer and have installed Android Play Services SDK level 26 or greater, it is convenient to create Android barcode reader apps with Android Vision API as well. Since Google has released a demo on GitHub, we can learn how to construct a simple Android barcode reader from the source code. Let’s anatomize the code and try to build our own version.

Android Barcode Demo with Google Vision API

Get the sample code of Android vision from https://github.com/googlesamples/android-vision, and load barcode-reader folder to Android Studio.

Press Ctrl+Alt+Shift+N to globally search for onPreviewFrame (CameraSource.java) which is the entry that we can get started with camera preview data:

private class CameraPreviewCallback implements Camera.PreviewCallback {
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        mFrameProcessor.setNextFrame(data, camera);
    }
}

The mFrameProcessor is the instance of class FrameProcessingRunnable. According to the class name, we can speculate that it will process preview data in a worker thread. The advantage is that if the barcode detection API costs too much time, it will not block UI thread.

Take a look at setNextFrame which uses synchronization to lock the data. Once a frame of preview data is cached, it will notify the worker thread to do the reading work.

void setNextFrame(byte[] data, Camera camera) {
    synchronized (mLock) {
        if (mPendingFrameData != null) {
            camera.addCallbackBuffer(mPendingFrameData.array());
            mPendingFrameData = null;
        }

        // Timestamp and frame ID are maintained here, which will give downstream code some
        // idea of the timing of frames received and when frames were dropped along the way.
        mPendingTimeMillis = SystemClock.elapsedRealtime() - mStartTimeMillis;
        mPendingFrameId++;
        mPendingFrameData = mBytesToByteBuffer.get(data);

        // Notify the processor thread if it is waiting on the next frame (see below).
        mLock.notifyAll();
    }
}

Press Ctrl+F12 to search for run:

public void run() {
            Frame outputFrame;
            ByteBuffer data;

            while (true) {
                synchronized (mLock) {
                    if (mActive && (mPendingFrameData == null)) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException e) {
                            Log.d(TAG, "Frame processing loop terminated.", e);
                            return;
                        }
                    }

                    if (!mActive) {
                        return;
                    }

                    outputFrame = new Frame.Builder()
                            .setImageData(mPendingFrameData, mPreviewSize.getWidth(),
                                    mPreviewSize.getHeight(), ImageFormat.NV21)
                            .setId(mPendingFrameId)
                            .setTimestampMillis(mPendingTimeMillis)
                            .setRotation(mRotation)
                            .build();

                    data = mPendingFrameData;
                    mPendingFrameData = null;
                }

                try {
                    mDetector.receiveFrame(outputFrame);
                } catch (Throwable t) {
                    Log.e(TAG, "Exception thrown from receiver.", t);
                } finally {
                    mCamera.addCallbackBuffer(data.array());
                }
            }
        }

android barcode thread run

Use the cached data to construct an output frame, and detect it with receiveFrame which is an asynchronous interface.

To receive the results, associate multi-processor instance (BarcodeCaptureActivity.java) to barcode detector:

BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay);
barcodeDetector.setProcessor(new MultiProcessor.Builder<>(barcodeFactory).build());

Create a tracker (BarcodeTrackerFactory.java) for each barcode:

@Override
public Tracker<Barcode> create(Barcode barcode) {
    BarcodeGraphic graphic = new BarcodeGraphic(mGraphicOverlay);
    return new BarcodeGraphicTracker(mGraphicOverlay, graphic);
}

Update graphics (BarcodeGraphicTracker.java) as follows:

@Override
public void onUpdate(Detector.Detections<Barcode> detectionResults, Barcode item) {
    mOverlay.add(mGraphic);
    mGraphic.updateItem(item);
}

Android Barcode Reader with Third-Party SDK

Google’s demo is a skeleton for us. Based on it, we don’t need to write barcode reader from scratch. I will add some barcode format options and replace the Google Vision API with the preview version of Dynamsoft mobile barcode SDK:

Dynamsoft Android barcode sdk

Create a LinearLayout and add four Switch widgets into the layout:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/auto_focus"
        android:layout_below="@+id/status_message"
        android:layout_centerVertical="true"
        android:orientation="vertical"
        >
        <Switch
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/dbr_1d"
            android:id="@+id/dbr_1d"
            android:switchPadding="50dp"
            android:checked="true"
            android:layout_marginTop="180dp"/>
        <Switch
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/dbr_qr"
            android:id="@+id/dbr_qr"
            android:switchPadding="50dp"
            android:checked="true" />
        <Switch
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/dbr_data_matrix"
            android:id="@+id/dbr_data_matrix"
            android:checked="true" />
        <Switch
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/dbr_pdf417"
            android:id="@+id/dbr_pdf"
            android:switchPadding="20dp"
            android:checked="true" />
    </LinearLayout>

android barcode config

Create CameraListener (CameraSource.java) for asynchronously updating UI:

    private CameraListener mCameraListener;
    public void setCameraListener(CameraListener listener) {
        mCameraListener = listener;
    }

    public interface CameraListener {
        public void onBarcodeResults(com.dynamsoft.barcode.ReadResult result);
    }

Replace com.google.android.gms.vision.Detector with com.dynamsoft.barcode.BarcodeReader:

public void run() {
            ByteBuffer data;

            while (true) {
                synchronized (mLock) {
                    if (mActive && (mPendingFrameData == null)) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException e) {
                            Log.d(TAG, "Frame processing loop terminated.", e);
                            return;
                        }
                    }

                    if (!mActive) {
                        return;
                    }

                    data = mPendingFrameData;
                    mPendingFrameData = null;
                }

                try {
                    byte[] buff = data.array();
                    com.dynamsoft.barcode.ReadResult dbrResult = mDetector.readSingle(buff, mPreviewSize.getWidth(), mPreviewSize.getHeight(), mBarcodeFormat);
                    if (mCameraListener != null) {
                        mCameraListener.onBarcodeResults(dbrResult);
                    }

                } catch (Throwable t) {
                    Log.e(TAG, "Exception thrown from receiver.", t);
                } finally {
                    mCamera.addCallbackBuffer(data.array());
                }
            }
        }

Scan barcode images:

android barcode scan

Tap the screen to return the results:

private boolean onTap(float rawX, float rawY) {

        //TODO: use the tap position to select the barcode.
        BarcodeGraphic graphic = mGraphicOverlay.getFirstGraphic();
        com.dynamsoft.barcode.Barcode barcode = null;
        if (graphic != null) {
            barcode = graphic.getBarcode();
            if (barcode != null) {
                Intent data = new Intent();
                data.putExtra(BarcodeObject, barcode.displayValue);
                setResult(1, data);
                finish();
            }
            else {
                Log.d(TAG, "barcode data is null");
            }
        }
        else {
            Log.d(TAG,"no barcode detected");
        }
        return barcode != null;
    }

android barcode result

Dynamsoft mobile barcode reader SDK supports Android and iOS. If you want to try a preview version, please contact support@dynamsoft.com. You can also replace Google Vision APIs with ZXing and ZBar if you prefer open source mobile barcode SDKs.

Source Code

https://github.com/yushulx/android-barcode-reader-demo

The post How to Make Android Barcode Reader with Barcode SDK appeared first on Code Pool.

How to Build PHP Barcode Reader on Linux

$
0
0

No matter whether you are a web developer or an end-user, you probably have heard of the terms SaaS, Paas, and IaaS. They are three different models of cloud service. Why more and more people tend to embrace web and cloud services such as Google Cloud, Azure, and AWS? Because no application download and installation needed. A variety of software and functions can be accessed via web browsers. Assuming you want to build a web barcode reader as a service from scratch. Using Dynamsoft Barcode Reader SDK will expedite your development.

This article has been posted on CodeProject.

linux php barcode reader

SDK Download

Dynamsoft Barcode Reader 30-day Free Trial

Server-side PHP Barcode Reader

Dynamsoft Barcode Reader supports 64-bit PHP from 5.3 to 5.6. Therefore, you need to firstly check the version of PHP that installed on your system:

php -v

In addition to PHP version, you need to know whether the PHP is thread-safe or not:

 php –i | grep Thread

Copy shared libraries of Dynamsoft Barcode Reader to /usr/lib:

sudo cp <Dynamsoft Barcode Reader>/lib/* /usr/lib

Edit php.ini to add following extension path:

extension=<Dynamsoft Barcode Reader>/php/extension/<version>/<ts|nts>/php_DynamsoftBarcodeReader.so

Upload barcode images to a web server with Form:

<form id="uploadForm" method="post" action="readbarcode.php" enctype="multipart/form-data">
    <input type="file" id="upLoadFile" name="upLoadFile" class="ImgLocalPath" />
    <input type="text" readonly="readonly" id="txtUploadFileName" class="radius3" />
    <input type="button" id="btnUploadFile" value="Browse..." class="radius3 ml20"/>
    <input type="submit" id="btnReadBarcode" class="radius3 left ml20"  value="Read Barcode" />

</form>

Detect barcode data on server-side:

<?php
include 'DynamsoftBarcodeReader.php';
ini_set('display_errors',1);
error_reporting(E_ALL);
$post_max_size = ini_get("post_max_size");
$maxsize = return_bytes($post_max_size);

if($_SERVER['CONTENT_LENGTH'] > $maxsize) {
         echo "Post data size is bigger than " . $post_max_size;
         exit;
}

$file = $_FILES["upLoadFile"]["tmp_name"];
if(!empty($file)){
         readBarcode($file);                                         
}
else {
         echo "Fail to upload file.";
}

function readBarcode($path) {
    try {       
        $br = new BarcodeReader();
    } catch (exception $exp) {       
        echo 'Your barcode reader component is not registered correctly. Please refer to ReadMe.txt for details.<br/>';
        exit;
    }

    $br->initLicense('693C401F1CC972A5018B729568B0CDD8');

    try {       
        $br->decodeFile($path);
    } catch(Exception $exp) {
        echo $br->getErrorString() . '<br/>';
        exit;
    }

    $cnt = $br->getBarcodesCount();
    if($cnt > 0) {
        echo 'Total barcode(s) found:' . $cnt . '.<br/>';
        for ($i = 0; $i < $cnt; $i++) {
            $result = $br->getBarcodeResult($i);
             echo ($i+1) . ': ';
             echo "$result->BarcodeFormatString, ";
             echo "$result->BarcodeText<br/>";
        }
    }
    else {
        echo 'No barcodes found.<br/>';
    }   
}
?>

How to Deploy the Sample Code to Apache on Ubuntu

Install php5-curl, apache2 and libapache2-mod-php5:

sudo apt-get install php5-curl apache2 libapache2-mod-php5

Extract the package and copy the project to /var/www/html/:

sudo cp -r DecodeLocalFile /var/www/html

Add extension path to /etc/php5/apache2/php.ini.

Start Apache service:

sudo service apache2 start

Visit http://localhost/DecodeLocalFile/index.php in Firefox or Chrome.

Online Demo & Source Code

Visit PHP Barcode Reader to experience the online demo.

Download the source code.

 

The post How to Build PHP Barcode Reader on Linux appeared first on Code Pool.

How to Dockerize PHP Barcode Reader on Ubuntu

$
0
0

When using PHP native extensions, you have to carefully match the right PHP version. Otherwise, it may cause a compatibility issue. In addition, the web server deployment of a PHP project with customized extensions is complicated as well. A proper solution for quickly experiencing a PHP project is to use Docker. In this article, I will demonstrate how to Dockerize the PHP barcode reader project built with Dynamsoft Barcode Reader SDK for Linux.

docker php barcode reader linux

Building Docker Image for PHP Barcode Reader

A Docker image with PHP and Apache

Create a Dockerfile and choose a suitable Docker image with PHP and Apache according to PHP Docker hub page:

FROM php:5.6-apache

Build the Docker image:

sudo docker build -t php-barcode-reader .

Run the image:

sudo docker run -p 2016:80 php-barcode-reader

Open Firefox to visit localhost:2016,  you will see the Apache homepage.

A Docker image with PHP barcode reader

Since Dynamsoft Barcode Reader supports PHP 5.3, 5.4, 5.5 and 5.6 for thread-safe and non-thread-safe, you need to check the relevant information firstly.

We can access the Docker container to run Bash, referring to exec of command line reference:

sudo docker exec -it container_id bash
php –v
php –i | grep Thread

docker container bash

Download the source code of PHP barcode reader and extract the package.

Create three folders config, libs, and src, and then copy corresponding resources to these folders:

docker project structure

Add extension path to php.ini:

extension=/usr/lib/php_DynamsoftBarcodeReader.so

Edit Dockerfile:

FROM php:5.6-apache

COPY config/php.ini /usr/local/etc/php/
COPY src/ /var/www/html/
COPY libs/ /usr/lib/

Save the Dockerfile and built the image again. Now if you run the Docker image, you will see the homepage of your PHP barcode reader:

linux php barcode reader

Tag the image and push it to Docker hub:

sudo docker tag php-barcode-reader dynamsoft/php-barcode-reader 
sudo docker push dynamsoft/php-barcode-reader

Docker Image

https://hub.docker.com/r/dynamsoft/php-barcode-reader/

The post How to Dockerize PHP Barcode Reader on Ubuntu appeared first on Code Pool.

How to Build a Simple iOS Barcode Scanner App

$
0
0

Dynamsoft has released the mobile barcode SDK for iOS. In this post, let’s see how to use the SDK to quickly build an iOS barcode scanner app.

iOS barcode scanner result

iOS Barcode Scanner with Dynamsoft Barcode Reader SDK

SDK

Download

Xcode Project Configuration

  1. Open Xcode 7 and press Shift+Command+N to create a new project with the Single View Application template.
  2. Drag DynamsoftBarcodeReader.framework to your project. Check the option “Copy items if needed”:drag framework to Xcode

    The framework will be copied to your project folder. Why do you need to do this? Open project properties and select Build Settings > Search Paths:

    Xcode search path

    If you do not copy the Framework into your project, you have to change the Framework Search Path. Otherwise, it will fail to find the framework.

  3. Add dependencies. Select Build Phases > Link Binary With Libraries to add DynamsoftBarcodeReader.framework and libc++.tbd(libc++.dylib for Xcode 6):
    Xcode link binary

How-to

Create an instance of DbrManager in ViewDidLoad:

- (void)viewDidLoad {

    [super viewDidLoad];



    [[UIApplication sharedApplication] setIdleTimerDisabled: YES];



    //register notification for UIApplicationDidBecomeActiveNotification

    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(didBecomeActive:)

                                                 name:UIApplicationDidBecomeActiveNotification

                                               object:nil];



    //init DbrManager with Dynamsoft Barcode Reader mobile license

    dbrManager = [[DbrManager alloc] initWithLicense:@"<license>"];

    [dbrManager setRecognitionCallback:self :@selector(onReadImageBufferComplete:)];

    [dbrManager beginVideoSession];



    [self configInterface];

}

Initialize Dynamsoft Barcode Reader with a valid license:

-(id)initWithLicense:(NSString *)license{

    self = [super init];



    if(self)

    {

        m_videoCaptureSession = nil;

        m_barcodeReader = [[BarcodeReader alloc] initWithLicense:license];



        isPauseFramesComing = NO;

        isCurrentFrameDecodeFinished = YES;



        barcodeFormat = [Barcode UNKNOWN];

        startRecognitionDate = nil;



        m_recognitionReceiver = nil;

    }



    return self;

}

Use back-facing camera as the capture device:

-(AVCaptureDevice *)getAvailableCamera {

    NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

    AVCaptureDevice *captureDevice = nil;

    for (AVCaptureDevice *device in videoDevices) {

        if (device.position == AVCaptureDevicePositionBack) {

            captureDevice = device;

            break;

        }

    }



    if (!captureDevice)

        captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];



    return captureDevice;

}

Create a video capture session:

-(void)beginVideoSession {

    AVCaptureDevice *inputDevice = [self getAvailableCamera];



    AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput

                                          deviceInputWithDevice:inputDevice

                                          error:nil];



    AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];



    captureOutput.alwaysDiscardsLateVideoFrames = YES;



    dispatch_queue_t queue;

    queue = dispatch_queue_create("dbrCameraQueue", NULL);

    [captureOutput setSampleBufferDelegate:self queue:queue];



    // Enable continuous autofocus

    if ([inputDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {

        NSError *error = nil;

        if ([inputDevice lockForConfiguration:&error]) {

            inputDevice.focusMode = AVCaptureFocusModeContinuousAutoFocus;

            [inputDevice unlockForConfiguration];

        }

    }



    // Enable AutoFocusRangeRestriction

     if([inputDevice respondsToSelector:@selector(isAutoFocusRangeRestrictionSupported)] &&

        inputDevice.autoFocusRangeRestrictionSupported) {

         if([inputDevice lockForConfiguration:nil]) {

             inputDevice.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;

             [inputDevice unlockForConfiguration];

         }

     }



    [captureOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];



    if(captureInput == nil || captureOutput == nil)

    {

        return;

    }



    m_videoCaptureSession = [[AVCaptureSession alloc] init];

    [m_videoCaptureSession addInput:captureInput];

    [m_videoCaptureSession addOutput:captureOutput];



    if ([m_videoCaptureSession canSetSessionPreset:AVCaptureSessionPreset1920x1080])

    {

        [m_videoCaptureSession setSessionPreset :AVCaptureSessionPreset1920x1080];

        cameraResolution.width = 1920;

        cameraResolution.height = 1080;

    }

    else if ([m_videoCaptureSession canSetSessionPreset:AVCaptureSessionPreset1280x720])

    {

        [m_videoCaptureSession setSessionPreset :AVCaptureSessionPreset1280x720];

        cameraResolution.width = 1280;

        cameraResolution.height = 720;

    }

    else if([m_videoCaptureSession canSetSessionPreset:AVCaptureSessionPreset640x480])

    {

        [m_videoCaptureSession setSessionPreset :AVCaptureSessionPreset640x480];

        cameraResolution.width = 640;

        cameraResolution.height = 480;

    }



    [m_videoCaptureSession startRunning];

}

Display video on preview layer:

AVCaptureSession* captureSession = [dbrManager getVideoSession];

    if(captureSession == nil)

        return;



    previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];

    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

        previewLayer.frame = mainScreenLandscapeBoundary;

    cameraPreview = [[UIView alloc] init];

    [cameraPreview.layer addSublayer:previewLayer];

    [self.view insertSubview:cameraPreview atIndex:0];

According to the environment brightness, toggle flash:

- (void) turnFlashOn: (BOOL) on {

    // validate whether flashlight is available

    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");

    if (captureDeviceClass != nil) {

        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

        if (device != nil && [device hasTorch] && [device hasFlash]){

            [device lockForConfiguration:nil];



            if (on == YES) {

                [device setTorchMode:AVCaptureTorchModeOn];

                [device setFlashMode:AVCaptureFlashModeOn];

                [flashButton setImage:[UIImage imageNamed:@"flash_on"] forState:UIControlStateNormal];

                [flashButton setTitle:NSLocalizedString(@"flash-on", @"flash on string") forState:UIControlStateNormal];



            } else {

                [device setTorchMode:AVCaptureTorchModeOff];

                [device setFlashMode:AVCaptureFlashModeOff];

                [flashButton setImage:[UIImage imageNamed:@"flash_off"] forState:UIControlStateNormal];

                [flashButton setTitle:NSLocalizedString(@"flash-off", @"flash off string") forState:UIControlStateNormal];

            }



            [device unlockForConfiguration];

        }

    }

}

Keep camera automatically focused:

if ([inputDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {

        NSError *error = nil;

        if ([inputDevice lockForConfiguration:&error]) {

            inputDevice.focusMode = AVCaptureFocusModeContinuousAutoFocus;

            [inputDevice unlockForConfiguration];

        }

    }

     if([inputDevice respondsToSelector:@selector(isAutoFocusRangeRestrictionSupported)] &&

        inputDevice.autoFocusRangeRestrictionSupported) {

         if([inputDevice lockForConfiguration:nil]) {

             inputDevice.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;

             [inputDevice unlockForConfiguration];

         }

}

Receive captured video with AVCaptureVideoDataOutputSampleBufferDelegate and read barcode in captureOutput:

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection;

{

    @autoreleasepool {

        if(isPauseFramesComing == YES || isCurrentFrameDecodeFinished == NO) return;



        isCurrentFrameDecodeFinished = NO;



        void *imageData = NULL;

        uint8_t *copyToAddress;



        CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);



        OSType pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer);



        if (!(pixelFormat == '420v' || pixelFormat == '420f'))

        {

            isCurrentFrameDecodeFinished = YES;

            return;

        }



        CVPixelBufferLockBaseAddress(imageBuffer, 0);

        int numPlanes = (int)CVPixelBufferGetPlaneCount(imageBuffer);

        int bufferSize = (int)CVPixelBufferGetDataSize(imageBuffer);

        int imgWidth = (int)CVPixelBufferGetWidthOfPlane(imageBuffer, 0);

        int imgHeight = (int)CVPixelBufferGetHeightOfPlane(imageBuffer, 0);



        if(numPlanes < 1)

        {

            isCurrentFrameDecodeFinished = YES;

            return;

        }



        uint8_t *baseAddress = (uint8_t *) CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);

        size_t bytesToCopy = CVPixelBufferGetHeightOfPlane(imageBuffer, 0) * CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0);

        imageData = malloc(bytesToCopy);

        copyToAddress = (uint8_t *) imageData;

        memcpy(copyToAddress, baseAddress, bytesToCopy);



        CVPixelBufferUnlockBaseAddress(imageBuffer, 0);



        NSData *buffer = [NSData dataWithBytesNoCopy:imageData length:bufferSize freeWhenDone:YES];



        startRecognitionDate = [NSDate date];



        // read frame using Dynamsoft Barcode Reader in async manner

        [m_barcodeReader readSingleAsync:buffer width:imgWidth height:imgHeight barcodeFormat: barcodeFormat sender:m_recognitionReceiver onComplete:m_recognitionCallback];

    }

}

Video of iOS Barcode Scanner

App Installation

You can download the app from iTunes App Store.

Source Code

https://github.com/dynamsoft-dbr/iOS-barcode-scanner

The post How to Build a Simple iOS Barcode Scanner App appeared first on Code Pool.

Viewing all 145 articles
Browse latest View live