Android Camera 系列目录

  1. 搭建Camera开发项目
  2. Android Camera API
    • Camera API使用指南
    • Camera 高级特性——手动对焦
    • Android Camera 高级特性——闪光灯、抗闪烁、场景
    • Camera性能优化
  3. Android Camera2 API
    • Camera2 API使用指南
    • Camera2硬件兼容级别
    • Camera2拉伸问题
    • Camera2高级特性
    • Camera2源代码分析
  4. 相机模块设计

1. 前言

对焦可以说是相机最基本的功能。
Android Camera提供了多种对焦方式:

  • FOCUS_MODE_AUTO:个人认为这个名字起的有点随意
  • FOCUS_MODE_CONTINUOUS_PICTURE : 持续对焦模式,适用于拍照,此模式可调用autoFocus(AutoFocusCallback)

Applications can call autoFocus(AutoFocusCallback) in this mode. If the autofocus is in the middle of scanning, the focus callback will return when it completes. If the autofocus is not scanning, the focus callback will immediately return with a boolean that indicates whether the focus is sharp or not. The apps can then decide if they want to take a picture immediately or to change the focus mode to auto, and run a full autofocus cycle. The focus position is locked after autoFocus call. If applications want to resume the continuous focus, cancelAutoFocus must be called. Restarting the preview will not resume the continuous autofocus. To stop continuous focus, applications should change the focus mode to other modes.1

  • FOCUS_MODE_CONTINUOUS_VIDEO :持续对焦模式,适用录制视频,对焦比FOCUS_MODE_CONTINUOUS_PICTURE要消极一些,官方文档上说,这是录制视频时最好的选择,因为焦点变化时更加顺滑。此模式可调用autoFocus(AutoFocusCallback)

Since API level 14, applications can call autoFocus(AutoFocusCallback) in this mode. The focus callback will immediately return with a boolean that indicates whether the focus is sharp or not. The focus position is locked after autoFocus call. If applications want to resume the continuous focus, cancelAutoFocus must be called. Restarting the preview will not resume the continuous autofocus. To stop continuous focus, applications should change the focus mode to other modes.

  • FOCUS_MODE_EDOF : Extended depth of field (EDOF),此模式不能调用autoFocus(AutoFocusCallback)
  • FOCUS_MODE_FIXED : 适用于超焦距对焦,此模式不能调用autoFocus(AutoFocusCallback)
  • FOCUS_MODE_INFINITY : 无穷(??)模式,此模式不能调用autoFocus(AutoFocusCallback)
  • FOCUS_MODE_MACRO :宏观(特写)对焦模式,此模式可调用autoFocus(AutoFocusCallback)

其中前三種是常用的對焦模式。

2. 实现

2.1 默认对焦设置

在前一篇文章《Android Camera API使用指南
》中我提到可以再配置Camera.Parameters中设置对焦类型,这里就不介绍了。

        //对焦方式        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {            mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);        }---------------------本文来自 微岩 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/matrix_laboratory/article/details/82871064?utm_source=copy 

2.2 手动对焦实现

2.2.1 最简单的对焦实现

所谓的手动对焦就是用户点击了屏幕的某块区域,需要把相机对焦到用户点击的区域。(又废话了…… -_-||)
一般我们看到文章介绍Camera API1时,通常会说它使用非常简单(当然相对于Camera API2来说),原因是修改Camera的状态非常简单,只要重新配置下Camera.Parameters,然后设置给Camera就OK。最简单的设置步骤是:

    public synchronized void setFocusMode(String focusMode) {        if (mCameraDevice == null)            return;        mParams = mCameraDevice.getParameters();        List focusModes = mParams.getSupportedFocusModes();        if (focusModes.contains(focusMode)) {            mParams.setFocusMode(focusMode);        }    }

上面的对焦实现是非常简单的,切换对焦模式后效果基本没有明显的变化,而且也没有设置对焦区域……(呃~该对焦效果确实生效了…………)

2.2.2 系统相机对焦效果仿真实现

需求分析

首先分析下系统相机的对焦都有哪些效果:

  1. 支持用户设置对焦区域,重新设定对焦区域后会触发相机对焦。
  2. 重新设定对焦区域后,画面有明显的亮度变化。

