delphi启动ie调用本地html传参数_如何在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<Value>&amp; args) {
    if (!createDBR()) {return;}
    Isolate* isolate = Isolate::GetCurrent();
    Local<Context> context = 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
    Local<Function> cb = Local<Function>::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(), &amp;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中的运行效果:

a659f6bbe8865c24c9d1ba37a897923d.png

视频

知乎视频​www.zhihu.com

源码

https://github.com/yushulx/nodejs-barcode-reader

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值