Android应用层语言是java,对于相机、传感器等底层的操作仍旧是低级语言来实现的。java只是做了一层包裹和封装,方便应用层的调用。
Android Framework架构中有两个Camera类
android.hardware.Camera
android.graphics.Camera
android.hardware.Camera
The Camera class is used to set image capture settings, start/stop preview, snap pictures, and retrieve frames for encoding for video. This class is a client for the Camera service, which manages the actual camera hardware.
相机类是用来设置拍照属性,开始/停止预览区,拍照,录制视频。这个类是Camera Service的客户端,真正的相机操作在Camera Service中
如果你要拍照,需要调用底层硬件资源,那么就需要涉及到Android的permission系统。
絮絮叨叨这么多,两句话:相机类是用来拍照和录制视频的,具体实现在Camera Service中。
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
拍照的步骤:
1 Obtain an instance of Camera from open(int). 获得相机的实例
2 Get existing (default) settings with getParameters(). 获得设置属性的对象
3 If necessary, modify the returned Camera.Parameters object and call setParameters(Camera.Parameters). 设置属性
4 If desired, call setDisplayOrientation(int). 设置角度
5 Important: Pass a fully initialized SurfaceHolder to setPreviewDisplay(SurfaceHolder). Without a surface, the camera will be unable to start the preview. 设置预览区
6 Important: Call startPreview() to start updating the preview surface. Preview must be started before you can take a picture.打开预览区
7 When you want, call takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback) to capture a photo. Wait for the callbacks to provide the actual image data. 拍照,等待回调方法返回图片数据
8 After taking a picture, preview display will have stopped. To take more photos, call startPreview() again first.拍照完毕后停下预览,如果需要继续拍照,可以重新调用打开预览的方法。
9 Call stopPreview() to stop updating the preview surface.
10 Important: Call release() to release the camera for use by other applications. Applications should release the camera immediately in onPause() (and re-open() it inonResume()). 释放相机资源
To quickly switch to video recording mode, use these steps: 录制视频
11 Obtain and initialize a Camera and start preview as described above. 首先初始化相机,打开预览区
12 Call unlock() to allow the media process to access the camera. 调用unlock方法将media 和Camera两个进程串起来
13 Pass the camera to setCamera(Camera). See MediaRecorder information about video recording. 把相机设置到MeidaRecorder 中
14 When finished recording, call reconnect() to re-acquire and re-lock the camera. 录制结束后重新设置相机
15 If desired, restart preview and take more photos or videos. 如果想要继续拍照或者录制视频,需要重新打开预览区
16 Call stopPreview() and release() as described above. 像拍照步骤一样,最后需要调用停止预览、释放资源。
http://developer.android.com/guide/topics/media/camera.html 这个链接里的东西也太多了,慢慢消化吧。
1. 注意事项:
(1)配置文件中声明本app需要相机,没有相机的设备请略过
(2)你的应用是想使用相机功能还是重新定制化相机
(3)存储
2. 基本介绍
Android提供了两种访问相机的方式:
(1)intent
(2)相机api
主要涉及四个类:
(1)Camera相机操作类,当你要重新构建相机app时会使用到
(2)SurfaceView相机预览区
(3)MediaRecorder 录像记录
(4)Intent 通过intent的方式(不适用Camera类)调用相机。 MediaStore.ACTION_IMAGE_CAPTURE or MediaStore.ACTION_VIDEO_CAPTURE
3. 配置文件声明
(1)Camera 权限,如果使用intent的方式调用相机,不需要加这个权限。
<uses-permission android:name="android.permission.CAMERA" />
(2)Camera Feature,这个属性从另外方面过滤,在应用市场上显示本app需要带有相机功能的设备
<uses-feature android:name="android.hardware.camera" />
如果相机功能不是必须的可以加上属性:
android:required="false"
(3)存储权限:通常app将照片和视频存在sd卡上,这就需要读写sd卡的权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
(4)录制视频的权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
(5)定位权限,照片中会有位置数据,这样可以方便用户知道照片拍摄的位置,参考 在地图上显示大头针,iPhone的这个用户体验很不错。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
4. 使用已安装的相机apps:通过intent的方式调用相机
这个方式的优点是:代码量少,简单。缺点是因为代码托管到了其他的app(相机),那么本app的控制度降低了。
步骤:
(1)创建一个intent,对应action为:
· MediaStore.ACTION_IMAGE_CAPTURE - Intent action type for requesting an image from an existing camera application.拍照
· MediaStore.ACTION_VIDEO_CAPTURE - Intent action type for requesting a video from an existing camera application.录像
(2)启动相机intent
startActivityForResult()
(3)获得回调数据, onActivityResult(),拍照或录制视频结束后,得到相应的data
4.1 拍照intent
这个方式可以用最少的代码完成拍照的功能,拍照的intent还可以包含其他的一些其他信息
MediaStore.EXTRA_OUTPUT
这个extra值负责制定拍照后照片存放的位置,如果不做任何处理,那么照片将存在默认的位置。
4.2 录制视频的intent
同上,通过intent方式可以用最少的代码量完成,视频录制的功能。录制视频的intent可以包含一些其他信息。
(1)MediaStore.EXTRA_OUTPUT 视频存放的位置
(2)MediaStore.EXTRA_VIDEO_QUALITY 录制视频的品质
(3)MediaStore.EXTRA_DURATION_LIMIT - Set this value to limit the length, in seconds, of the video being captured.限制录制视频的时间 单位s
(4)MediaStore.EXTRA_SIZE_LIMIT - Set this value to limit the file size, in bytes, of the video being captured. 录制视频的大小 单位byte
4.3 获得回调数据
当启动intent拍照或录像结束后,本app需要接受回调的data,这样本app可以对拍的的照片或录制的视频进行操
作。为了得到这样的效果,必须在启动相机的Activity中覆盖onActivityResult()方法。
5. 创建一个自己的相机应用
很多应用定制自己的相机模块,可以给用户带来更好的体验。
开发一个Camera App通常需要以下步骤:
a. 探测和访问硬件
b. 创建预览区
c. 将预览区嵌入布局
d.创建监听器
e.拍照和存储
f.释放相机资源
5.1 检测相机硬件
通常程序需要相机相关的功能会在manifest中进行声明,如果没有声明,可以在程序启动时使用代码进行探测
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
android设备只是多摄像头,在sdk 2.3 中加入了探测摄像头数目的api,Camera.getNumberOfCameras()
使用这个api要谨慎些。查看底层代码,呃...直接进native方法了。
public native static int getNumberOfCamera();
5.2 检测相机的特性:现在有些厂商十分无良,使用标准api获取得到数目是2,这样就准备在页面上增加一个按钮---前置后置摄像头的切换,但是,这个坑货只有一个后置摄像头好不好?
当用户点击完切换按钮后,肯定黑屏了啊!
不同的硬件支持的功能点可能会不一样,使用
Camera.getParameters()
来获取Camera.Parameters
如果使用的是9以上的api版本,使用Camera.getCameraInfo()来确定相机的旋转角度等....很不幸的是:呃,这个值也是不准的
5.3 创建预览区类:
首先预览区是什么?要拍照首先要知道相机看到了什么,这就是预览区的作用。
5.4 创建预览区类
5.5 把预览区嵌入到布局中
5.6 拍照
5.7 录制视频
5.8 释放相机资源
6. 保存多媒体资源
7. 相机特性
7.1 探测特性是否可用
7.2 使用特性
7.3 测光和对焦区域
7.4 人脸检测
7.5 时光推移视频