第1点很正常,就是预期的对焦效果。
第2点触发图像亮度变化,实际上这已经不是对焦的范畴了,而是测光。从效果上看,系统相机响应手动对焦的同时根据焦点重新测光。

实现方案

通过上面的分析,我们需要设置对焦区域和测光区域,Camera.Parameters中提供了依赖的接口:

  • getMaxNumFocusAreas:获取支持的对焦区域的个数
  • setFocusAreas:设置对焦区域列表
  • getFocusAreas:获取对焦区域列表
  • getMaxNumMeteringAreas: 获取支持的测光区域的个数
  • setMeteringAreas:设置测光区域列表
  • getMeteringAreas:获取测光区域列表

用到的接口就这几个。具体操作如下:

  1. 计算对焦和测光区域
    Camera中区域是由Camera.Area定义的,用于相机计算自动曝光、自动白平衡、自动聚焦。其中包含两个成员:
    /**     * Create an area with specified rectangle and weight.     *     * @param rect the bounds of the area.     * @param weight the weight of the area.     */    public Area(Rect rect, int weight) {        this.rect = rect;//区域:[-1000, 1000]        this.weight = weight;//权重: [1, 1000]    }

Area到屏幕的映射如下,坐标(-1000,-1000)代表Camera图像的左上角:

如此就需要把用户点击的屏幕坐标转换为Camera.Area,下面一段简单转换的代码:

            int focusRadius = (int) (radius * 1000.0f);            int left = (int) (x * 2000.0f - 1000.0f) - focusRadius;            int top = (int) (y * 2000.0f - 1000.0f) - focusRadius;            Rect focusArea = new Rect();            focusArea.left = Math.max(left, -1000);            focusArea.top = Math.max(top, -1000);            focusArea.right = Math.min(left + focusRadius, 1000);            focusArea.bottom = Math.min(top + focusRadius, 1000);            Camera.Area cameraArea = new Camera.Area(focusArea, 800);
  1. 添加对焦/测光区域
List meteringAreas;List focusAreas;if (mParams.getMaxNumMeteringAreas() > 0) {List meteringAreas = new ArrayList();meteringAreas.add(cameraArea);}if (mParams.getMaxNumMeteringAreas() > 0) {focusAreas = new ArrayList();focusAreas.add(cameraArea);}    mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);    mParams.setFocusAreas(meteringAreas);
  1. 设置对焦策略
            try {                mCameraDevice.cancelAutoFocus();                mCameraDevice.setParameters(mParams);                mCameraDevice.autoFocus(callback);            } catch (Exception e) {                LogUtil.e(TAG, "Error: focusAtPoint failed: " + e.toString());            }

上面三个步骤都是必须的,对焦不是瞬间完成,而是一个持续的过程。1

  • cancelAutoFocus:结束上一次的对焦操作,不管是有没有完成对焦
  • autoFocus:执行一次对焦操作,通过Camera.AutoFocusCallback返回对焦结果。

至此,一次对焦操作就完成了。

3. 参考文献


  1. Android Camera (https://developer.android.com/reference/android/hardware/Camera#autoFocus(android.hardware.Camera.AutoFocusCallback) ↩︎

更多相关文章

  1. No.11 使用firewall配置的防火墙策略的生效模式
  2. Android屏幕区域划分及尺寸获取
  3. OpenGL ES 2.0 - Matrix. setLookAtM/.frustumM/.multiplyMM
  4. [Android面试题-3] Activity的四种加载模式
  5. 如何实现Android(安卓)布局背景模糊化处理
  6. 对于Android的Activity启动模式的一些总结和理解
  7. android 布局背景模糊化处理
  8. Android中设计模式无处不在之单例模式
  9. Android技术栈总结

随机推荐

  1. Android(安卓)EditText 不可编辑到可编辑
  2. Android(安卓)上传文件[转]
  3. android 如何去掉状态栏和标题栏
  4. android如何用代码实现界面ui
  5. Android页面跳转是如何传递参数的
  6. Android(安卓)点击空白区域 软键盘消失
  7. android 操作路由表
  8. Android各版本代号/版本号/API级别
  9. android实现双击事件的监听
  10. 图片比例缩放以及bitMap转BitmapDrawable