AngularJS中使用HTML5手机摄像头拍照


Posted in Javascript onFebruary 22, 2016

1. 项目背景

公司开发一个网站,在做用户头像修改的时候领导提到增加一个由摄像头拍照实现修改头像的功能。因为我们网站是基于Html5进行开发,所以就直接采用H5来实现拍照。起初觉得这个功能很简单,但是做的时候才发现并不是那么简单的。

AngularJS中使用HTML5手机摄像头拍照

这是在AngularJs中成功实现调用摄像头拍照并截图上传的例图:

AngularJS中使用HTML5手机摄像头拍照

AngularJS中使用HTML5手机摄像头拍照

2. 如何调用摄像头

$scope.photoErr = false;
$scope.photoBtnDiable = true;
var mediaStream = null,track = null;

navigator.getMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
if (navigator.getMedia) {
navigator.getMedia(
{
video: true
},
// successCallback
function (stream) {
var s = window.URL.createObjectURL(stream);
var video = document.getElementById('video');
video.src = window.URL.createObjectURL(stream);
mediaStream = stream;
track = stream.getTracks()[0];
$scope.photoBtnDiable = false; $scope.$apply();
},
// errorCallback
function (err) {
$scope.errorPhoto();
console.log("The following error occured:" + err);
});
} else {
$scope.errorPhoto();
}

代码解析:

navigator为浏览器对象,包含浏览器的信息,这里就是用这个对象打开摄像头。$scope为AndularJs语法。第一步声明navigator.getMedia来调用浏览器不同的打开摄像头函数,目前仅有getUserMedia、webkitGetUserMedia、mozGetUserMedia、msGetUserMedia四种方式分别对应通用浏览器、Google浏览器、火狐浏览器和IE浏览器,浏览器会自动判断调用哪一个函数。第二步是调用打开浏览器,包含三个参数,分别为需要使用的多媒体类型、获取成功返回的流数据处理函数以及操作失败返回错误消息处理函数。其中,使用时不仅可以设置视频还能设置使用麦克风,设置方式为:

{
video: true,
audio: true
}

调用成功即打开摄像头后返回视频流数据,我们可以将流数据设置到video标签在界面上实时显示图像。mediaStream用来记录获取到的流数据,track在Chrome浏览器中用来跟踪摄像头状态,这两个变量都能用来关闭摄像头。

3. 拍照

$scope.snap = function () {
var canvas = document.createElement('canvas');
canvas.width = "400";
canvas.height = "304";

var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, 400, 304);
$scope.closeCamera();
$uibModalInstance.close(canvas.toDataURL("image/png"));
};

拍照时需要使用到canvas标签,创建一个canvas标签,设置我们需要拍照的尺寸大小,通过drawImage函数将video当前的图像保存到canvas标签,最后将图像数据转换为base64数据返回并关闭摄像头,这样就完成了我们的拍照功能。这里的$uibModalInstance对象是我们项目中打开弹出层的一个对象,用来控制弹出层的显示。

4. 如何关闭摄像头

$scope.closeCamera = function () {
if (mediaStream != null) {
if (mediaStream.stop) {
mediaStream.stop();
}
$scope.videosrc = "";
}
if (track != null) {
if (track.stop) {
track.stop();
}
}
}

正如前面所说,关闭摄像头的方式是通过mediaStream和track变量,只不过,track只能关闭Chrome浏览器中的摄像头,这也是Chrome 45版本以上关闭摄像头的方式。

5. 集成到AndularJs

事实上,前面所说的都是在AndularJs中实现的,当然,这里只是实现了拍照并返回拍照数据,我们想要在其他地方也使用,就需要将这部分独立出来,这里我们用到了AngularJs中的service机制,将这部分单独做成一个service并在项目中注入,然后就可以在其他地方调用了。

service注册:

app().registerService("h5TakePhotoService", function ($q, $uibModal) {

this.photo = function () {
var deferred = $q.defer();
require([config.server + "/com/controllers/photo.js"], function () {
$uibModal.open({
templateUrl: config.server + "/com/views/modal_take_photo.html",
controller: "photoModalController",
windowClass: "modal-photo"
}).result.then(function (e) {
deferred.resolve(e);
});
});
return deferred.promise;
}
});

调用方式:

$scope.takePhoto = function () {
h5TakePhotoService.photo().then(function (res) {
if (res != null && res != "") {
$scope.myImage = res;
}
});
}

h5TakePhotoService为控制器中注入的拍照service对象,最后处理返回的图像数据,设置数据显示到界面上。

6. 兼容问题

