1. 设置摄像头方向
2. 打开线程与预览线程
3. 设置参数
4. Camera外设按键
5. 自动对焦与触摸对焦
6. 拍照
7. 人脸检测
8. 位置管理
9. 旋转管理
10. 变焦
11. 录像
Camera的架构为典型的C/S架构,Client端,用户的行为,是为应用程序进程,Server端,设备的功能,是为Camera服务守护进程,客户端进程承载用户的需求,由Binder进程间通信送往服务端实现设备的功能,服务端由回调函数和消息机制反馈数据返还给用户。
ps查看进程,类似 com.android.camera是为客户端Camera进程,/system/bin/mediaserver是为服务端守护进程,由系统启动时开启。
1. 设置摄像头方向
Framework框架层的Camera对象(camera.java)里有一个类class CameraInfo,里面存放了两个公有成员变量facing和orientation,即我们要讨论的前后置和方向。 程序第一次初始化时initializeFirstTime(),通过getCameraInfo()得到前后置和方向的信息,客户端发送请求getCameraInfo()询问服务端,服务端调用抽象层拿数据,抽象层参考底层camera sensor驱动的数据facing和orientation,这两个值在驱动里是写死的,不能由用户改变,camera程序启动以后就把它们作为全局变量存放起来。
1.1 前置与后置
后置back camera背对手机屏幕,朝外,像素高,前置front camera,面对自己,朝内,像素低。
1.2 方向
摄像头模组有长边和短边,比如采集图像的比例为4:3,那么4为长边,3为短边。设备屏幕也有长边和短边,理论上,摄像头模组的长边不能与屏幕的长边垂直,至于为什么呢,我语文水平太差,没办法很好地表达出来...总之目的就是为了显示效果。
2 打开线程与预览线程
onCreate()里会先后开启CameraOpenThread和CameraPreviewThread。
打开camera还需要线程?CameraOpenThread名为打开,实为C/S connect连接服务端,binder进程间通信,开销较大。预览线程必须在打开线程完成以后执行,它贯穿始终直到进程消亡为止,整个预览过程相对复杂,在抽象层和底层驱动实现,概括讲,预览线程再开启两个线程,一个拿sensor的frame,一个送往framebuffer经surfaceflinger显示出来。
3 设置参数
预览拍照录像之前,用户需要设置很多参数,比如闪光,白平衡,场景,对比度等。
程序里这些参数保存在SharedPreferences共享优选项和Parameters两个地方,Preferences包含Parameters,打开程序读取优选项参数,关闭程序保存优选项参数,考虑到用户经常会调整参数,引入Parameters来保存从打开以后到关闭以前这个中间过程的参数变量,Parameters的键值由抽象层根据硬件sensor的能力决定。
4. Camera外设按键
Manifest里注册broadcast receiver,
<receiver android:name="com.android.camera.CameraButtonIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.CAMERA_BUTTON"/>
</intent-filter>
</receiver>
有些手机上有camera按键,用户按下按键,android输入系统有两种实现方法,
1)发送广播CAMERA_BUTTON,收到广播后开启主Activity。
2)上报键值KEYCODE_CAMERA,程序收到消息,可自定义实现功能,比如拍照。
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_CAMERA:
if (mFirstTimeInitialized && event.getRepeatCount() == 0) {
onShutterButtonClick();
}
return true;
5. 自动对焦与触摸对焦
外界事物由光线经凸透镜聚焦到sensor上成像,camera模组开启马达前后平移镜头取得最佳成像效果,这个过程称之为对焦。
5.1 自动对焦
1) camera模组会因感光强度变化而自动开启对焦,驱动控制。
2) 用户长按快门,软件控制自动对焦。
3) 用户按下快门拍照,拍摄前自动对焦。
程序里,Camera对象实现类ShutterButton的接口OnShutterButtonListener里的方法onShutterButtonFocus(boolean pressed)和onShutterButtonClick(),后者是拍照,下节讨论,先看onShutterButtonFocus(boolean pressed),这个pressed判断是否为一次有效的长按,如果是的话,执行autoFocus(),这个autoFocus()也是Camera对象实现类FocusManager的接口Listener里的方法,由binder交给camera service,最后在底层驱动实现自动对焦。
5.2 触摸对焦
自动对焦的对焦区域位于屏幕正中,用户也可触摸特定区域对焦。