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

相关文章
|
5月前
|
存储 JSON JavaScript
详细介绍AngularJS中与HTML DOM交互的各种方法和技术
详细介绍AngularJS中与HTML DOM交互的各种方法和技术
120 0
|
8月前
|
移动开发 HTML5
HTML5 图片上传预览(调用摄像头、文件)demo效果示例(整理)
HTML5 图片上传预览(调用摄像头、文件)demo效果示例(整理)
|
Web App开发
HTML - Video 在使用非 localhost/127.0.0.1 地址访问时打开摄像头失败
HTML - Video 在使用非 localhost/127.0.0.1 地址访问时打开摄像头失败
259 0
|
移动开发 前端开发 HTML5
利用html5调用本地摄像头拍照上传图片
原文:利用html5调用本地摄像头拍照上传图片 xmlns="http://www.w3.org/1999/xhtml">    html5概念啥的就不废话了,不知道的 百度, 谷歌一堆。
1261 0
|
Web App开发 移动开发 JavaScript
HTML5——利用navigator+Video调用摄像头进行录像
                     以前无聊的时候玩儿过HTML5,感觉里面的很多新标签确实深深震撼了我额。。。。        今天需求那边要做这样一个功能,在微信里面调用摄像头进行拍摄,然后上传。
1509 0
|
JavaScript 前端开发
模仿angularjs写了一个简单的HTML模版和js数据填充的示例
//框架代码 $(function () { $("[up-ctl]").
794 0
|
Web App开发 移动开发 JavaScript
使用HTML5拍照
原文连接地址: Camera and Video Control with HTML5  演示地址: HTML5拍照演示  翻译日期: 2013年8月6日 首先,我们看看HTML代码结构,当然,这部分的DOM内容应该是在用户允许使用其摄像头事件出发后,动态加载生成的。
771 0
|
JavaScript 前端开发