AngularJS中使用HTML5摄像头拍照

简介:

1. 项目背景

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

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

2. 如何调用摄像头

 
  1. $scope.photoErr = false
  2. $scope.photoBtnDiable = true
  3. var mediaStream = null,track = null
  4.  
  5. navigator.getMedia = (navigator.getUserMedia || 
  6.                       navigator.webkitGetUserMedia || navigator.mozGetUserMedia || 
  7.                       navigator.msGetUserMedia); 
  8.         if (navigator.getMedia) { 
  9.             navigator.getMedia( 
  10.            { 
  11.                video: true 
  12.            }, 
  13.            // successCallback 
  14.            function (stream) { 
  15.                var s = window.URL.createObjectURL(stream); 
  16.                var video = document.getElementById('video'); 
  17.                video.src = window.URL.createObjectURL(stream); 
  18.                mediaStream = stream; 
  19.                track = stream.getTracks()[0]; 
  20.                $scope.photoBtnDiable = false;               $scope.$apply(); 
  21.            }, 
  22.            // errorCallback 
  23.            function (err) { 
  24.                $scope.errorPhoto(); 
  25.                console.log("The following error occured:" + err); 
  26.            }); 
  27.               } else { 
  28.             $scope.errorPhoto(); 
  29.         } 

代码解析:

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

 
  1.       video: true, 
  2.       audio: true 

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

3. 拍照

 
  1. $scope.snap = function () { 
  2.         var canvas = document.createElement('canvas'); 
  3.             canvas.width = "400"
  4.             canvas.height = "304"
  5.  
  6.             var ctx = canvas.getContext('2d'); 
  7.             ctx.drawImage(video, 00400304); 
  8.             $scope.closeCamera(); 
  9.             $uibModalInstance.close(canvas.toDataURL("image/png")); 
  10. }; 

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

4. 如何关闭摄像头

 
  1. $scope.closeCamera = function () { 
  2.             if (mediaStream != null) { 
  3.                 if (mediaStream.stop) { 
  4.                     mediaStream.stop(); 
  5.                 } 
  6.                 $scope.videosrc = ""
  7.             } 
  8.             if (track != null) { 
  9.                 if (track.stop) { 
  10.                     track.stop(); 
  11.                 } 
  12.             } 
  13.         } 

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

5. 集成到AndularJs

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

 
  1. service注册: 
  2.  
  3. app().registerService("h5TakePhotoService", function ($q, $uibModal) { 
  4.  
  5.         this.photo = function () { 
  6.             var deferred = $q.defer(); 
  7.             require([config.server + "/com/controllers/photo.js"], function () { 
  8.                 $uibModal.open({ 
  9.                     templateUrl: config.server + "/com/views/modal_take_photo.html"
  10.                     controller: "photoModalController"
  11.                     windowClass: "modal-photo" 
  12.                 }).result.then(function (e) { 
  13.                     deferred.resolve(e); 
  14.                 }); 
  15.             }); 
  16.             return deferred.promise; 
  17.         } 
  18.  
  19.     }); 

调用方式:

 
  1. $scope.takePhoto = function () { 
  2.       h5TakePhotoService.photo().then(function (res) { 
  3.            if (res != null && res != "") { 
  4.                $scope.myImage = res; 
  5.            } 
  6.       }); 

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

6. 兼容问题

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

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


作者:杨勇

来源:51CTO

相关文章
|
移动开发 前端开发 HTML5
利用html5调用本地摄像头拍照上传图片
原文:利用html5调用本地摄像头拍照上传图片 xmlns="http://www.w3.org/1999/xhtml">    html5概念啥的就不废话了,不知道的 百度, 谷歌一堆。
1248 0
|
移动开发 前端开发 HTML5
html5调用摄像头实现拍照
<p>技术时刻都在前进着。我们的需求也是时刻在改变着。最近在开发中遇到了用户进行账号注册时需要个人图像,网站提供自动拍照功能。还有在登录了PC之后,手机端进行登录时只需要扫描一下PC上的二维码就可以登录。这对一个网络来说难度是极大的。</p> <p>技术的进步使我们遇到了html5。下面这个简单粗暴的demo就是来完成这些功能的。直接看代码:</p> <pre code_snippet_
2897 0
|
Web App开发 移动开发 JavaScript
使用HTML5拍照
原文连接地址: Camera and Video Control with HTML5  演示地址: HTML5拍照演示  翻译日期: 2013年8月6日 首先,我们看看HTML代码结构,当然,这部分的DOM内容应该是在用户允许使用其摄像头事件出发后,动态加载生成的。
765 0
|
1天前
|
移动开发 前端开发 JavaScript
[HTML、CSS]知识点
[HTML、CSS]知识点
25 0
[HTML、CSS]知识点
|
1天前
|
移动开发 前端开发 JavaScript
[HTML、CSS]细节、经验
[HTML、CSS]细节、经验
25 0
[HTML、CSS]细节、经验
|
13天前
|
移动开发 前端开发 JavaScript
H5+CSS3+JS逆向前置——HTML2、table表格标签
H5+CSS3+JS逆向前置——HTML2、table表格标签
14 0
|
15天前
|
前端开发 JavaScript UED
动态伸缩搜索框:HTML, CSS, JavaScript的完美结合
动态伸缩搜索框:HTML, CSS, JavaScript的完美结合
23 1
|
18天前
|
监控 前端开发 JavaScript
局域网远程管理软件的图形化界面设计(使用HTML/CSS)
在现代企业和组织中,局域网远程管理软件发挥着至关重要的作用。为了更好地实现对局域网内设备的远程管理,图形化界面设计显得尤为重要。本文将探讨如何使用HTML和CSS创建一种直观而功能强大的远程管理软件界面。
67 0

热门文章

最新文章

相关产品

  • 云迁移中心