如何在IE中打开USB摄像头扫描条形码
IE不支持WebRTC,所以没有办法通过JS接口在浏览器中直接访问USB摄像头。解决的方法就是通过本地启动一个服务去获取摄像头数据,然后发送到IE的web页面上,通过img元素不断刷新来显示,这个在上一篇文章中已经说过。这篇文章是基于上一篇里Node.js的代码,增加条形码扫描功能。
基于C/C 的Node.js条形码模块编译
C/C 的封装代码在
https://github.com/Dynamsoft/nodejs-barcode。
用于解码的接口是decodeBufferAsync()。以下是相关的C/C 代码:
void DecodeBufferAsync(const FunctionCallbackInfo& args) { if (!createDBR()) {return;} Isolate* isolate = Isolate::GetCurrent(); Localcontext = isolate->GetCurrentContext(); // get arguments unsigned char* buffer = (unsigned char*) node::Buffer::Data(args[0]); // file stream int width = args[1]->Int32Value(context).ToChecked(); // image width int height = args[2]->Int32Value(context).ToChecked(); // image height int stride = args[3]->Int32Value(context).ToChecked(); // stride int iFormat = args[4]->Int32Value(context).ToChecked(); // barcode types Localcb = Local::Cast(args[5]); // javascript callback function String::Utf8Value templateName(isolate, args[6]); // template name char *pTemplateName = *templateName; // initialize BarcodeWorker BarcodeWorker *worker = new BarcodeWorker; worker->request.data = worker; worker->callback.Reset(isolate, cb); worker->iFormat = iFormat; worker->pResults = NULL; worker->buffer = buffer; worker->width = width; worker->height = height; worker->bufferType = RGB_BUFFER; worker->stride = stride; if (hasTemplate(pTemplateName)) { // Load the template. char szErrorMsg[256]; DBR_InitRuntimeSettingsWithString(hBarcode, pTemplateName, CM_OVERWRITE, szErrorMsg, 256); worker->useTemplate = true; } else { worker->useTemplate = false; } uv_queue_work(uv_default_loop(), &worker->request, (uv_work_cb)DetectionWorking, (uv_after_work_cb)DetectionDone); }
第一个参数是图像数据的指针,所以在JS层要通过getData() 获取buffer:
const vCap = new cv.VideoCapture(0); var img = vCap.read(); dbr.decodeBufferAsync(img.getData(), img.cols, img.rows, img.step, barcodeTypes, function (err, msg) { results = msg }, "");
编译的时候针对不同的平台有一些差别。Linux上通过rpath设置相对路径;Windows上把DLL拷贝到输出目录;mac上把dylib文件拷贝到/usr/local/lib目录下。
binding.gyp
{ "targets": [ { 'target_name': "dbr", 'sources': ["src/dbr.cc"], "cflags" : [ "-std=c 11" ], 'ldflags': [ "-Wl,-rpath,'$$ORIGIN'" ], 'include_dirs': [ "./" ], 'conditions': [ ['OS=="linux"', { 'defines': [ 'LINUX_DBR', ], 'libraries': [ "-lDynamsoftBarcodeReader", "-L../platforms/linux" ], 'copies': [ { 'destination': 'build/Release/', 'files': [ './platforms/linux/libDynamsoftBarcodeReader.so' ] } ] }], ['OS=="win"', { 'defines': [ 'WINDOWS_DBR', ], 'libraries': [ "-l../platforms/windows/DBRx64.lib" ], 'copies': [ { 'destination': 'build/Release/', 'files': [ './platforms/windows/**.*' ] } ] }], ['OS=="mac"', { 'defines': [ 'MAC_DBR', ], 'libraries': [ "-lDynamsoftBarcodeReader", "-L../platforms/macos" ], 'copies': [ { 'destination': '/usr/local/lib/', 'files': [ './platforms/macos/libDynamsoftBarcodeReader.dylib' ] } ] }] ] } ] }
包已经发布到npm上。安装前先装好每个平台需要的C/C 编译环境。然后运行下面的命令下载,编译,安装:
npm install -g node-gyp npm install barcode4nodejs
通过Node.js实现在IE浏览器中扫描条形码
在服务端调用JS条形码接口,当返回结果的时候画到当前图像上,然后通过jpg编码发送给web客户端:
function capture() { var frame = wCap.read() if (frame.empty) { wCap.reset(); frame = wCap.read(); } dbr.decodeBufferAsync(frame.getData(), frame.cols, frame.rows, frame.step, barcodeTypes, function (err, msg) { // console.log(results) results = msg }, "", 1); 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) frame.drawLine( upperLeft, bottomLeft, drawParams ) frame.drawLine( bottomLeft, upperRight, drawParams ) frame.drawLine( upperRight, bottomRight, drawParams ) frame.drawLine( bottomRight, upperLeft, drawParams ) frame.putText(result.value, new cv.Point(result.x1, result.y1 10), fontFace, fontScale, textColor, thickness); } } img = cv.imencode('.jpg', frame); setTimeout(capture, 30); } capture();
var server = http.createServer(function (req, res) { //create web server 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(); } });
结果是异步返回的,因为连续帧之间的差别很小,所以用于显示问题不大。
以下是IE中的运行效果:
视频
重播
播放
00:00 / 00:00 正在直播00:00
进入全屏
50
点击按住可拖动视频
源码
https://github.com/yushulx/nodejs-barcode-reader
赞 (0)