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
-
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("LICENSE-KEY")
-
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:
-
Get the source code of barcode4nodejs.
git clone https://github.com/Dynamsoft/nodejs-barcode
Download Dynamsoft C++ Barcode SDK. Copy header files to the
src
folder and copy shared libraries toplatforms
folder. Dynamsoft Barcode Reader SDK supportsWindows
,Linux (AMD64 and ARM64)
, andmacOS
. Theoretically, the Node.js addon can work on all desktop platforms.Edit
src/dbr.cc
andindex.js
to add custom functions.-
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("LICENSE-KEY")
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);
}
}
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.
Source Code
https://github.com/yushulx/nodejs-barcode/tree/main/examples/opencv