主要存在Chrome浏览器中,本地测试时,Chrome浏览器中能够正常使用,但是部署到服务器后就不能正常使用,报错消息为 [object NavigatorUserMediaError],这是因为Chrome浏览器在使用摄像头时只支持安全源访问,所以只能通过https访问才能正常使用。

最后需要说一下,测试时只能通过http://url访问才能使用,不能通过file://url方式访问,即我们需要将代码部署才能访问,可以在Visual Studio、 java web、php中完成。

以上所述是小编给大家介绍的AngularJS中使用HTML5手机摄像头拍照的相关知识,希望对大家有所帮助!

Javascript 相关文章推荐
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
Dec 02 Javascript
ExtJS如何设置与获取radio控件的选取状态
Jan 22 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
Mar 10 Javascript
AspNet中使用JQuery上传插件Uploadify详解
May 20 Javascript
jquery ui sortable拖拽后保存位置
Apr 27 jQuery
jQuery实现的简单动态添加、删除表格功能示例
Sep 21 jQuery
基于vue实现可搜索下拉框定制组件
Mar 26 Javascript
js实现左右两侧浮动广告
Jul 09 Javascript
element-ui循环显示radio控件信息的方法
Aug 24 Javascript
javascript实现前端成语点击验证优化
Jun 24 Javascript
浅析vue中的nextTick
Dec 28 Vue.js
vue el-table实现递归嵌套的示例代码
Aug 14 Vue.js
JS字符串的切分用法实例
Feb 22 #Javascript
JS实现上下左右对称的九九乘法表
Feb 22 #Javascript
基于Javascript实现倒计时功能
Feb 22 #Javascript
TypeOf这些知识点你了解吗
Feb 21 #Javascript
详谈javascript异步编程
Feb 21 #Javascript
浅谈javascript的call()、apply()、bind()的用法
Feb 21 #Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
Feb 21 #Javascript
You might like
php+oracle 分页类
2006/10/09 PHP
深入Memcache的Session数据的多服务器共享详解
2013/06/13 PHP
不使用php api函数实现数组的交换排序示例
2014/04/13 PHP
PHP实现在线阅读PDF文件的方法
2015/06/23 PHP
yii2 页面底部加载css和js的技巧
2016/04/21 PHP
确保Laravel网站不会被嵌入到其他站点中的方法
2019/10/18 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
event.keyCode键码值表 附只能输入特定的字符串代码
2009/05/15 Javascript
分享一个asp.net pager分页控件
2012/01/04 Javascript
50款非常棒的 jQuery 插件分享
2012/03/29 Javascript
jquery封装的对话框简单实现
2013/07/21 Javascript
jquery对table中各数据的增加、保存、删除操作示例
2014/05/14 Javascript
JavaScript声明变量时为什么要加var关键字
2014/09/29 Javascript
JS如何设置cookie有效期为当天24点并弹出欢迎登陆界面
2016/08/04 Javascript
socket.io实现在线群聊功能
2017/04/07 Javascript
vue如何集成raphael.js中国地图的方法示例
2017/08/15 Javascript
使用Nodejs连接mongodb数据库的实现代码
2017/08/21 NodeJs
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
2017/11/10 jQuery
layui之select的option叠加问题的解决方法
2018/03/08 Javascript
JS简单获取并修改input文本框内容的方法示例
2018/04/08 Javascript
nodejs中函数的调用实例详解
2018/10/31 NodeJs
微信小程序实现获取用户信息并存入数据库操作示例
2019/05/07 Javascript
vue中 数字相加为字串转化为数值的例子
2019/11/07 Javascript
js中关于Blob对象的介绍与使用
2019/11/29 Javascript
[00:44]TI7不朽珍藏III——军团指挥官不朽展示
2017/07/15 DOTA
[00:13]天涯墨客二技能展示
2018/08/25 DOTA
Windows下实现Python2和Python3两个版共存的方法
2015/06/12 Python
python使用matplotlib绘制柱状图教程
2017/02/08 Python
解决python opencv无法显示图片的问题
2018/10/28 Python
python正则表达式匹配[]中间为任意字符的实例
2018/12/25 Python
opencv实现简单人脸识别
2021/02/19 Python
python mysql自增字段AUTO_INCREMENT值的修改方式
2020/05/18 Python
python代码实现将列表中重复元素之间的内容全部滤除
2020/05/22 Python
机械绘图员岗位职责
2013/11/19 职场文书
祖国在我心中演讲稿300字
2014/05/04 职场文书
Mysql systemctl start mysqld报错的问题解决
2021/06/03 MySQL