html5调用手机本地摄像头和相册识别二维码详细实现过程(附源码下载)

 项目中有用到h5识别我们的单据,单据上面有二维码. 实现的场景就是业务人员扫码 类似以下场景

 业务员拿到单据以后,直接可以扫码进入相关单据业也可以 输入二维码下方的号码进行识别

 

 

 

 

 

下面是h5的页面构造(部分代码参考国外网友编写的)

@{
    Layout = "~/Views/Shared/_MForm.cshtml";// 这里是weui的样式 可以不用就是按钮变丑了而已
}
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Web QR</title>

    <style type="text/css">
        body {
            width: 100%;
            text-align: center;
        }

        img {
            border: 0;
        }

        #main {
            margin: 15px auto;
            background: white;
            overflow: auto;
            width: 100%;
        }

 
        #mainbody {
            background: white;
            width: 100%;
            display: none;
        }

        #footer {
            background: white;
        }

        #v {
            width: 320px;
            height: 240px;
        }

        #qr-canvas {
            display: none;
        }

        #qrfile {
            width: 320px;
            height: 240px;
        }

        #mp1 {
            text-align: center;
            font-size: 35px;
        }

        #imghelp {
            position: relative;
            left: 0px;
            top: -160px;
            z-index: 100;
            font: 18px arial,sans-serif;
            background: #f0f0f0;
            margin-left: 35px;
            margin-right: 35px;
            padding-top: 10px;
            padding-bottom: 10px;
            border-radius: 20px;
        }

        .selector {
            margin: 0;
            padding: 0;
            cursor: pointer;
            margin-bottom: -5px;
        }

        #outdiv {
            width: 320px;
            height: 240px;
            border: solid;
            border-width: 3px 3px 3px 3px;
        }

        #result {
            border: solid;
            border-width: 1px 1px 1px 1px;
            padding: 20px;
            width: 70%;
        }

      

        .tsel {
            padding: 0;
        }
         .fileinput-button {
            position: relative;
            display: none;
        }
 

    </style>
    <script src="~/Content/scripts/weui/barcode/llqrcode.js"></script>
    
    <script src="~/Content/scripts/weui/barcode/webqr.js"></script>
</head>

<body >
    <div id="main">
        <div id="mainbody">
            <table class="tsel" border="0" width="100%">
                <tr>
                    <td valign="top" align="center" width="50%">
                        <table class="tsel" border="0">
                            @*<tr>
                                <td><img class="selector" id="webcamimg" src="vid.png" onclick="setwebcam()" align="left" /></td>
                                <td><img class="selector" id="qrimg" src="cam.png" onclick="setimg()" align="right" /></td>
                            </tr>*@
                            <tr>
                                <td  align="center">
                                    <div id="outdiv">
                                    </div>
                                </td>
                            </tr>
                            <tr>
                                <td><a class="weui-btn weui-btn_primary"   href="javascript:void(0);" onclick="setwebcam()" id="btnsaveCharge">相机扫码</a></td>
                            </tr>
                            <tr>
                                <td><a class="weui-btn weui-btn_primary" href="javascript:void(0);" onclick="setimg()" id="btnsaveCharge">相册识别</a></td>
                            </tr>
                            <tr ><td><div  class="weui-input" id="result"></div></td></tr>
                        </table>
                    </td>
                </tr>
            </table>
        </div>
    </div>
    <canvas id="qr-canvas" width="800" height="600"></canvas>
    <script type="text/javascript">

        load();
        setwebcam();
    
    </script>
</body>

</html>

 

 

//如果您对具体实现感兴趣可以看看

var gCtx = null;
var gCanvas = null;
var c=0;
var stype=0;
var gUM=false;
var webkit=false;
var moz=false;
var v=null;
 
//隐藏了从相册获取图片的情况
var imghtml = '<div id="qrfile"><canvas id="out-canvas" width="320" height="240"></canvas>' +
    '<div id="imghelp"  style="display:none">' +
      '<span class="fileinput-button"> <input id="picselect" type="file"  onchange="handleFiles(this.files)"  > </span>' +
    '</div>' +
'</div>';

var vidhtml = '<video id="v" autoplay></video>';

function dragenter(e) {
  e.stopPropagation();
  e.preventDefault();
}

function dragover(e) {
  e.stopPropagation();
  e.preventDefault();
}
function drop(e) {
  e.stopPropagation();
  e.preventDefault();

  var dt = e.dataTransfer;
  var files = dt.files;
  if(files.length>0)
  {
    handleFiles(files);
  }
  else
  if(dt.getData('URL'))
  {
    qrcode.decode(dt.getData('URL'));
  }
}

