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 相关文章推荐
破解Session cookie的方法
Jul 28 Javascript
showModelessDialog()使用详解
Sep 07 Javascript
In Javascript Class, how to call the prototype method.(three method)
Jan 09 Javascript
Mootools 1.2教程 类(一)
Sep 15 Javascript
setTimeout()递归调用不加引号出错的解决方法
Sep 05 Javascript
5个JavaScript经典面试题
Oct 13 Javascript
node-webkit打包成exe文件被360误报木马的解决方法
Mar 11 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
Apr 13 Javascript
JavaScript设计模式之策略模式详解
Jun 09 Javascript
基于AngularJS的拖拽文件上传的实例代码
Jul 15 Javascript
vue.js项目打包上线的图文教程
Nov 16 Javascript
解决Echarts 显示隐藏后宽度高度变小的问题
Jul 19 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
Session的工作方式
2006/10/09 PHP
php设计模式 Adapter(适配器模式)
2011/06/26 PHP
php笔记之:php函数range() round()和list()的使用说明
2013/04/26 PHP
php通过Chianz.com获取IP地址与地区的方法
2015/01/14 PHP
Linux(CentOS)下PHP扩展PDO编译安装的方法
2016/04/07 PHP
Yii2中使用join、joinwith多表关联查询
2016/06/30 PHP
javascript学习笔记(五) Array 数组类型介绍
2012/06/19 Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
2012/10/11 Javascript
在jQuery中 关于json空对象筛选替换
2013/04/15 Javascript
JavaScript获取图片像素颜色并转换为box-shadow显示
2016/03/11 Javascript
AngularJs  unit-testing(单元测试)详解
2016/09/02 Javascript
基于javascript实现最简单选项卡切换
2017/02/01 Javascript
详解Vue中使用v-for语句抛出错误的解决方案
2017/05/04 Javascript
JavaScript事件发布/订阅模式原理与用法分析
2018/08/21 Javascript
vue组件(全局,局部,动态加载组件)
2018/09/02 Javascript
[53:38]OG vs LGD 2018国际邀请赛淘汰赛BO3 第三场 8.26
2018/08/30 DOTA
[01:07:19]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第一场 1月19日
2021/03/11 DOTA
在Python中操作列表之List.append()方法的使用
2015/05/20 Python
python3.4下django集成使用xadmin后台的方法
2017/08/15 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
python opencv实现gif图片分解的示例代码
2019/12/13 Python
python 实现图片批量压缩的示例
2020/12/18 Python
一款纯css3实现的鼠标经过按钮特效教程
2014/11/09 HTML / CSS
澳大利亚运动鞋零售商:The Athlete’s Foot
2018/11/04 全球购物
韩国演唱会订票网站:StubHub韩国
2019/01/17 全球购物
在c#中using和new这两个关键字有什么意义
2013/05/19 面试题
运动会表扬稿大全
2014/01/16 职场文书
德语专业求职信
2014/03/12 职场文书
幼儿园课题方案
2014/06/09 职场文书
2015大学自主招生自荐信范文
2015/03/04 职场文书
学校会议通知范文
2015/04/15 职场文书
生日赠语
2015/06/23 职场文书
企业宣传语大全
2015/07/13 职场文书
四十年同学聚会致辞
2015/07/28 职场文书
JavaScript 中for/of,for/in 的详细介绍
2021/11/17 Javascript
使用ICOM IC-R9500接收机同时测评十台收音机中波接收性能
2022/05/10 无线电