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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
} 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调用手机本地摄像头和相册识别二维码详细实现过程的更多相关文章
- 使用JS调用手机本地摄像头或者相册图片识别二维码/条形码
接着昨天的需求,不过这次不依赖微信,使用纯js唤醒手机本地摄像头或者选择手机相册图片,识别其中的二维码或者是条形码.昨天,我使用微信扫一扫识别,效果超棒的.不过如果依赖微信的话,又怎么实现呢,这里介绍 ...
- python3 树莓派 + usb摄像头 做颜色识别 二维码识别
今天又啥也没干 我完蛋了哦 就是没办法沉下心来,咋办....还是先来条NLP吧.. 七,凡事必有至少三个解决方法 对事情只有一个方法的人,必陷入困境,因为别无选择. 对事情有两个方法的人也陷入困境, ...
- HTML5实现扫描识别二维码/生成二维码
扫描识别二维码 思路: 1. 操作摄像头,获取图片.HTML5 WEBRTC的navigator.getUserMedia方法去实时获取摄像头资源. 2. 利用canvas使用相关算法分析图片识别图 ...
- day111:MoFang:邀请好友流程&生成邀请好友二维码&第三方应用识别二维码&本地编译测试&记录邀请人信息
目录 1.邀请业务逻辑流程图 2.邀请好友-前端 3.邀请好友-后端接口(生成二维码) 4.前端获取后端生成的二维码 5.前端长按页面,保存图片到相册 6.客户端通过第三方识别微信二维码,服务端提供对 ...
- iOS--iOS7摄像头识别二维码功能
iOS–iOS7摄像头识别二维码功能 属性介绍: AVFoundation 框架基于以下几个类实现图像捕捉 ,通过这些类可以访问来自相机设备的原始数据并控制它的组件. AVCaptureDevice ...
- ios 中生成二维码和相册中识别二维码
iOS 使用CIDetector扫描相册二维码.原生扫描 原生扫描 iOS7之后,AVFoundation让我们终于可以使用原生扫描进行扫码了(二维码与条码皆可)AVFoundation可以让我们从设 ...
- 移动端禁止图片长按和vivo手机点击img标签放大图片,禁止长按识别二维码或保存图片【转载】
移动端禁止图片长按和vivo手机点击img标签放大图片,禁止长按识别二维码或保存图片 img{ pointer-events: none; } 源文地址:https://www.cnblogs.com ...
- C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(二)
1.使用ZXint.Net生成带logo的二维码 /// <summary> /// 生成带Logo的二维码 /// </summary> /// <param name ...
- winform 扫码识别二维码
因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能. 我根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好) 现在将调用摄像头+识别二 ...
随机推荐
- NVME SSD vs SATA SSD(转)
NVMe是个啥?未来SSD主流标准早知 关注固态硬盘的朋友应该对于这个词汇并不陌生,特别是今年NVMe也频繁出现在各大媒体文章中,随着高端SSD市场逐渐从SATA专项PCI-E时,以前的AHCI标准已 ...
- hdu 5078(2014鞍山现场赛 I题)
数据 表示每次到达某个位置的坐标和时间 计算出每对相邻点之间转移的速度(两点间距离距离/相隔时间) 输出最大值 Sample Input252 1 9//t x y3 7 25 9 06 6 37 6 ...
- Hive SQL综合案例
一 Hive SQL练习之影评案例 案例说明 现有如此三份数据:1.users.dat 数据格式为: 2::M::56::16::70072, 共有6040条数据对应字段为:UserID BigInt ...
- java.lang.NoClassDefFoundError: javax/persistence/EntityListeners
在使用 Hibernate 进行数据库操作的时候,在启动 Tomcat 服务器后,Console 控制台可能会打印出这样的异常:java.lang.NoClassDefFoundError: java ...
- CentOS7多实例安装mysq5.6二进制版本
1丶下载mysql,解压,创建用户,创建软链接 test -d /tools || mkdir /tools ;cd /tools wget http://mirrors.sohu.com/mysql ...
- python3与mysql交互:pymysql
python3与mysql交互 1.安装pymysql模块 pip3 install pymysql3 2.pymysql的简单使用: # /usr/bin/env python3 import py ...
- Bootstrap--响应式表格布局
<div class="row"> <div class="col-sm-2 col-md-2" style="min-height ...
- Hive分区和桶的概念
Hive 已是目前业界最为通用.廉价的构建大数据时代数据仓库的解决方案了,虽然也有 Impala 等后起之秀,但目前从功能.稳定性等方面来说,Hive 的地位尚不可撼动. 其实这篇博文主要是想聊聊 S ...
- Bubbo的启动时检查
这个地方参考dubbo的官网,不是很难,为了使得文档的完整,也单独起一章. 1.默认 Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时, ...
- xshell连接linux,切换焦点,自动执行ctrl+c
这几天发现 xshell 连接 linux 的时候,无缘无故的执行了 ctrl+c,导致 执行界面 终端,比方说 ,hbase shell 执行窗口命令 ,每次切换 窗口焦点之后,就终止了.百度后 发 ...