如何在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)

相关推荐

  • 如何在12123中打开违章消息的短信提醒功能

    有的小伙伴在使用交管12123软件时,为了可以快速知道自己是否违章了, 因此想要打开违章消息的短信提醒功能,但是却不知道如何打开,那么小编就来为大家介绍一下吧.具体如下:1. 第一步,点击并打开交管1 ...

  • 如何在三星A6s中打开USB调试?

    大家有所不知的是,三星A6s的USB调试选项默认是被隐藏的,需要进行操作才能打开,接下来就让我来教大家如何操作吧!具体如下:1. 首先在屏幕主页点击进入设置图标,在进入设置界面后,打开"关于 ...

  • 如何在qq中打开云端文件

    有的小伙伴在使用QQ软件时,会将一些文件放入云端文件中,那么如何打开云端文件呢?小编就来为大家介绍一下吧.具体如下:1. 第一步,点击并打开QQ软件,接着点击左上角的头像,如何点击我的文件选项.2. ...

  • 如何在QQ中打开群发助手

    有的小伙伴在使用QQ软件时,需要将一些消息进行群发,但是却不知道如何打开群发助手,那么小编就来为大家介绍一下吧.具体如下:1. 第一步,点击并打开QQ软件,接着点击左上角的个人头像.2. 第二步,在下 ...

  • 如何在QQ中打开小游戏

    有的小伙伴看到很多好友都在QQ中玩小游戏,所以自己也想要玩小游戏,但是却不知道如何打开,那么小编就来为大家介绍一下吧.具体如下:1. 第一步,点击并打开QQ软件.2. 第二步,来到QQ软件消息后,点击 ...

  • 如何在华为荣耀畅玩6X中打开USB调试模式?

    手机和电脑相互连接时需要用到手机的USB调试模式,但是很多人不知道该如何在手机中打开USB调试模式,接下来小编以华为荣耀畅玩6X为例给大家介绍一下具体步骤.具体如下:1.  首先第一步打开手机,找到并 ...

  • 如何在Google中打开pinterest网页?

    Pinterest是世界上最大的图片社交分享网站,很多人不知道如何在如何在Google中打开pinterest网页,接下来小编就给大家介绍一下具体的操作步骤.具体如下:1. 首先第一步打开电脑中的浏览 ...

  • 如何在QQ中打开代替悄悄话的坦白说

    有的小伙伴在使用QQ软件时,想要使用悄悄话功能,但是却发现没有悄悄话了,其实我们可以使用QQ坦白说功能,来代替悄悄话功能,如何打开坦白说呢?小编就来为大家介绍一下吧.具体如下:1. 第一步,自从QQ7 ...

  • 如何在QQ中打开登录保护功能并绑定密保手机

    手机版QQ软件被很多人使用,用来聊天,或者逛空间等,有的用户为了自己的QQ安全,因此想要打开登录保护功能,并且想要绑定密保手机,但是却不知道如何打开和绑定,那么小编就来为大家介绍一下吧.具体如下:1. ...

  • 如何在QQ中打开群课堂的循环播放背景音乐功能

    手机版QQ软件被很多人使用,用来聊天或者逛空间等, 有的老师还会在该软件上上课,为了缓解上课的氛围,因此想要打开群课堂的循环播放背景音乐功能,但是却不知道如何打开,那么小编就来为大家介绍一下吧.具体如 ...