function handleFiles(f)
{
    var o=[];
    
    for(var i =0;i<f.length;i++)
    {
        var reader = new FileReader();
        reader.onload = (function(theFile) {
        return function(e) {
            gCtx.clearRect(0, 0, gCanvas.width, gCanvas.height);

            qrcode.decode(e.target.result);
        };
        })(f[i]);
        reader.readAsDataURL(f[i]);    
    }
}

function initCanvas(w,h)
{
    gCanvas = document.getElementById("qr-canvas");
    gCanvas.style.width = w + "px";
    gCanvas.style.height = h + "px";
    gCanvas.width = w;
    gCanvas.height = h;
    gCtx = gCanvas.getContext("2d");
    gCtx.clearRect(0, 0, w, h);
}


function captureToCanvas() {
    if(stype!=1)
        return;
    if(gUM)
    {
        try{
            gCtx.drawImage(v,0,0);
            try{
                qrcode.decode();
            }
            catch(e){       
                console.log(e);
                setTimeout(captureToCanvas, 500);
            };
        }
        catch(e){       
                console.log(e);
                setTimeout(captureToCanvas, 500);
        };
    }
}

function htmlEntities(str) {
    return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

function read(a)
{

    alert(a);

}    

function isCanvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}
function success(stream) 
{

    v.srcObject = stream;
    v.play();

    gUM=true;
    setTimeout(captureToCanvas, 500);
}
        
function error(error)
{
    gUM=false;
    return;
}

function load()
{
    if(isCanvasSupported() && window.File && window.FileReader)
    {
        initCanvas(800, 600);
        qrcode.callback = read;
        document.getElementById("mainbody").style.display="inline";
        setwebcam();
    }
    else
    {
        document.getElementById("mainbody").style.display="inline";
        alert("您当前浏览器不支持扫码,请安装UC浏览器试试!");
    }
}

function setwebcam()
{
    
    var options = true;
    if(navigator.mediaDevices && navigator.mediaDevices.enumerateDevices)
    {
        try{
            navigator.mediaDevices.enumerateDevices()
            .then(function(devices) {
              devices.forEach(function(device) {
                if (device.kind === 'videoinput') {
                  if(device.label.toLowerCase().search("back") >-1)
                    options={'deviceId': {'exact':device.deviceId}, 'facingMode':'environment'} ;
                }
                console.log(device.kind + ": " + device.label +" id = " + device.deviceId);
              });
              setwebcam2(options);
            });
        }
        catch(e)
        {
            console.log(e);
        }
    }
    else{
        console.log("no navigator.mediaDevices.enumerateDevices" );
        setwebcam2(options);
    }
    
}

function setwebcam2(options)
{
    console.log(options);
    document.getElementById("result").innerHTML="- scanning -";
    if(stype==1)
    {
        setTimeout(captureToCanvas, 500);    
        return;
    }
    var n=navigator;
    document.getElementById("outdiv").innerHTML = vidhtml;
    v=document.getElementById("v");


    if(n.mediaDevices.getUserMedia)
    {
        n.mediaDevices.getUserMedia({video: options, audio: false}).
            then(function(stream){
                success(stream);
            }).catch(function(error){
                error(error)
            });
    }
    else
    if(n.getUserMedia)
    {
        webkit=true;
        n.getUserMedia({video: options, audio: false}, success, error);
    }
    else
    if(n.webkitGetUserMedia)
    {
        webkit=true;
        n.webkitGetUserMedia({video:options, audio: false}, success, error);
    }
 
    stype=1;
    setTimeout(captureToCanvas, 500);
}

function setimg()
{
    document.getElementById("result").innerHTML="";
    if(stype==2)
        return;
    document.getElementById("outdiv").innerHTML = imghtml; //绘制选取样式
 

    //这里模拟点击事件
    var fileEle = document.getElementById('picselect');
    if (fileEle) {
        fileEle.click();
    }


    var qrfile = document.getElementById("qrfile");
    qrfile.addEventListener("dragenter", dragenter, false);  
    qrfile.addEventListener("dragover", dragover, false);  
    qrfile.addEventListener("drop", drop, false);
    stype=2;
}

 

 

 

 

 

 

 示例1  ----本地或相册二维码识别结果

 

 

示例2   相机扫码识别结果

 

 需要引用的库请点击附件下载 ↓

附件

源码参考直接右键 :https://files.cnblogs.com/files/benbenfishfish/htmltortf.zip

 

 

 

 

需要注意的是:

我目前只测试了安卓平台UC浏览器. 其他浏览器未做测试. 

posted @ 2018-09-19 13:54  笨笨鱼~  阅读(23798)  评论(15编辑  收藏  举报