首页 > 编程语言 >php调取摄像头实现拍照功能

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

时间:2022-11-25 12:34:46浏览次数:42  
标签:function canvas image display video error php 调取 摄像头


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

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

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

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

需求:

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

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

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

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

php调取摄像头实现拍照功能_上传_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('编辑失败,请刷新重试!');

}

}

 

标签:function,canvas,image,display,video,error,php,调取,摄像头
From: https://blog.51cto.com/u_13940603/5886337

相关文章

  • 四种PHP异步执行的常用方式
    客户端与服务器端是通过HTTP协议进行连接通讯,客户端发起请求,服务器端接收到请求后执行处理,并返回处理结果。有时服务器需要执行很耗时的操作,这个操作的结果并不需要返回给客......
  • php与Redis实现一个100万用户的投票项目,实现实时查看投票情况?
    微信分享里总是有一些亲子活动,或者参加某些大赛需要进行投票,而面向的是所有人都可以参与,或者有限制一个人每天能投票同一个参与者3票之类的。。。这些应用场景有很多。假如......
  • PHP操作Redis
    redis的基本操作方法1.redis的连接://实例化redis$redis=newRedis();//连接$redis->connect('127.0.0.1',6379);//检测是否连接成功echo"Serverisrunning:".$r......
  • PHP处理 字符串个数(压缩处理)方法
    不说了,都是泪,直接上代码...$str='aaabbccqqwwe';//字符串示例$strRecord=[];//把出现过的字符记录在此数组中,如果记录有,则不记录,$new_str='';//最后......
  • PHP闭包之变量作用域
    在项目中,难免会遇到闭包的形式,那么在闭包中,变量的作用域到底是怎么样的呢。下面有几个简单的例子。functiontest_1(){$a='php';$func=function($b)use($a)......
  • php运用无限级分类实现评论及回复功能
    经常在各大论坛或新闻板块详情页面下边看到评论功能,当然不单单是直接发表评论内容那么简单,可以对别人的评论进行回复,别人又可以对你的回复再次评论或回复,如此反复,理论上可以......
  • PHP+Redis实现分页
    废话少说,上代码吧<?phpclassRedisPage{protected$_redis;protected$_redis_ip;protected$_redis_port;protected$_redis_db;protected$_has......
  • PHP文件日志记录
    <?php/***@notes:Logging*@auther:BinShi*@dateTime:2020/05/1317:44*/classLogging{/***进程唯一ID**@varstring*/priva......
  • 安装php环境
    环境:192.168.11.20PHP(主机名)PHP节点关闭防火墙配置好yum源用centos7.5-1804(1)安装配置基础服务[[email protected]]#yuminstall-ygccgcc-c++libxml2-......
  • 安装php7.2
    #方法一:rpm-Uvhhttps://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpmrpm-Uvhhttps://mirror.webtatic.com/yum/el7/webtatic-release.rpm#......