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


Posted in Javascript onFebruary 14, 2016

在这篇文章中,我们将展示一个非常简单的方法构建一个自定义的 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 条形码识别程序构建思路详解

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

Javascript 相关文章推荐
Js的MessageBox
Dec 03 Javascript
javascript网页关闭时提醒效果脚本
Oct 22 Javascript
悄悄用脚本检查你访问过哪些网站的代码
Dec 04 Javascript
在js文件中如何获取basePath处理js路径问题
Jul 10 Javascript
jquery控制页面部分刷新的方法
Jun 24 Javascript
jQuery日历插件datepicker用法详解
Mar 03 Javascript
JQuery解析XML的方法小结
Apr 02 Javascript
简单实现js间歇或无缝滚动效果
Jun 29 Javascript
Laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的解决方法
Aug 18 Javascript
Web技术实现移动监测的介绍
Sep 18 Javascript
js实现继承的方法及优缺点总结
May 08 Javascript
8个有意思的JavaScript面试题
Jul 30 Javascript
jQuery插件支持同一页面被多次调用
Feb 14 #Javascript
JavaScript中通过提示框跳转页面的方法
Feb 14 #Javascript
JavaScript中关联原型链属性特性
Feb 13 #Javascript
JavaScript操作class和style样式代码详解
Feb 13 #Javascript
javascript实现查找数组中最大值方法汇总
Feb 13 #Javascript
JavaScript常用数组算法小结
Feb 13 #Javascript
Javascript 字符串模板的简单实现
Feb 13 #Javascript
You might like
输出控制类
2006/10/09 PHP
php 修改zen-cart下单和付款流程以防止漏单
2010/03/08 PHP
MySQL的FIND_IN_SET函数使用方法分享
2012/03/27 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
利用jquery的获取JS文件中的字符串内容
2012/02/14 Javascript
Web跨浏览器进程通信(Web跨域)
2013/04/17 Javascript
jquery自定义滚动条插件示例分享
2014/02/21 Javascript
基于jquery实现人物头像跟随鼠标转动
2015/08/23 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
JavaScript中获取时间的函数集
2016/08/16 Javascript
AngularJS全局scope与Isolate scope通信用法示例
2016/11/22 Javascript
BootStrap Fileinput的使用教程
2016/12/30 Javascript
JavaScript队列函数和异步执行详解
2017/06/19 Javascript
element ui 对话框el-dialog关闭事件详解
2018/02/26 Javascript
JavaScript中变量、指针和引用功能与操作示例
2018/08/04 Javascript
JS实现的贪吃蛇游戏完整实例
2019/01/18 Javascript
微信小程序中的video视频实现 自定义播放按钮、封面图、视频封面上文案
2020/01/02 Javascript
js 实现碰撞检测的示例
2020/10/28 Javascript
原生js+canvas实现验证码
2020/11/29 Javascript
Python中单、双下划线的区别总结
2017/12/01 Python
numpy的文件存储.npy .npz 文件详解
2018/07/09 Python
详解Numpy中的数组拼接、合并操作(concatenate, append, stack, hstack, vstack, r_, c_等)
2019/05/27 Python
简单了解python 邮件模块的使用方法
2019/07/24 Python
New Balance加拿大官方网站:运动鞋和健身服装
2018/11/19 全球购物
韩国保养品、日本药妆购物网:小三美日
2018/12/30 全球购物
俄罗斯最大的在线珠宝大卖场:Nebo
2019/12/08 全球购物
俄罗斯宠物用品网上商店:ZooMag
2019/12/12 全球购物
成功的酒店创业计划书
2013/12/27 职场文书
可口可乐广告词
2014/03/20 职场文书
反邪教警示教育方案
2014/05/13 职场文书
影子教师研修方案
2014/06/14 职场文书
自强自立美德少年事迹材料
2014/08/16 职场文书
小学生美德少年事迹材料
2014/08/24 职场文书
安全生产隐患排查制度
2015/08/05 职场文书
《月球之谜》教学反思
2016/02/20 职场文书
公务员的复习计划书,请收下!
2019/07/15 职场文书