Node.js Barcode and QR Code Reader for Desktop and Web

There are many open source JavaScript barcode and QR code reader libraries, but few of them are suitable for enterprise use. The reason is that they do not have a road map for long-term algorithm updates and maintenance. In addition, the performance of pure JavaScript is not good enough. WebAssembly is a better choice comparing to pure JavaScript if you pursue performance. Nevertheless, for server-side programming using Node.js, it is still not the end. What is under the hood of Node.js? It is C/C++. It is no doubt that a Node.js addon with C++ has the best performance. In this article, you will see how to use Node.js barcode and QR code addon based on Dynamsoft C++ Barcode SDK to build desktop and web applications using JavaScript.

Installation

  • barcode4nodejs

    The barcode4nodejs package is a Node.js addon built based on Dynamsoft Barcode Reader. We use it to scan barcode and QR code.

      npm install barcode4nodejs
    

    Click here to get a valid license key for SDK activation.

      const dbr = require('barcode4nodejs');
      dbr.initLicense("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==")
    
  • opencv4nodejs

    The opencv4nodejs package is a Node.js addon for OpenCV. We use it to open camera and read video stream.

      npm install opencv4nodejs
    

Customizing Node.js API for Reading Barcode and QR Code

Currently, the barcode4nodejs package only supports a part of C++ API of Dynamsoft Barcode Reader. If the features cannot satisfy your needs, you can use the following steps to customize the JavaScript API:

  1. Get the source code of barcode4nodejs.

     git clone https://github.com/Dynamsoft/nodejs-barcode
    
  2. Download Dynamsoft C++ Barcode SDK. Copy header files to the src folder and copy shared libraries to platforms folder. Dynamsoft Barcode Reader SDK supports Windows, Linux (AMD64 and ARM64), and macOS. Theoretically, the Node.js addon can work on all desktop platforms.

  3. Edit src/dbr.cc and index.js to add custom functions.
  4. Build the Node.js extension:

     node-gyp configure
     node-gyp build
    

Building Node.js Barcode and QR Code Reader for Desktop and Web in 5 Minutes

Node.js Desktop Application

Create a desktop.js file. According to the basic tutorial of opencv4nodejs, we can use an infinite loop to capture webcam frames and show them in a desktop window:

const cv = require('opencv4nodejs');
const vCap = new cv.VideoCapture(0);
const delay = 10;
while (true) {
  let frame = vCap.read();
  if (frame.empty) {
    vCap.reset();
    frame = vCap.read();
  }
 
  cv.imshow('OpenCV Node.js', frame);
  const key = cv.waitKey(delay); // Press ESC to quit
  if (key == 27) {break;}
}

However, if we invoke the asynchronous function to decode QR code and barcode continuously in the loop, the result callback function will never return. The workaround is to keep calling setTimeout() function as barcode and QR code are detected:

const dbr = require('barcode4nodejs');
const cv = require('opencv4nodejs');
dbr.initLicense("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==")
barcodeTypes = dbr.barcodeTypes
const vCap = new cv.VideoCapture(0);
const drawParams = { color: new cv.Vec(0, 255, 0), thickness: 2 }
const fontFace = cv.FONT_HERSHEY_SIMPLEX;
const fontScale = 0.5;
const textColor = new cv.Vec(255, 0, 0);
const thickness = 2;

results = null;

function getframe() {
    let img = vCap.read();
    dbr.decodeBufferAsync(img.getData(), img.cols, img.rows, img.step, barcodeTypes, function (err, msg) {
        results = msg
    }, "", 1);
    cv.imshow('Webcam', img);
    const key = cv.waitKey(10); // Press ESC to quit
    if (key != 27) {
        setTimeout(getframe, 30);
    }
}

getframe()

In the following code, we use OpenCV API to draw an overlay, which show the text and bounding boxes of the detected barcode and QR code. Due to the similarity of the adjacent frames, we do not need to draw a frame and its corresponding results synchronously. A little bit of delay is acceptable.

if (results != null) {
    for (index in results) {
        let result = results[index];

        let upperLeft = new cv.Point(result.x1, result.y1);
        let bottomLeft = new cv.Point(result.x2, result.y2);
        let upperRight = new cv.Point(result.x3, result.y3);
        let bottomRight = new cv.Point(result.x4, result.y4);

        img.drawLine(upperLeft, bottomLeft, drawParams);
        img.drawLine(bottomLeft, upperRight, drawParams);
        img.drawLine(upperRight, bottomRight, drawParams);
        img.drawLine(bottomRight, upperLeft, drawParams);

        img.putText(result.value, new cv.Point(result.x1, result.y1 + 10), fontFace, fontScale, textColor, thickness);
    }
}

OpenCV Node.js barcode and QR code reader with webcam

Node.js Web Application

Create a web.js file, in which we add the following code to launch a web server:

var fs=require("fs");
var html = fs.readFileSync("index.htm", "utf8");

var server = http.createServer(function (req, res) {  
    if (req.url.startsWith("/image")) {
        res.writeHead(200, { 'Content-Type': 'image/jpeg' });
        res.write(img);
        res.end();
    }
    else {
        res.writeHead(200, { 'Content-Type': 'text/html' });     
        res.write(html);
        res.end();
    }
});

server.listen(2020);

console.log('Node.js web server is running at port 2020...')

Copy the code used in desktop.js to web.js. Instead of using cv.imshow() to show the webcam image in a desktop window, we use res.write() to send the image data to the web client.

The next step is to create an HTML page to display the image data:

<!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>Webcam</title>
</head>

<body>
    <img id="image" width="960" />

    <script type="text/javascript">
        var image = document.getElementById('image');
        function refresh() {
            image.src = "/image?" + new Date().getTime();
            image.onload= function(){
                setTimeout(refresh, 30);
            }
        }
        
        refresh();
    </script>

</body>
</html>

There is no advanced HTML5 API used but an image element. Therefore, the web application is 100% compatible with any web browser.

Now we can run the server-side barcode and QR code scanning app using Node.js.

node web.js

Here is a screenshot from Microsoft Internet Explorer.

OpenCV Node.js Barcode and QR code for web

Source Code

https://github.com/yushulx/nodejs-barcode-reader