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, 0, 0, 400, 304); 
  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

时间: 2024-09-03 05:57:57

AngularJS中使用HTML5摄像头拍照的相关文章

AngularJS中使用HTML5摄像头拍照应用例子

 项目背景 公司开发一个网站,在做用户头像修改的时候领导提到增加一个由摄像头拍照实现修改头像的功能.因为我们网站是基于Html5进行开发,所以就直接采用H5来实现拍照.起初觉得这个功能很简单,但是做的时候才发现并不是那么简单的. 这是在AngularJs中成功实现调用摄像头拍照并截图上传的例图: 2. 如何调用摄像头 $scope.photoErr = false; $scope.photoBtnDiable = true; var mediaStream = null,track = null

AngularJS中使用HTML5手机摄像头拍照_AngularJS

1. 项目背景 公司开发一个网站,在做用户头像修改的时候领导提到增加一个由摄像头拍照实现修改头像的功能.因为我们网站是基于Html5进行开发,所以就直接采用H5来实现拍照.起初觉得这个功能很简单,但是做的时候才发现并不是那么简单的. 这是在AngularJs中成功实现调用摄像头拍照并截图上传的例图: 2. 如何调用摄像头 $scope.photoErr = false; $scope.photoBtnDiable = true; var mediaStream = null,track = nu

Android 开发随手笔记之使用摄像头拍照_Android

在Android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的Camera,另一种是自己写一个摄像的界面.       我们要添加如下权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> 1.调用系统Camer

Android 开发随手笔记之使用摄像头拍照

在Android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的Camera,另一种是自己写一个摄像的界面. 我们要添加如下权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> 1.调用系统Camera 调用系统

利用html5调用本地摄像头拍照上传图片

原文:利用html5调用本地摄像头拍照上传图片 xmlns="http://www.w3.org/1999/xhtml">    html5概念啥的就不废话了,不知道的 百度, 谷歌一堆..今天学了学html5中的Canvas结合新增的<video>标签来获取本地摄像头,在html5之前,要在浏览器获取本地摄像头只有通过插件(ActiveX,但是这种只有IE支持)或者是flash来获取(或许你没学过flash那就很坑爹了),在之后微软的silvertlight中也可以

Java中利用JMF编写摄像头拍照程序

程序 首先到SUN下载最新的JMF,然后安装.http://java.sun.com/products/java-media/jmf/index.jsp 然后,说一下需求 1. 用摄像头拍照 2. 在文本框输入文件名 3. 按下拍照按钮,获取摄像头内的图像 4. 在拍下的照片上有一红框截取固定大小的照片. 5. 保存为本地图像为jpg格式,不得压缩画质 技术关键,相信也是大家最感兴趣的部分也就是如何让一个摄像头工作,并拍下一张照片了. 利用JMF,代码很简单: //利用这三个类分别获取摄像头驱动

在WPF中使用AForge.net控制摄像头拍照

原文:在WPF中使用AForge.net控制摄像头拍照 利用AForge.net控制摄像头拍照最方便的方法就是利用PictureBox显示摄像头画面,但在WPF中不能直接使用PictureBox.必须通过<WindowsFormsHost></WindowsFormsHost>来提供交换功能.其解决方法如下: 1.按照常规方法新建一个WPF应用程序: 2.添加引用 WindowsFormsIntegration  (与WinForm交互的支持) System.Windows.For

急!怎样在j2ee中实现摄像头拍照上传?

问题描述 哪位知道怎样在j2ee中实现摄像头拍照上传?着急啊! 解决方案 解决方案二:光J2EE做不了这活,因为你需要有本地代码(exe/dll/ocx)来驱动摄像头.解决方案三:该回复于2011-04-29 09:15:29被版主删除解决方案四:拍照后把相片存在相应的位置然后使用文件上传不可以么?解决方案五:该回复于2011-04-29 09:39:40被版主删除解决方案六:该回复于2011-04-29 09:47:03被版主删除解决方案七:该回复于2011-04-29 09:32:45被版主

手机端用HTML5实现拍照上传功能

HTML5实现WAP网站拍照上传功能 做web应用想达到这样的效果: 目前网上发布的教程中,大多数介绍HTML5网页拍照上传都是基于canvas调用摄像头,并转化为数据流进行传输,服务器解码并写入文件.前前后后代码好几百行,影响性能不说,达到的效果也不是我们想要的. 经过分析百度贴吧等网页端的代码,发现实现的技术其实很简单,就是下面这个input: <input type="file" name="pic" id="pic" accept=