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 相关文章推荐
javascript 计算两个整数的百分比值
Dec 26 Javascript
利用JQuery的load函数动态加载其它页面的内容的实现代码
Dec 14 Javascript
JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)
Oct 16 Javascript
jQuery实现图片加载完成后改变图片大小的方法
Mar 29 Javascript
浅谈JS运算符&&和|| 及其优先级
Aug 10 Javascript
BootStrap整体框架之基础布局组件
Dec 15 Javascript
关于jquery form表单序列化的注意事项详解
Aug 01 jQuery
vue.js简单配置axios的方法详解
Dec 13 Javascript
微信小程序分享功能之按钮button 边框隐藏和点击隐藏
Jun 14 Javascript
使用konva和vue-konva库实现拖拽滑块验证功能
Apr 27 Javascript
Vue插槽_特殊特性slot,slot-scope与指令v-slot说明
Sep 04 Javascript
ant design的table组件实现全选功能以及自定义分页
Nov 17 Javascript
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获取redis里不存在的6位随机数应用示例【设置24小时过时】
2017/06/07 PHP
PDO::errorInfo讲解
2019/01/28 PHP
jQuery.prototype.init选择器构造函数源码思路分析
2013/02/05 Javascript
js统计页面的来访次数实现代码
2014/05/09 Javascript
JavaScript获取当前网页最后修改时间的方法
2015/04/03 Javascript
JS自定义混合Mixin函数示例
2016/11/26 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
2016/12/26 Javascript
利用jQuery解析获取JSON数据
2017/04/08 jQuery
uploader秒传图片到服务器完整代码
2017/04/22 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
2017/11/29 Javascript
基于dataset的使用和图片延时加载的实现方法
2017/12/11 Javascript
Webpack中雪碧图插件使用详解
2018/05/25 Javascript
微信小程序用canvas画图并分享
2020/03/09 Javascript
可拖拽组件slider.js使用方法详解
2020/12/04 Javascript
Python写的创建文件夹自定义函数mkdir()
2014/08/25 Python
python 类详解及简单实例
2017/03/24 Python
在python3环境下的Django中使用MySQL数据库的实例
2017/08/29 Python
Python通过paramiko远程下载Linux服务器上的文件实例
2018/12/27 Python
pycharm new project变成灰色的解决方法
2019/06/27 Python
tensorflow生成多个tfrecord文件实例
2020/02/17 Python
python中matplotlib实现随鼠标滑动自动标注代码
2020/04/23 Python
python获取本周、上周、本月、上月及本季的时间代码实例
2020/09/08 Python
Myprotein俄罗斯官网:欧洲第一运动营养品牌
2019/05/05 全球购物
C,C++的几个面试题小集
2013/07/13 面试题
介绍一下gcc特性
2012/01/20 面试题
应届毕业生求职信范文分享
2013/12/26 职场文书
公司培训欢迎词
2014/01/10 职场文书
葬礼司仪主持词
2014/03/31 职场文书
《分一分》教学反思
2014/04/13 职场文书
绿色环保演讲稿
2014/05/10 职场文书
低碳环保口号
2014/06/12 职场文书
反腐倡廉标语
2014/06/24 职场文书
开展创先争优活动总结
2014/08/28 职场文书
业绩倒数第一的检讨书
2014/09/24 职场文书
《异世界四重奏》剧场版6月10日上映 PV视觉图原创角色发表
2022/03/20 日漫
windows server2016安装oracle 11g的图文教程
2022/07/15 Servers