admin管理员组

文章数量:1614169

刚开始提出要在手机浏览器中的HTML页面做扫描是有点懵的,一顿百度后搜到两种方法:

方案一,浏览器中打开相机navigator.mediaDevices.getUserMedia

  1. 自带浏览器不支持该属性,Chrome只支持HTTPS的链接,其它浏览器可以打开前置摄像头,后置摄像头的问题后来找到个方法,实测UC浏览器可用。
  2. 识别效率不高,需要自己将拍照的图片进行识别。
  3. 每次打开都会询问访问权限,浏览器关闭后再打开会有权限提示。

方案二,浏览器打开本地相机<input type="file" accept="image/*" capture="camera">

  1. 自带浏览器能够打开本地相机
  2. 需要用户进行手动操作,先点击扫描-打开本地相机-点击拍照-进行识别,如果第一次识别不到,需要用户重复手动操做

很明显第二种可以做图片上传啥的,但不适合做扫描,虽然第一种方案限制很大,但也只能硬着头皮做了。

成品长这样子

先来个官网链接

再来个参考示例,这个示例主要解决了navigator.mediaDevices.getUserMedia后置摄像头的问题。使用前先在手机浏览器打开这个网址https://philnash.github.io/mediadevices-camera-selection/,试一下能否打开后置摄像头

贴个代码,加完整示例,包括reqrcode.js进行图片识别二维码,以及一些自定义样式文件。

有好多bug,每次访问权限的问题没有解决,前后摄像头转换没加,毕竟扫描只用到了后置。还有一个地方就是中文二维码识别乱码的问题也没解决,应该是reqrcodejs的问题,可以试试jQuery的qrcodejs。

<div class="content">
    <video id="video" width="100%" height="100%" autoplay="autoplay" style="object-fit: fill">您的浏览器不支持该功能~</video>
    <canvas id="canvas" width="500px" height="500px" style="display: none"></canvas>
    <div class="bc-scan"></div>
    <div class="through-line"></div>
</div>

<script>
    var video = document.getElementById('video');
    var currentStream;
    var labelId = "";//后置摄像头的id

    function stopMediaTracks(stream) {
        stream.getTracks().forEach(function (track) {
            track.stop();
        });
    }

    //获取设备信息,获取后置摄像头信息
    function gotDevices(mediaDevices) {
        var count = 1;
        for (var i = 0; i < mediaDevices.length; i++) {
            if (mediaDevices[i].kind === 'videoinput') {
                var label = mediaDevices[i].label || 'Camera ' + count++;
                if ("camera 0, facing back" == label) {
                    labelId = mediaDevices[i].deviceId;
                    console.log("deviceId1====" + label);
                    getMedia();
                    break;
                }
                var textNode = document.createTextNode(label);
            }
        }
    }

    //打开摄像头,防止无限循环
    function gotDevices2(mediaDevices) {
        var count = 1;
        for (var i = 0; i < mediaDevices.length; i++) {
            if (mediaDevices[i].kind === 'videoinput') {
                var label = mediaDevices[i].label || 'Camera ' + count++;
                if ("camera 0, facing back" == label) {
                    labelId = mediaDevices[i].deviceId;
                    console.log("deviceId1====" + label);
                    takePhoto();
                    break;
                }
                var textNode = document.createTextNode(label);
            }
        }
    }

    //打开相机
    function getMedia() {
        if (typeof currentStream !== 'undefined') {
            stopMediaTracks(currentStream);
        }
        var videoConstraints = {};
        if (labelId === '') {
            videoConstraints.facingMode = 'environment';
        } else {
            videoConstraints.deviceId = {exact: labelId};
            console.log("deviceId2======" + videoConstraints.deviceId);
        }
        var constraints = {
            video: videoConstraints,
            audio: false
        };
        navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
            currentStream = stream;
            video.srcObject = stream;
            return navigator.mediaDevices.enumerateDevices();
        }).then(gotDevices2).catch(function (error) {
            console.error(error);
            alert("您拒绝了使用摄像头的权限,扫描功能将无法使用,请重启浏览器");
        });
    }

    navigator.mediaDevices.enumerateDevices().then(gotDevices);


    //拍照识别
    function takePhoto() {
        //获得Canvas对象
        var video = document.getElementById("video");
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');
        ctx.drawImage(video, 0, 0, 500, 500);
        // 把画布的内容转换为base64编码格式的图片
        var data = canvas.toDataURL('image/png', 1);  //1表示质量(无损压缩)
        //解析二维码
        qrcode.decode(data);
        qrcode.callback = function (imgMsg) {
            console.log(imgMsg);
            if (imgMsg == 'error decoding QR Code') {
                takePhoto();
            } else {
                alert("扫描成功," + imgMsg);
             
            }
        }
    }
</script>

本文标签: 器中相机二维码