纯web端实现二维码识别

前言

最近公司的业务场景中有个生成二维码和识别二维码的需求。生成二维码以前有作过,选用的 qrcode.js这个前端库,操做比较简单。这里再也不赘述。 刚开始看到二维识别这个需求以为很简单,觉得有相应的前端库直接用就好了。但当真正开始写功能时,发现二维识别会涉及到不少其余的功能。废话再也不多说,仍是来看看如何实现的吧。前端

实现流程

  • 调用摄像头web

    经过浏览器调用摄像头在h5中已经有个属性能够兼容大部分平台了。 navigator.getUserMedia = navigator.mediaDevices.getUserMedia || navigator.mediaDevices.webkitGetUserMedia || navigator.mediaDevices..mozGetUserMedia; 咱们来看下mdn中的介绍: MediaDevices.getUserMedia()会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流能够包含一个视频轨道(来自硬件或者虚拟视频源,好比相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(一样来自硬件或虚拟音频源,好比麦克风、A/D转换器等等),也多是其它轨道类型。它返回一个 Promise 对象,成功后会resolve回调一个 MediaStream 对象。若用户拒绝了使用权限,或者须要的媒体源不可用,promise会reject回调一个 PermissionDeniedError 或者 NotFoundError 。查看详情 也就是说这个属性的返回值中咱们能够获取摄像头正在拍摄的视频流动。canvas

  • 获取视频流并显示在video 视频流经过getUserMedia已经能够获取到接下须要把他放到video中:promise

let option = {
                    width: 1280,
                    height: 720
                }
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                            navigator.mediaDevices.getUserMedia({
                                video: option
                            }).then(function(stream) {
                              //将视频流实时播放在video
                                self.$refs.video.srcObject = stream
                                self.$refs.video.style.display = 'block'
                                //截取video内容
                                setTimeout(() => {
                                    self.screenShot()
                                }, 2000);
                            }).catch(function(err) {
                                alert(err);
                            });
                } else if (navigator.getUserMedia) {
                    navigator.getUserMedia({
                        video: true
                    }).then(function(stream) {
                        self.$refs.video.srcObject = stream
                        self.$refs.video.style.display = 'block'
                        setTimeout(() => {
                            self.screenShot()
                        }, 2000);
                    }).catch(function(err) {
                        alert(err);
                    });
                }
复制代码
  • canvas实现截图

当录像正常显示时,咱们能够实时的进行截图。b浏览器

let $canvas = $('canvas');
                let $video = $('video');
                $canvas.attr({
                    width: $video.width(),
                    height: $video.height(),
                })
                let ctx = $canvas[0].getContext('2d');
                ctx.drawImage($video[0], 0, 0, $video.width(), $video.height());
                let base64 = $canvas[0].toDataURL('images/png');
                //截图成功对图片进行识别
                this.decodeQrcode(base64)
复制代码
  • 图片识别(判断是不是二维码)

使用二维码识别库reqrcode.js,识别截取的视频图片,若是失败则继续截图从新识别bash

decodeQrcode(base64) {
                let self = this
                // $('#screenshot_img').attr('src', base64)
                qrcode.decode(base64)
                qrcode.callback = function(imgMsg) {
                    if (!self.visible) {
                        return
                    }
                    if (imgMsg == 'error decoding QR Code') {
                        setTimeout(function() {
                        //截图从新识别
                            self.screenShot()
                        }, 2000)
                    } else {
                        alert(imgMsg)
                        window.location.href = imgMsg
                    }
                }
                // }
            }
复制代码
  • 获取识别内容

识别成功获取二维码内容ide

总结

最后二维码功能虽然实现了,可是远远超过个人预估时间,这里缘由大部分是由于二维码识别不单单须要识别二维码这一功能。在识别前咱们须要实现JavaScript调用摄像头功能,canvas截图功能等等一系列问题。因此下次再遇到本身未接触过的需求,就须要有充分的调研,详细的分析的需求的难点。ui

相关文章
相关标签/搜索