Node.js 条形码识别程序构建思路详解

 更新时间:2016年2月18日 10:05  点击:2300

在这篇文章中,我们将展示一个非常简单的方法构建一个自定义的 Node 模块,该模块封装了Dynamsoft Barcode Reader SDK ,支持 Windows、Linux 和 OS X,同时我们将演示如何集成这块模块实现一个在线的条形码读取应用。

越来越多的 Web 开发者选择 Node 来构建网站,因为使用 JavaScript 来开发复杂的服务器端 Web 应用越来越便利。为了扩展在不同平台下的 Node 的功能,Node 允许开发者使用 C/C++ 来创建扩展。

介绍

Dynamsoft Barcode Reader 为 Windows、Linux 和 OS X 提供条形码解析的 C/C++ 共享库。其最大的优势是适用于多种高级编程语言,包括 JavaScript, Python, Java, Ruby, PHP 等,只要可以封装 C/C++ API 作为一个扩展就可以使用。不管是什么编程语言,最终只需要简单几行代码即可完成条形码的解析。

支持 1D/2D 条形码类型

Code 39, Code 93, Code 128, Codabar, Interleaved 2 of 5, EAN-8, EAN-13, UPC-A, UPC-E,Industrial 2 of 5
QRCode
DataMatrix
PDF417

支持图像类型

BMP, JPEG, PNG, GIF, TIFF, PDF

运行环境

Windows, Linux & Mac
Node v5.5.0

Node.js 条形码扩展

Node.js 扩展使用 C/C++ 编写的动态链接的共享对象。如果你没有接触过这方面的技术,可以阅读 官方教程 。

创建扩展

创建名为 dbr.cc 的文件,并添加方法 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)

解析来自 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]);

解析条形码图像:

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

将条形码转成字符串:

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

将结果转成 v8 对象:

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

构建扩展

要求:

Windows: 需要安装 DBR for Windows, visual Studio, and Python v2.7.

Linux: 安装 DBR for Linux.

Mac: 安装 DBR for Mac 和 Xcode.

安装 node-gyp:

npm install -g node-gyp

创建 binding.gyp 用于多平台编译:

{
"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"
]
}]
]
}
]
}

将 DRB 安装目录替换成你机器上的实际目录。

配置构建环境:

node-gyp configure

可以在 Mac 上你会碰到下面的错误:

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

解决办法是:

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

构建项目:

node-gyp build

在线条形码解析

你已经成功的构建了 Node 的条形码解析模块,现在可以创建一个简单的条形码读取应用。

安装 Express 和 Formidable:

npm install express
npm install formidable

使用 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);
});
});

