在这篇文章中,我们将展示一个非常简单的方法构建一个自定义的 Node 模块,该模块封装了Dynamsoft Barcode Reader SDK ,支持 Windows、Linux 和 OS X,同时我们将演示如何集成这块模块实现一个在线的条形码读取应用。 越来越多的 Web 开发者选择 Node 来构建网站,因为使用 JavaScript 来开发复杂的服务器端 Web 应用越来越便利。为了扩展在不同平台下的 Node 的功能,Node 允许开发者使用 C/C++ 来创建扩展。 演示项目代码下载:
介绍
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #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 传递过来的参数
1 2 3 4 5 6 7 8 | 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]); |
解析条形码图像:
1 2 3 4 5 6 7 8 9 | 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); |
将条形码转成字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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 对象:
1 2 3 4 5 6 7 8 9 10 11 12 | 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:
1 | npm install -g node-gyp |
创建 binding.gyp 用于多平台编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | { "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 安装目录替换成你机器上的实际目录。
配置构建环境:
1 | node-gyp configure |
可以在 Mac 上你会碰到下面的错误:
1 | error: xcode- select : error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance |
解决办法是:
1 | sudo xcode- select --switch /Applications/Xcode .app /Contents/Developer |
构建项目:
1 | node-gyp build |
你已经成功的构建了 Node 的条形码解析模块,现在可以创建一个简单的条形码读取应用。
安装 Express 和 Formidable:
1 2 | npm install express npm install formidable |
使用 Express 创建一个简单应用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 从表单中提取图像数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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 () { }); }); }); } }); }); }); |
导入条形码模块用来解析图像文件:
1 | decodeBarcode(res, license, tmpFileName, barcodeType); |
运行应用:
1 | node server.js |
访问 http://localhost:2016/index.htm:
如果你要在 Windows、Linux 和 Mac 下构建条形码读取应用,可以直接下载示例程序 Dynamsoft Barcode Reader, 也可以直接咨询 support@dynamsoft.com。