对焦可以说是相机最基本的功能。
Android Camera提供了多种对焦方式:
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
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.
其中前三種是常用的對焦模式。
在前一篇文章《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
所谓的手动对焦就是用户点击了屏幕的某块区域,需要把相机对焦到用户点击的区域。(又废话了…… -_-||)
一般我们看到文章介绍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);
}
}
上面的对焦实现是非常简单的,切换对焦模式后效果基本没有明显的变化,而且也没有设置对焦区域……(呃~该对焦效果确实生效了…………)
首先分析下系统相机的对焦都有哪些效果:
第1点很正常,就是预期的对焦效果。
第2点触发图像亮度变化,实际上这已经不是对焦的范畴了,而是测光。从效果上看,系统相机响应手动对焦的同时根据焦点重新测光。
通过上面的分析,我们需要设置对焦区域和测光区域,Camera.Parameters中提供了依赖的接口:
用到的接口就这几个。具体操作如下:
/**
* 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);
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);
try {
mCameraDevice.cancelAutoFocus();
mCameraDevice.setParameters(mParams);
mCameraDevice.autoFocus(callback);
} catch (Exception e) {
LogUtil.e(TAG, "Error: focusAtPoint failed: " + e.toString());
}
上面三个步骤都是必须的,对焦不是瞬间完成,而是一个持续的过程。1
至此,一次对焦操作就完成了。
Android Camera (https://developer.android.com/reference/android/hardware/Camera#autoFocus(android.hardware.Camera.AutoFocusCallback) ↩︎