项目中有用到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浏览器. 其他浏览器未做测试.

html5调用手机本地摄像头和相册识别二维码详细实现过程的更多相关文章

  1. 使用JS调用手机本地摄像头或者相册图片识别二维码/条形码

    接着昨天的需求,不过这次不依赖微信,使用纯js唤醒手机本地摄像头或者选择手机相册图片,识别其中的二维码或者是条形码.昨天,我使用微信扫一扫识别,效果超棒的.不过如果依赖微信的话,又怎么实现呢,这里介绍 ...

  2. python3 树莓派 + usb摄像头 做颜色识别 二维码识别

    今天又啥也没干 我完蛋了哦  就是没办法沉下心来,咋办....还是先来条NLP吧.. 七,凡事必有至少三个解决方法 对事情只有一个方法的人,必陷入困境,因为别无选择. 对事情有两个方法的人也陷入困境, ...

  3. HTML5实现扫描识别二维码/生成二维码

    扫描识别二维码 思路: 1. 操作摄像头,获取图片.HTML5 WEBRTC的navigator.getUserMedia方法去实时获取摄像头资源.  2. 利用canvas使用相关算法分析图片识别图 ...

  4. day111:MoFang:邀请好友流程&生成邀请好友二维码&第三方应用识别二维码&本地编译测试&记录邀请人信息

    目录 1.邀请业务逻辑流程图 2.邀请好友-前端 3.邀请好友-后端接口(生成二维码) 4.前端获取后端生成的二维码 5.前端长按页面,保存图片到相册 6.客户端通过第三方识别微信二维码,服务端提供对 ...

  5. iOS--iOS7摄像头识别二维码功能

    iOS–iOS7摄像头识别二维码功能 属性介绍: AVFoundation 框架基于以下几个类实现图像捕捉 ,通过这些类可以访问来自相机设备的原始数据并控制它的组件. AVCaptureDevice ...

  6. ios 中生成二维码和相册中识别二维码

    iOS 使用CIDetector扫描相册二维码.原生扫描 原生扫描 iOS7之后,AVFoundation让我们终于可以使用原生扫描进行扫码了(二维码与条码皆可)AVFoundation可以让我们从设 ...

  7. 移动端禁止图片长按和vivo手机点击img标签放大图片,禁止长按识别二维码或保存图片【转载】

    移动端禁止图片长按和vivo手机点击img标签放大图片,禁止长按识别二维码或保存图片 img{ pointer-events: none; } 源文地址:https://www.cnblogs.com ...

  8. C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(二)

    1.使用ZXint.Net生成带logo的二维码 /// <summary> /// 生成带Logo的二维码 /// </summary> /// <param name ...

  9. winform 扫码识别二维码

    因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能. 我根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好) 现在将调用摄像头+识别二 ...

随机推荐

  1. 30 C? Go? Cgo!

    C? Go? Cgo! 17 March 2011 Introduction Cgo lets Go packages call C code. Given a Go source file writ ...

  2. 洛谷P1782 旅行商的背包

    传送门啦 这个题不用二进制优化的话根本不行,现学的二进制优化,调了一段时间终于A了,不容易.. 如果不懂二进制优化的话可以去看我那个博客 二进制优化多重背包入口 不想TLE,不要打memset,一定要 ...

  3. 20165203 预备作业3 Linux安装及学习

    一.安装虚拟机 1.下载问题:当自己在虚拟机上下载ubuntu时,总是下载好长时间,而且最后下载失败,这让我很苦恼. 解决方案:求助同学后,同学给了我一个中文版官网的网址http://cn.ubunt ...

  4. Nt函数原型头文件

    //转自看雪,可以作为一个头文件使用,方便快捷 1 NTSTATUS NTAPI NtAcceptConnectPort( OUT PHANDLE PortHandle, IN PVOID PortI ...

  5. 更改MyEclipse中的src目录的浏览方式

    看到这个标题,有人可能不会明白,这里先看张图: 右边的图就是我们要更改的样子,有的时候我们做项目需要看下目录的层次,于是使用了Navigator的那个视图,其实常用的这种包视图也可以变成那种样式. 这 ...

  6. 二进制方式部署Kubernetes 1.6.0集群(开启TLS)

    本节内容: Kubernetes简介 环境信息 创建TLS加密通信的证书和密钥 下载和配置 kubectl(kubecontrol) 命令行工具 创建 kubeconfig 文件 创建高可用 etcd ...

  7. JavaScript闭包与变量的经典问题

    许多人第一次接触闭包大概都是从高程里这段代码开始的: function createFunctions() { var result = new Array(); for(var i=0; i< ...

  8. 2017 ACM Amman Collegiate Programming Contest 题解

    [题目链接] A - Watching TV 模拟.统计一下哪个数字最多即可. #include <bits/stdc++.h> using namespace std; const in ...

  9. 【GO基础】神奇的iota特殊常量

    最近在学习GO语言,然后发现有一个特殊常量是以前没有接触过的,比较感兴趣,这里给大家介绍一下. iota,特殊常量,可以被认为是一个可以被编译器修改的常量. 核心概念:iota在const关键字出现时 ...

  10. 【运维理论】RAID级别简介

    独立硬盘冗余阵列(RAID, Redundant Array of Independent Disks),旧称廉价磁盘冗余阵列(RAID, Redundant Array of Inexpensive ...