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 原型模式实现OOP的再研究
Apr 09 Javascript
Jquery之Ajax运用 学习运用篇
Sep 26 Javascript
jQuery简单实现网页选项卡特效
Nov 24 Javascript
jquery实现浮动在网页右下角的彩票开奖公告窗口代码
Sep 04 Javascript
JS结合bootstrap实现基本的增删改查功能
Jul 22 Javascript
详解用vue-cli来搭建vue项目和webpack
Apr 20 Javascript
微信小程序 es6-promise.js封装请求与处理异步进程
Jun 12 Javascript
Vue写一个简单的倒计时按钮功能
Apr 20 Javascript
Vue封装的组件全局注册并引用
Jul 24 Javascript
Centos7 安装Node.js10以上版本的方法步骤
Oct 15 Javascript
解决vue自定义全局消息框组件问题
Nov 22 Javascript
详解ES6实现类的私有变量的几种写法
Feb 10 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学习之正则表达式
2011/04/17 PHP
解析php获取字符串的编码格式的方法(函数)
2013/06/21 PHP
jQuery+PHP+ajax实现微博加载更多内容列表功能
2014/06/27 PHP
php中的登陆login实例代码
2016/06/20 PHP
js判断游览器类型及版本号的代码
2014/05/11 Javascript
使用原生JS实现弹出层特效
2014/12/22 Javascript
wangEditor编辑器失去焦点后仍然可以在原位置插入图片分析
2015/05/06 Javascript
实用又漂亮的BootstrapValidator表单验证插件
2016/05/30 Javascript
JavaScript学习笔记--常用的互动方法
2016/12/07 Javascript
vue时间格式化实例代码
2017/06/13 Javascript
vue中如何使用ztree
2018/02/06 Javascript
JavaScript 判断对象中是否有某属性的常用方法
2018/06/14 Javascript
浅谈ElementUI中switch回调函数change的参数问题
2018/08/24 Javascript
JavaScript中var的重要性实例分析
2019/07/09 Javascript
解决vue 子组件修改父组件传来的props值报错问题
2019/11/09 Javascript
vue实现商城秒杀倒计时功能
2019/12/12 Javascript
[00:47]DOTA2荣耀之路6:天火,天火!
2018/05/30 DOTA
Python实现把json格式转换成文本或sql文件
2015/07/10 Python
初步剖析C语言编程中的结构体
2016/01/16 Python
python+pandas分析nginx日志的实例
2018/04/28 Python
python解决字符串倒序输出的问题
2018/06/25 Python
Python批处理删除和重命名文件夹的实例
2018/07/11 Python
Python 访问限制 private public的详细介绍
2018/10/16 Python
python3使用matplotlib绘制条形图
2020/03/25 Python
python的pytest框架之命令行参数详解(下)
2019/06/27 Python
ERLANG和PYTHON互通实现过程详解
2019/07/05 Python
python 计算概率密度、累计分布、逆函数的例子
2020/02/25 Python
Python startswith()和endswith() 方法原理解析
2020/04/28 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
2020/11/27 Python
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
学生打架检讨书1000字
2014/01/16 职场文书
2015年教务工作总结
2015/05/23 职场文书
2016校本研修培训心得体会
2016/01/08 职场文书
python批量更改目录名/文件名的方法
2021/04/18 Python
MySQL分库分表与分区的入门指南
2021/04/22 MySQL
springboot如何接收application/x-www-form-urlencoded类型的请求
2021/11/02 Java/Android