0
点赞
收藏
分享

微信扫一扫

php调取摄像头实现拍照功能


最近做的商户后台要实现调取摄像头拍摄用户打卡照片的功能,找资料研究了下,终于黄天不负有心人,成功了,下面我分步骤将代码贴出来,希望能有帮助。

代码有点多,但是每一步都很好理解,首先是HTML代码,写一个form表单,到时候上传图片时ajax异步提交,不需要引入别的js,h5有方法能直接调取媒体设备。

不过要注意的是好几个浏览器比如谷歌,QQ,360等因为安全原因,没有HTTPS协议的网站一律认为是不安全的,所以,调取不到,要记得给网站申请HTTPS证书,安装在服务器上。

测试阶段,他们的浏览器默认是关闭的lash和摄像头设备的,打不开,找了各种找入口,就是没有打卡的按钮,最后试了试火狐的,火狐的可以调取,所以建议测试阶段用火狐浏览器开发。

需求:

拍照和照片要在同一个位置,拍完以后视频框显示照片,如果想重拍点击激活摄像头按钮,视频框显示,照片隐藏,再点击拍,拍摄成功,点击上传。

调取成功摄像头,如图下会有进度条的视频框显示:

php调取摄像头实现拍照功能_ide

点击拍照,拍摄成功,左边会显示激活摄像头的按钮,其实不点激活摄像头,不满意接着点拍照,是可以拍的,只不过看不到是什么样的,如图:

php调取摄像头实现拍照功能_ide_02

拍摄完成,点击上传,上传至后台进行数据操作。

样式文件:

.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('编辑失败,请刷新重试!');

}

}

 

举报

相关推荐

0 条评论