HTML5能够经过调用navigator.getUserMedia来获取手机设备摄像头,兼容性写法以下javascript
window.navigator.getUserMedia = navigator.getUserMedia || navigator.webKitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;css
可是navigator.getUserMediau已经从 Web 标准中删除,虽然部分浏览器可使用,生产环境中仍是要作好兼容。新的API更替为MediaDevices.getUserMedia。MediaDevices.getUserMedia能够经过video的facingMode属性指定调用手机的前置或后置摄像头
video:{ 'facingMode': "user" }//调用前置摄像头
video: { facingMode: { exact: "environment" } }//后置html
具体代码:java
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <title>Document1</title> <style type='text/css'> * { margin: 0; padding: 0; } html, body { height: 100%; } .flex { display: flex; } .flex-row { flex-direction: row; justify-content: space-around; align-items: center; } .flex-column { flex-direction: column; justify-content: flex-start; align-items: center; } body { overflow: auto; background: #fff; } .title { width: 920px; padding: 30px; align-items: flex-end; } .title h1 { padding-bottom: 20px; font-size: 38px; color: #ffffff; text-shadow: 0 1px 3px #222222; } .title p { font-size: 18px; color: #f5f5f5; text-shadow: 0 1px 3px #565656; } .wrap { width: 1220px; } .wrap .reference { position: relative; padding: 10px; background-color: rgba(255, 255, 255, 0); border-radius: 10px; box-shadow: 0 0 20px #a1a19f; } .wrap .reference img.face { display: block; width: 320px; height: auto; border-radius: 10px; } .wrap .reference img.toggle { position: absolute; right: 10px; top: 10px; width: 50px; height: 50px; } .wrap .scan video { background-color: rgba(0, 0, 0, .8); border-radius: 10px; } .wrap .control { justify-content: space-around; height: 456px; padding: 0 20px; } .wrap .control p { width: 160px; height: 60px; background-color: #f9f9f9; text-align: center; line-height: 60px; color: #ffffff; font-size: 24px; border-radius: 8px; cursor: pointer; box-shadow: -8px -8px 150px -8px #b2b3b5 inset, 0 0 5px #222222; text-shadow: 0 0 1px #222222; transition: .5s; } .wrap .control p:hover { box-shadow: -8px -8px 150px -8px #50c4f1 inset, 0 0 5px #ffffff; } .wrap .scan { position: relative; overflow: hidden; } .wrap .scan .strainer { position: absolute; top: 10px; width: 320px; z-index: 999; height: 3px; } .wrap .scan .capture { width: 320px; height: 456px; } .wrap .scan .strainer.on { background: linear-gradient(to left, transparent, #0bffb2, transparent); animation: scan 1s linear infinite; } @keyframes scan { 0% { top: 10px; } 50% { top: 456px; } 100% { top: 10px; } } </style> <script type="text/javascript" src="vconsole.min.js"></script> </head> <body> <div class="title flex flex-column"> </div> <div class="wrap flex flex-row"> <div class="control flex flex-column"> <p class="open">开启摄像头</p> <p class="recognition">显示到Canvas</p> <p class="close">关闭摄像头</p> </div> <div class="scan reference"> <div class="strainer"></div> <video class="capture" width="320" height="456" src=""></video> </div> </div> <script type="text/javascript"> var buffer; var oCapture = document.querySelector(".capture"), open = document.querySelector(".open"), recognition = document.querySelector(".recognition"), close = document.querySelector(".close"); var control = document.querySelector(".control"); window.navigator.getUserMedia = navigator.getUserMedia || navigator.webKitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; function invokingCarera(){ if(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){ navigator.mediaDevices.getUserMedia({ 'audio':true, 'video':{ 'facingMode': "user" }//调用前置摄像头,后置摄像头使用video: { facingMode: { exact: "environment" } } }) .then(function(mediaStream) {console.log(555);getVideoStream(mediaStream)}) .catch(function(error) { console.log(666);console.log(error) }) }else if(navigator.getUserMedia){ navigator.getUserMedia({ 'video':true, 'audio':true },getVideoStream,getFail) }else{ alert('不支持摄像头调用!') } } //调用成功 function getVideoStream(stream){ buffer = stream; if(oCapture.mozSrcObject !== undefined){ oCapture.mozSrcObject = buffer; }else{ oCapture.src = window.URL && window.URL.createObjectURL(buffer); } oCapture.play(); } function getFail(){ } recognition.onclick = function(){ } control.addEventListener('click',function(e){ e = e || window.event; var className = e.target.className; switch(className){ case 'open': invokingCarera(); break; case 'close': closeCamera(); break; case 'recognition': screenShot(); break; default: break; } }) function closeCamera(){ buffer&&buffer.getTracks()[1].stop();//关闭摄像头 } window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })(); function screenShot(){ var canvas = document.createElement('canvas'); canvas.width=320,canvas.height = 456; document.querySelector(".wrap").appendChild(canvas); var ctx = canvas.getContext('2d'); function drawVideo(){ ctx.drawImage(oCapture,0,0,320,456); ctx.font = "30px sans-serif"; ctx.fillStyle = "blue"; ctx.fillText("请眨眼", 50, 50); requestAnimationFrame(drawVideo); } window.requestAnimationFrame(drawVideo); } </script> </body> </html>
以上代码并无进行太多的错误处理,好比用户拒绝受权访问摄像头或浏览器不支持等状况,生产环境使用需添加错误处理代码web
以上代码在PC端和Android手机端和微信测试经过,IOS下浏览器均不支持,听说IOS11会开放权限。
注意,以上HTML须要在HTTPS下访问方可正常工做
查看在线DEMO,若是使用微信访问可能被屏蔽,微信打开连接后点击右下角“访问原网页”
如需本地测试请使用Chrome插件:web-server;
webserver使用方法:chrome://apps > web-server > choose folder 勾选 Show Advanced Settings下Set CORS Headers便可
使用input type=”file”调用摄像头拍照能够参考camera APIchrome
补充下,获取vedio的实际尺寸,能够经过:this.videoWidth,this.videoHeight获取。canvas
可用函数浏览器
drawImage(image, x, y) //按原图片大小绘制。 drawImage(image, x, y, width, height) //按指定大小绘制。 drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight) //经常使用于图片裁剪
参数微信
image:所要绘制的图像。这必须是表示 标记或者屏幕外图像的 Image 对象,或者是 Canvas 元素。 x和y:图片在文档中的坐标位置。 width和height:图片的宽高。 对于drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight) 经常使用有图片的裁剪。其参数含义是原来image上从某一个位置开始(sourceX,sourceY),指定长宽进行剪切(sourceX,sourceY),而后将剪切的内容放到位置为(destX,destY),宽度为(destWidth),高度为(destHeight)的位置上,固然裁剪后的会覆盖原来的图片。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>drawImage</title> </head> <body> <canvas id="myCanvas" width="500" height="400"></canvas> <script type="text/javascript"> var canv=document.getElementById("myCanvas"); var ctx = canv.getContext("2d"); img = new Image(); img.src = "2.jpg"; //当图片加载完毕的时候在drawImage,不然可能图片尚未加载完毕 //固然画不上去喽,这就和浏览器的性能有关了。 img.onload=function(){ ctx.drawImage(img,0,0,500,500); //ctx.drawImage(img,0,0,100,100,300,100,100,100); } </script> </body> </html>
除此以外,drawImage()还能够画video,参考连接app