使用 Formidable 从表单中提取图像数据:

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() {

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

导入条形码模块用来解析图像文件:

decodeBarcode(res, license, tmpFileName, barcodeType);

运行应用:

node server.js

访问 http://localhost:2016/index.htm:


以上所述是小编给大家介绍的Node.js 条形码识别程序构建思路详解,希望对大家有所帮助。

[!--infotagslink--]

相关文章

  • node.js如何操作MySQL数据库

    这篇文章主要介绍了node.js如何操作MySQL数据库,帮助大家更好的进行web开发,感兴趣的朋友可以了解下...2020-10-29
  • node.JS md5加密中文与php结果不一致怎么办

    这次文章要给大家介绍的是node.JS md5加密中文与php结果不一致怎么办,不知道具体解决办法的下面跟小编一起来看看。 因项目需要,需要Node.js与PHP做接口调用,发现nod...2017-07-06
  • 浅谈node.js中async异步编程

    1.什么是异步编程? 异步编程是指由于异步I/O等因素,无法同步获得执行结果时, 在回调函数中进行下一步操作的代码编写风格,常见的如setTimeout函数、ajax请求等等。示例: for (var i = 1; i <= 3; i++) {setTimeout(functi...2015-10-23
  • node.js+express留言板功能实现示例

    本文介绍基于nodejs+express+art-template的留言板功能。包含列表界面、添加界面和发送留言功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-21
  • NODE.JS加密模块CRYPTO常用方法介绍

    使用require('crypto')调用加密模块。加密模块需要底层系统提供OpenSSL的支持。它提供了一种安全凭证的封装方式,可以用于HTTPS安全网络以及普通HTTP连接。该模块还提供了一套针对OpenSSL的hash(哈希),hmac(密钥哈希),cipher...2014-06-07
  • 安装使用Mongoose配合Node.js操作MongoDB的基础教程

    这篇文章主要介绍了安装使用Mongoose来让Node.js操作MongoDB的基础教程,前端js+后端node+js操作MongoDB正是所谓最流行的一种JavaScript全栈开发方案,需要的朋友可以参考下...2016-03-03
  • 比较node.js和Deno

    这篇文章主要介绍了node.js和Deno的区别,对deno感兴趣的同学,可以参考下...2021-04-27
  • node.js从数据库获取数据

    这篇文章主要为大家详细介绍了node.js从数据库获取数据的具体代码,nodejs可以获取具体某张数据表信息,感兴趣的朋友可以参考一下...2016-05-09
  • 利用Node.js获取项目根目录的小技巧

    这篇文章介绍的是一个小技巧来获取node.js项目根目录,这个技巧非常实用。有需要的朋友们可以参考借鉴,下面来一起看看吧。...2016-10-02
  • node.js [superAgent] 请求使用示例

    post请求:复制代码 代码如下: request.post('/api/pet') .end(function(resp,err){ if (resp.body.status===200) { alert('yay got ' + JSON.stringify(res.body)); } else { return nex...2015-03-15
  • Node.js之http模块的用法

    这篇文章主要介绍了Node.js之http模块的用法,对Node.js感兴趣的同学,可以参考下...2021-04-25
  • 三种Node.js写文件的方式

    这篇文章主要为大家详细介绍了三种Node.js写文件的方式,感兴趣的小伙伴们可以参考一下...2016-03-10
  • 教你如何在Node.js中使用jQuery

    本文给大家分享的是如何在Node.js中使用jQuery的方法,包含步骤以及出错的处理,非常的详细,有需要的小伙伴可以参考下...2016-09-01
  • node.js 全局变量的具体使用

    这篇文章主要介绍了node.js 全局变量的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-15
  • node.js爬虫爬取拉勾网职位信息

    本篇文章主要介绍了node.js爬虫爬取拉勾网职位信息的方法。具有很好的参考价值。下面跟着小编一起来看下吧 用node.js写了一个简单的小爬虫,用来爬取拉勾网上的招...2017-07-06
  • node.js爬虫框架node-crawler初体验

    这篇文章主要介绍了node.js爬虫框架node-crawler的相关资料,帮助大家利用node.js进行爬虫,感兴趣的朋友可以了解下...2020-10-29
  • Webpack 实现 Node.js 代码热替换

    这两天为了这个问题, Gitter 上问, Twitter 上问, GitHub 上问, 两天没反应 原来写博客的 jlongster 不理我, 我也不知道 Webpack 作者的联系方式 最后在 Gitter 上发的消息他似乎看到了, 就粗略地解释了一遍, 醍醐灌...2015-10-23
  • node.js利用express自动搭建项目的全过程

    这篇文章主要给大家介绍了关于node.js利用express自动搭建项目的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-09
  • 通过node-mysql搭建Windows+Node.js+MySQL环境的教程

    这篇文章主要介绍了通过node-mysql搭建Windows+Node.js+MySQL环境的教程,node-mysql是JavaScript编写的一个Node的MySQL驱动,需要的朋友可以参考下...2016-03-03
  • 跟我学Node.js(四)---Node.js的模块载入方式与机制

    其它的如通过NPM安装的第三方模块(third-party modules)或本地模块(local modules),每个模块都会暴露一个公开的API。以便开发者可以导入。如复制代码 代码如下:var mod = require('module_name')此句执行后,Node内部会载入...2014-06-07