博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AngularJS中使用HTML5摄像头拍照
阅读量:6331 次
发布时间:2019-06-22

本文共 3165 字,大约阅读时间需要 10 分钟。

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

转载地址:http://lrboa.baihongyu.com/

你可能感兴趣的文章
jdbcTemplate 调用存储过程。 入参 array 返回 cursor
查看>>
C++中的stack类、QT中的QStack类
查看>>
Linux常用基本命令[cp]
查看>>
CSS 相对|绝对(relative/absolute)定位系列(一)
查看>>
关于 Nginx 配置 WebSocket 400 问题
查看>>
Glide和Govendor安装和使用
查看>>
Java全角、半角字符的关系以及转换
查看>>
Dubbo和Zookeeper
查看>>
前端项目课程3 jquery1.8.3到1.11.1有了哪些新改变
查看>>
UOJ#179. 线性规划(线性规划)
查看>>
整合spring cloud云架构 - SSO单点登录之OAuth2.0登录认证(1)
查看>>
Isolation Forest原理总结
查看>>
windows的服务中的登录身份本地系统账户、本地服务账户和网络服务账户修改
查看>>
JAVA中循环删除list中元素的方法总结
查看>>
redis 安装
查看>>
SQL some any all
查看>>
电子书下载:Programming Windows Identity Foundation
查看>>
有理想的程序员必须知道的15件事
查看>>
用于测试的字符串
查看>>
财付通和支付宝资料收集
查看>>