getUserMedia.访问摄像头(扫描以及上传图片)解析二维码

  • 1.准备工作
  • 2.通过getUserMedia方法调用摄像头进行扫描解析
  • 3.上传图片解析二维码

话不多说先上效果图:

1.准备工作

引用解析二维码的js插件:qrcode.js。
核心:qrcode.js中的qrcode.decode方法和qrcode.callback方法

2.通过getUserMedia方法调用摄像头进行扫描解析

首先你要了解getUserMedia的使用方法,这是MDN上的解释:getUserMedia语法。

注意:getUserMedia必须在HTTPS协议下才能访问摄像头,并且有的浏览器不支持getUserMedia方法,在这里推荐大家使用Chrome浏览器。

  1. 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">&times;</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>
  1. 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;
}
  1. 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">&times;</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扫描(上传)图片解析二维码相关推荐

  1. 【小程序开发原创】小程序裁剪图片上传头像,二维码源码

    微信小程序 图片裁剪工具,简单易用 项目需求 在做微信小程序的时候有个图片上传之前裁剪的需求,找过一些github中的项目,都不太理想,主要是没有办法自定义宽高,于是自己研究了一下,做了一个简单的图片 ...

  2. Android Zxing3.3.2扫描、生成、解析二维码,以及近距离无法识别的问题

    Zxing目前最新版本3.3.2,打开摄像头就成功了,真正的极速扫描,效果喜人. 一.集成流程 1.克隆代码就不说了. 2.zxing项目巨大,我们只需要扫描部分的代码. 将android.andro ...

  3. java+vue的二维码生成,二维码上传服务器,二维码的压缩包下载

    一. vue页面生成二维码 <template><div class="app-container">//在页面放着二维码的div<div id=&q ...

  4. Java利用Zxing生成二维码及解析二维码内容

    前言 Java 操作二维码的开源项目很多,如 SwetakeQRCode.BarCode4j.Zxing 等等 本篇文章是介绍利用Zxing来生成二维码图片在web网页上展示,同时解析二维码图片. Z ...

  5. QRCode生成二维码和解析二维码

    使用QRCode生成和解析二维码,这个和前面的不一样,只要盗图两个jar(后面上传),即可生成二维码 直接上代码,注释都有 Qrcode qrcode=new Qrcode();qrcode.setQ ...

  6. HTML5+js 实现生成二维码,扫描解析二维码

    先看效果图 二维码内容可以是数字,字母,中文,都可以解析识别.中文会存在乱码问题,要使用utf8Decode转码后才可以正确解析. 代码 使用了两个页面,一个是生成二维码页面,一个是解析页面. 下面是 ...

  7. Android超方便 集成 Zxing实现扫一扫,闪光灯,生成二维码图片,解析二维码(条码)等功能

    之前我写过一篇博客是关于如何将zxing集成到Android Studio中,以及简单的实现扫一扫功能. 详情请看:Android Studio集成Zxing扫一扫 但是,上面那篇博客只有有一个扫一扫 ...

  8. llqrcode.js识别二维码,解析二维码信息

    llqrcode.js具有扫描二维码功能,用来进行从图片中识别二维码,可解析二维码的信息. 直接上代码 <!DOCTYPE html> <html> <head>& ...

  9. js 将微信二维码转为url,qrcodeJs解析二维码,qrcode.decode is not a function报错

    前言 工作中遇到的需求:用户上传相册中选中的图片,判断这个图片里的二维码是不是微信二维码,如果是则上传到服务器:不是,则提示用户重新上传. 百度了下,qrcode.js是一个用于生成二维码的 Java ...

最新文章

  1. 如何查看SharePoint未知错误
  2. html列表无序嵌套,HTML/CSS - 如何正确定位这些嵌套的无序列表?
  3. 阿里云Redis (安装包安装篇)
  4. canvas绘制线条1像素的问题
  5. 知方可补不足~数据库名称和数据库别名不同了怎么办
  6. JAVA第三方包导入但找不到类,解决:导入第三方包报错java.lang.NoClassDefFoundError:XXX.XXX,XXXXXX...
  7. 在Linux中查看正在运行哪些process,杀掉一批名字相同的process
  8. 手动编译包含两个import自写类的java类。
  9. torch随机数 manual_seed
  10. cmd下执行java
  11. 离线安装SilverLight
  12. 华硕服务器主板那个系列好,华硕主板型号性价比排行 华硕主板那个性价最好用...
  13. mini QQ(项目一)
  14. 9. Enhancing Aspect Term Extraction with Soft Prototypes论文阅读笔记
  15. ajax 与form 表单连用 success不执行bug解决
  16. D3D9 简单图形的绘制以及显示
  17. 【鬼脚七经典电商思路】淘宝卖家的竞争力(2)之迎合容量
  18. 软件设计师之法律法规知识
  19. 尺寸有点太大了吧,我已经受不鸟了
  20. w ndows无法连接到System,电脑无法连接到System Event Notification Service服务

热门文章

  1. 两道有点难的回溯利口题996_37
  2. 小程序怎么变成链接?
  3. SQL Server 常用日期函数的运用
  4. keepass密码管理器使用
  5. 怀孕期间可以让孩子变漂亮的办法
  6. md5 16位加密 java_MD5加密,MD5在线加密,MD5校验
  7. 离散余弦变换 DCT
  8. 工业网关下的智慧楼宇整体监测解决方案
  9. 苏州市软件行业协会元宇宙专委会成立
  10. P8400 [CCC 2022 J1] Cupcake Party