js扫描(上传)图片解析二维码
getUserMedia.访问摄像头(扫描以及上传图片)解析二维码
- 1.准备工作
- 2.通过getUserMedia方法调用摄像头进行扫描解析
- 3.上传图片解析二维码
话不多说先上效果图:
1.准备工作
引用解析二维码的js插件:qrcode.js。
核心:qrcode.js中的qrcode.decode方法和qrcode.callback方法
2.通过getUserMedia方法调用摄像头进行扫描解析
首先你要了解getUserMedia的使用方法,这是MDN上的解释:getUserMedia语法。
注意:getUserMedia必须在HTTPS协议下才能访问摄像头,并且有的浏览器不支持getUserMedia方法,在这里推荐大家使用Chrome浏览器。
- html代码:
<button type="button" class="btn btn-primary" onclick="showPrintModal()">扫描</button><div class="modal fade" id="_printModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h4 class="modal-title"></h4></div><div class="modal-body" style="position:relative"><div class="qrcode-box" style="position:absolute;left:50%;transform:translateX(-50%);width:300px;height:300px"><span></span><span></span><span></span><span></span></div><video style="width: 100%;height:300px"></video><canvas class="hidden" width="300" height="300"></canvas></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button></div></div></div>
</div>
- css代码:
.qrcode-box:after {-webkit-animation: rotateAnim linear 3.68s infinite;animation: rotateAnim linear 3.68s infinite;content: '';position: absolute;display: block;width: 100%;height: 30px;background-image: linear-gradient(rgba(0,0,0,0),rgba(31,162,255,1) 90%);
}
/*二维码上下移动的扫描横线*/
@keyframes rotateAnim {from {top: 0;}to {top: calc(100% - 30px);}
}
@-webkit-keyframes rotateAnim {from {top: 0;}to {top: calc(100% - 30px);}
}
/*二维码扫描框的四角*/
.qrcode-box span {width: 24px;height: 24px;position: absolute;border: 4px solid #1fa2ff;
}
.qrcode-box span:nth-child( 1) {left: -4px;top: -4px;border-width: 4px 0 0 4px;
}
.qrcode-box span:nth-child( 2) {right: -4px;top: -4px;border-width: 4px 4px 0 0;
}
.qrcode-box span:nth-child( 3) {right: -4px;bottom: -4px;border-width: 0 4px 4px 0;
}
.qrcode-box span:nth-child( 4) {left: -4px;bottom: -4px;border-width: 0 0 4px 4px;
}
- js代码:
//二维码扫描模态框
function showPrintModal() {//closeVideo:接收视频流对象序列;canvasImg:接收定时器var closeVideo, canvasImg;var video = $('#_printModal video')[0];var canvas = $('#_printModal canvas')[0];var context = canvas.getContext('2d');//页面切换关闭模态框$(document).on("visibilitychange", function () {var page = this.visibilityState;if (page == "hidden") {$('#_printModal').modal('hide');}});//getUserMedia兼容性处理var getUserMedia = (constraints, success, error) => {if (navigator.mediaDevices.getUserMedia) {//最新的标准APInavigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);} else if (navigator.webkitGetUserMedia) {//webkit核心浏览器navigator.webkitGetUserMedia(constraints).then(success).catch(error);} else if (navigator.mozGetUserMedia) {//firfox浏览器navigator.mozGetUserMedia(constraints).then(success).catch(error);} else if (navigator.getUserMedia) {//旧版APInavigator.getUserMedia(constraints).then(success).catch(error);}}var capture = () => {//canvas上生成video里的图像context.drawImage(video, 0, 0, 300, 300);//toDataURL会返回一个data-URI(base64)然后对此进行解析qrcode.decode(canvas.toDataURL('image/png'));//解析图片结果回调qrcode.callback = (e) => {//解析失败都会返回error decoding QR Code"if (e != "error decoding QR Code") {//二维码解析成功//停止访问摄像头closeVideo.stop();//停止定时器clearInterval(canvasImg);//清空canvas上的图片context.clearRect(0, 0, canvas.width, canvas.height);//显示二维码内容alert(e);}}}//调用用户媒体设备, 访问摄像头if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {//所在浏览器支持getUserMedia就调用getUserMedia({video: {width: 500,height: 500,//user前置摄像头facingMode: { exact: "environment" }}//基础配置,MDN上还有其他的介绍}, (stream) => {//getUserMedia访问摄像头成功的回调//显示模态框$('#_printModal').modal("show");//video接收摄像头捕获的视频流video.srcObject = stream;//视频流在video标签中播放video.play();//使用closeVideo变量接收视频流对象序列,用来之后的关闭操作closeVideo = stream.getTracks()[0];//定时器:每隔0.5s执行capture方法,在canvas上生成图片进行解析canvasImg = setInterval(capture, 500);}, () => {//getUserMedia访问摄像头失败的回调alert("访问用户媒体设备失败");});} else {//浏览器不存在getUserMedia方法alert('不支持访问用户媒体');}
}
核心的思路是:在html界面创建video标签和canvas标签,使用getUserMedia方法调用摄像头在video标签中播放,然后每个0.5s获取video标签上的图像,在canvas标签上生成当时获取到的图像图片,通过toDataURL得到图片的data-URI(base64)。最后使用解析二维码插件qrcode.js中的qrcode.decode方法进行解析,解析之后qrcode.callback会返回解析的结果。
我们可以封装成一个函数,在实际应用中直接使用new Promise方法获取解析的结果,其他地方要使用扫描二维码的时候,直接通过new Promise调用此方法即可,方便快捷:
//二维码扫描模态框
function showPrintModal(resolve) {var modalId = '_printModal';var html =`<div class="modal fade" id="${modalId}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h4 class="modal-title"></h4></div><div class="modal-body" style="position:relative"><div class="qrcode-box" style="position:absolute;left:50%;transform:translateX(-50%);width:300px;height:300px"><span></span><span></span><span></span><span></span></div><video style="width: 100%;height:300px"></video><canvas class="hidden" width="300" height="300"></canvas></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button></div></div></div></div>`;var modal = $(html);$("body").append(modal);var closeVideo, canvasImg, qrCode = null;var video = $('#_printModal video')[0];var canvas = $('#_printModal canvas')[0];var context = canvas.getContext('2d');modal.on('hidden.bs.modal',function () {if (closeVideo) {closeVideo.stop();}if (canvasImg) {clearInterval(canvasImg);}resolve(qrCode);modal.remove();});$(document).on("visibilitychange", function () {var page = this.visibilityState;if (page == "hidden") {modal.modal('hide');}});var getUserMedia = (constraints, success, error) => {if (navigator.mediaDevices.getUserMedia) {//最新的标准APInavigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);} else if (navigator.webkitGetUserMedia) {//webkit核心浏览器navigator.webkitGetUserMedia(constraints).then(success).catch(error);} else if (navigator.mozGetUserMedia) {//firfox浏览器navigator.mozGetUserMedia(constraints).then(success).catch(error);} else if (navigator.getUserMedia) {//旧版APInavigator.getUserMedia(constraints).then(success).catch(error);}}var capture = () => {context.drawImage(video, 0, 0, 300, 300);qrcode.decode(canvas.toDataURL('image/png'));qrcode.callback = (e) => {//结果回调if (e != "error decoding QR Code") {qrCode = e;clearInterval(canvasImg);context.clearRect(0, 0, canvas.width, canvas.height);modal.modal('hide');}}}if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {//调用用户媒体设备, 访问摄像头getUserMedia({video: {width: 500,height: 500,//user前置摄像头facingMode: { exact: "environment" }}}, (stream) => {modal.modal("show");video.srcObject = stream;video.play();closeVideo = stream.getTracks()[0];canvasImg = setInterval(capture, 500);}, () => {modal.modal('hide');layer.msg("访问用户媒体设备失败");});} else {modal.modal('hide');layer.msg('不支持访问用户媒体');}
}
new Promise调用:
new Promise(function (resolve) {showPrintModal(resolve);}).then((result) => {alert(result);//扫描解析成功返回的数据});
3.上传图片解析二维码
html代码:
<input type="file" id="file" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg">
js代码:
//点击按钮上传图片之后
$("#file").on('change', function () {new Promise(function (resolve) {printImgUp(resolve, this);}.bind(this)).then((result) => {$(this).val("");//上传图片解析的结果result != null ? alert(result) : alert('识别失败');});
});//createObjectURL兼容性处理,返回file对象的URL
function getObjectURL(file) {var url = null;if (window.createObjectURL != undefined) { // basicurl = window.createObjectURL(file);} else if (window.URL != undefined) { // mozilla(firefox)url = window.URL.createObjectURL(file);} else if (window.webkitURL != undefined) { // webkit or chromeurl = window.webkitURL.createObjectURL(file);}return url;
}//上传图片识别二维码
function printImgUp(resolve, fileId) {//得到图片的URLvar file = getObjectURL(fileId.files[0]);//解析URLqrcode.decode(file);//结果回调qrcode.callback = function (e) {URL.revokeObjectURL(file);resolve(e != "error decoding QR Code" ? e : null);}
}
实现逻辑:点击file按钮上传图片后,通过new Promise调用printImgUp方法进行解析,在printImgUp方法中能获取到上传图片的URL,然后通过qrcode.decode解析这个URL,最后qrcode.callback会返回解析的结果,比扫描简单多了!!!
js扫描(上传)图片解析二维码相关推荐
- 【小程序开发原创】小程序裁剪图片上传头像,二维码源码
微信小程序 图片裁剪工具,简单易用 项目需求 在做微信小程序的时候有个图片上传之前裁剪的需求,找过一些github中的项目,都不太理想,主要是没有办法自定义宽高,于是自己研究了一下,做了一个简单的图片 ...
- Android Zxing3.3.2扫描、生成、解析二维码,以及近距离无法识别的问题
Zxing目前最新版本3.3.2,打开摄像头就成功了,真正的极速扫描,效果喜人. 一.集成流程 1.克隆代码就不说了. 2.zxing项目巨大,我们只需要扫描部分的代码. 将android.andro ...
- java+vue的二维码生成,二维码上传服务器,二维码的压缩包下载
一. vue页面生成二维码 <template><div class="app-container">//在页面放着二维码的div<div id=&q ...
- Java利用Zxing生成二维码及解析二维码内容
前言 Java 操作二维码的开源项目很多,如 SwetakeQRCode.BarCode4j.Zxing 等等 本篇文章是介绍利用Zxing来生成二维码图片在web网页上展示,同时解析二维码图片. Z ...
- QRCode生成二维码和解析二维码
使用QRCode生成和解析二维码,这个和前面的不一样,只要盗图两个jar(后面上传),即可生成二维码 直接上代码,注释都有 Qrcode qrcode=new Qrcode();qrcode.setQ ...
- HTML5+js 实现生成二维码,扫描解析二维码
先看效果图 二维码内容可以是数字,字母,中文,都可以解析识别.中文会存在乱码问题,要使用utf8Decode转码后才可以正确解析. 代码 使用了两个页面,一个是生成二维码页面,一个是解析页面. 下面是 ...
- Android超方便 集成 Zxing实现扫一扫,闪光灯,生成二维码图片,解析二维码(条码)等功能
之前我写过一篇博客是关于如何将zxing集成到Android Studio中,以及简单的实现扫一扫功能. 详情请看:Android Studio集成Zxing扫一扫 但是,上面那篇博客只有有一个扫一扫 ...
- llqrcode.js识别二维码,解析二维码信息
llqrcode.js具有扫描二维码功能,用来进行从图片中识别二维码,可解析二维码的信息. 直接上代码 <!DOCTYPE html> <html> <head>& ...
- js 将微信二维码转为url,qrcodeJs解析二维码,qrcode.decode is not a function报错
前言 工作中遇到的需求:用户上传相册中选中的图片,判断这个图片里的二维码是不是微信二维码,如果是则上传到服务器:不是,则提示用户重新上传. 百度了下,qrcode.js是一个用于生成二维码的 Java ...
最新文章
- 如何查看SharePoint未知错误
- html列表无序嵌套,HTML/CSS - 如何正确定位这些嵌套的无序列表?
- 阿里云Redis (安装包安装篇)
- canvas绘制线条1像素的问题
- 知方可补不足~数据库名称和数据库别名不同了怎么办
- JAVA第三方包导入但找不到类,解决:导入第三方包报错java.lang.NoClassDefFoundError:XXX.XXX,XXXXXX...
- 在Linux中查看正在运行哪些process,杀掉一批名字相同的process
- 手动编译包含两个import自写类的java类。
- torch随机数 manual_seed
- cmd下执行java
- 离线安装SilverLight
- 华硕服务器主板那个系列好,华硕主板型号性价比排行 华硕主板那个性价最好用...
- mini QQ(项目一)
- 9. Enhancing Aspect Term Extraction with Soft Prototypes论文阅读笔记
- ajax 与form 表单连用 success不执行bug解决
- D3D9 简单图形的绘制以及显示
- 【鬼脚七经典电商思路】淘宝卖家的竞争力(2)之迎合容量
- 软件设计师之法律法规知识
- 尺寸有点太大了吧,我已经受不鸟了
- w ndows无法连接到System,电脑无法连接到System Event Notification Service服务