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 相关文章推荐
TBCompressor js代码压缩
Jan 05 Javascript
AngularJs bootstrap搭载前台框架——js控制部分
Sep 01 Javascript
JavaScript自定义分页样式
Jan 17 Javascript
jQuery插件FusionWidgets实现的AngularGauge图效果示例【附demo源码】
Mar 23 jQuery
利用JS做网页特效_大图轮播(实例讲解)
Aug 09 Javascript
vue2.0+koa2+mongodb实现注册登录
Apr 10 Javascript
微信小程序自定义可滑动日历界面
Dec 28 Javascript
手把手带你封装一个vue component第三方库
Feb 14 Javascript
微信小程序实现多行文字超出部分省略号显示功能
Oct 23 Javascript
解决vue字符串换行问题(绝对管用)
Aug 06 Javascript
VsCode里的Vue模板的实现
Aug 12 Javascript
javascript实现打砖块小游戏(附完整源码)
Sep 18 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
删除无限分类并同时删除它下面的所有子分类的方法
2010/08/08 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
2013/07/02 PHP
php中用socket模拟http中post或者get提交数据的示例代码
2013/08/08 PHP
PHP使用file_get_content设置头信息的方法
2016/02/14 PHP
Android App中DrawerLayout抽屉效果的菜单编写实例
2016/03/21 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
2019/08/14 PHP
js使用函数绑定技术改变事件处理程序的作用域
2011/12/26 Javascript
jquerymobile局部渲染的各种刷新方法小结
2014/03/05 Javascript
JavaScript利用append添加元素报错的解决方法
2014/07/01 Javascript
PHP 数组current和next用法分享
2015/03/05 Javascript
js实现带有介绍的Select列表菜单实例
2015/08/18 Javascript
js滑动提示效果代码分享
2016/03/10 Javascript
jQuery中的基本选择器用法学习教程
2016/04/14 Javascript
基于WebUploader的文件上传js插件
2016/08/19 Javascript
Javascript动画效果(4)
2016/10/11 Javascript
理解Angular的providers给Http添加默认headers
2017/07/04 Javascript
利用C/C++编写node.js原生模块的方法教程
2017/07/07 Javascript
基于BootStrap multiselect.js实现的下拉框联动效果
2017/07/28 Javascript
vue2.0移除或更改的一些东西(移除index key)
2017/08/28 Javascript
vue2里面ref的具体使用方法
2017/10/27 Javascript
vue 动态绑定背景图片的方法
2018/08/10 Javascript
Element中的Cascader(级联列表)动态加载省\市\区数据的方法
2019/03/27 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
微信小程序视频弹幕发送功能的实现
2020/12/28 Javascript
Python采用socket模拟TCP通讯的实现方法
2014/11/19 Python
利用Python中SocketServer 实现客户端与服务器间非阻塞通信
2016/12/15 Python
Python编写Windows Service服务程序
2018/01/04 Python
Python3实现的简单验证码识别功能示例
2018/05/02 Python
用Python将mysql数据导出成json的方法
2018/08/21 Python
给Python学习者的文件读写指南(含基础与进阶)
2020/01/29 Python
英语专业应届生求职信范文
2013/11/15 职场文书
教你打造完美的创业计划书
2014/01/06 职场文书
会计求职信
2014/05/29 职场文书
党政领导班子群众路线对照检查材料思想汇报
2014/09/27 职场文书
防暑降温通知书
2015/04/27 职场文书
OpenCV-Python模板匹配人眼的实例
2021/06/08 Python