1、自动对焦
在预览前后设置的param里setFocusMode();为Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO或者Camera.Parameters.FOCUS_MODE_AUTO,建议采用后者。注意调用此方法后,再次调用Camera.autoFocus()会导致对焦失败
参考此文 http://blog.csdn.net/yanzi1225627/article/details/8577682
2、触摸对焦
触摸对焦在设置焦点前需要先取消先前设置的焦点,
参考文章 http://stackoverflow.com/a/19272166
/**
* On each tap event we will calculate focus area and metering area.
* <p/>
* Metering area is slightly larger as it should contain more info for exposure calculation.
* As it is very easy to over/under expose
*/
public void focusOnTouch(MotionEvent event) {
if (camera_ != null) {
//cancel previous actions
camera_.cancelAutoFocus();
Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);
Rect meteringRect = calculateTapArea(event.getX(), event.getY(), 1.5f);
Camera.Parameters parameters = null;
try {
parameters = camera_.getParameters();
} catch (Exception e) {
e.printStackTrace();
}
// check if parameters are set (handle RuntimeException: getParameters failed (empty parameters))
if (parameters != null) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
List<Camera.Area> focus = new ArrayList<>();
focus.add(new Camera.Area(focusRect, 1000));
parameters.setFocusAreas(focus);
if (parameters.getMaxNumMeteringAreas() > 0) {
List<Camera.Area> metering = new ArrayList<>();
metering.add(new Camera.Area(focusRect, 1000));
parameters.setMeteringAreas(metering);
}
}
try {
camera_.setParameters(parameters);
camera_.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private int focusAreaSize = 300;
/**
* Convert touch position x:y to {@link Camera.Area} position -1000:-1000 to 1000:1000.
* <p/>
* Rotate, scale and translate touch rectangle using matrix configured in
* {@link SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)}
*/
private Rect calculateTapArea(float x, float y, float coefficient) {
int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
int left = clamp((int) x - areaSize / 2, 0, surfaceView_.getWidth() - areaSize);
int top = clamp((int) y - areaSize / 2, 0, surfaceView_.getHeight() - areaSize);
RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
(new Matrix()).mapRect(rectF);
return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
}
private int clamp(int x, int min, int max) {
if (x > max) {
return max;
}
if (x < min) {
return min;
}
return x;
}