最近做的商户后台要实现调取摄像头拍摄用户打卡照片的功能,找资料研究了下,终于黄天不负有心人,成功了,下面我分步骤将代码贴出来,希望能有帮助。
代码有点多,但是每一步都很好理解,首先是html代码,写一个form表单,到时候上传图片时ajax异步提交,不需要引入别的js,h5有方法能直接调取媒体设备。
不过要注意的是好几个浏览器比如谷歌,qq,360等因为安全原因,没有https协议的网站一律认为是不安全的,所以,调取不到,要记得给网站申请https证书,安装在服务器上
测试阶段,他们的浏览器默认是关闭的lash和摄像头设备的,打不开,找了各种找入口,就是没有打卡的按钮,最后试了试火狐的,火狐的可以调取,所以建议测试阶段用火狐浏览器开发
需求:
拍照和照片要在同一个位置,拍完以后视频框显示照片,如果想重拍点击激活摄像头按钮,视频框显示,照片隐藏,再点击拍,拍摄成功,点击上传。
调取成功摄像头,如图下会有进度条的视频框显示:
点击拍照,拍摄成功,左边会显示激活摄像头的按钮,其实不点激活摄像头,不满意接着点拍照,是可以拍的,只不过看不到是什么样的,如图:
拍摄完成,点击上传,上传至后台进行数据操作。
样式文件:
.coach-price{display: none}.input-but{display: inline-flex;}#canvas{display: none}#showvideo{display: none}#input-picture{width:100%;}html代码:<div class="ibox float-e-margins"> <div class="ibox-title"> <h5>打卡头像</h5> </div> <div class="ibox-content img-content"> <form class="form-horizontal m-t" id="uppictureform" method="post" action=""> <div class="form-group " id="input-picture"> <div class="img-box" id="results"> <input name="image_code" id="image_code" type="hidden" value=""/> <input name="userid" class="userid" type="hidden" value=""/> //这是一个画布的容器 <canvas id="canvas" width="300" height="260"></canvas> </div> </div> <div class="form-group "> //要拍照的视频框 <video id="video" controls> </video> </div> <div class="form-group "> //各种按钮 <div class="input-but"> <button type="button" class="layui-btn" id="showvideo"> 激活摄像头 </button> <button type="button" class="layui-btn" id="capture"> <i class="layui-icon"></i>拍照 </button> <button type="button" id="uppicture" class="layui-btn" > <i class="layui-icon"></i>上传 </button> </div> </div> </form> </div></div>
js代码:
<script> //访问用户媒体设备的兼容方法 function getusermedia(constraints, success, error) { if (navigator.mediadevices.getusermedia) { //最新的标准api navigator.mediadevices.getusermedia(constraints).then(success).catch(error); } else if (navigator.webkitgetusermedia) { //webkit核心浏览器 navigator.webkitgetusermedia(constraints,success, error) } else if (navigator.mozgetusermedia) { //firfox浏览器 navigator.mozgetusermedia(constraints, success, error); } else if (navigator.getusermedia) { //旧版api navigator.getusermedia(constraints, success, error); } } function success(stream) { //兼容webkit核心浏览器 let compatibleurl = window.url || window.webkiturl; //将视频流设置为video元素的源 console.log(stream); //video.src = compatibleurl.createobjecturl(stream); video.srcobject = stream; video.play(); } function error(error) { alert(`访问用户摄像头失败${error.name}, ${error.message}`); } //从 canvas 提取图片 image function convertcanvastoimage(canvas) { //新image对象,可以理解为dom var image = new image(); // canvas.todataurl 返回的是一串base64编码的url // 指定格式 png image.src = canvas.todataurl("image/png"); return image; } function getnavigator() { if (navigator.mediadevices.getusermedia || navigator.getusermedia || navigator.webkitgetusermedia || navigator.mozgetusermedia) { //获取video宽高 var v_height,v_width; var myvobj = document.getelementbyid("video"); myvobj.addeventlistener("loadedmetadata", function () { v_height = this.videoheight; v_width =this.videowidth; $('#canvas').attr('width',v_width); $('#canvas').attr('height',v_height); }); //调用用户媒体设备, 访问摄像头 getusermedia({video : {width: 320, height: 240}}, success, error); } else { alert('不支持访问用户媒体'); } } getnavigator(); function showvideo(){ $('#results').find('img').remove(); $('#canvas').css('display','none'); $('#video').css('display','block'); $('#showvideo').css('display','none'); getnavigator(); } function showpicture(picture) { if($('#results').find('img').attr('src')){ $('#results').find('img').attr('src',picture); }else{ $('#results').append('<img src="'+picture+'"/>'); } $('#video').css('display','none'); $('#canvas').css('display','none'); $('#showvideo').show(); $('.picture').val(1); } function hidepicture() { $('#results').find('img').remove(); getnavigator(); $('#video').css('display','block'); $('#canvas').css('display','none'); $('#showvideo').css('display','none'); } $('#showvideo').click(function () { showvideo(); }); document.getelementbyid('capture').addeventlistener('click', function () { let video = document.getelementbyid('video'); let canvas = document.getelementbyid('canvas'); let context = canvas.getcontext('2d'); context.drawimage(video, 0, 0); //获取网页中的canvas对象 var mycans=$('canvas')[0]; //调用convertcanvastoimage函数将canvas转化为img形式 var img=convertcanvastoimage(mycans); if(img.src){ $('#results').find('#image_code').val(img.src); // $('#capture').text('修改'); $('#video').css('display','none'); $('#canvas').css('display','block'); $('#showvideo').show(); } })//点击图片上传按钮$('#uppicture').click(function () { var userid = $('.userid').val(); var image_code = $('#image_code').val();//图片值 if(!userid){ alert('用户不存在');return; } if(!image_code){ alert('请先拍照');return; } $.post("{:url('uppicture')}", {'userid':userid,'image_code':image_code}, function(res){ // console.log(res); if(1 == res.code){ layer.alert(res.msg, {title: '友情提示', icon: 1}); $('.picture').val(1); }else{ layer.alert(res.msg, {title: '友情提示', icon: 2}); } });});</script>
提交后台,php进行处理,用的框架是tp5的,所以后面返回的时候直接用的tp的success和error,很方便,它的第一个参数是msg,第二个是url,第三个是data。
public function uppicture(){ $image_code = input('image_code'); if(empty($image_code)){ $this ->error('照片为空'); } $uid = input('userid'); //处理接收过来的图片 $img = str_replace('data:image/png;base64,', '', $image_code); $img = str_replace(' ', '+', $img); $data = base64_decode($img); // 图片名称 $file_name = "./uploads/head/".time().".png"; $fp = fopen($file_name, 'w'); fwrite($fp, $data); fclose($fp); $array = array( "picture" => substr($file_name,1) ); $res = db::table("table")->where("userid",$uid)->setfield($array); if($res){ $this ->success('编辑成功!'); }else{ $this ->error('编辑失败,请刷新重试!'); } }
相关推荐:《php教程》
以上就是php调取摄像头实现拍照功能的方法的详细内容。