You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Camera2 API自动对焦锁定问题:连拍10张不同ISO图像失焦

自动对焦锁定实现方案(适配连拍多ISO场景)

核心逻辑

要解决连拍时首张后失焦的问题,核心是先触发单次对焦并锁定对焦状态,而非使用连续对焦模式。连续对焦会在拍摄过程中持续调整对焦,直接导致后续照片模糊。

具体实现步骤

1. 替换连续对焦为单次对焦触发

修改你当前的autoFocus()方法,把连续对焦改成单次对焦模式,并主动触发对焦动作:

public void autoFocus() {
    try {
        focusSeekBar.setCurrentValue(0);
        setFocusMode(Mode.AUTO);
        // 改用单次对焦模式,触发一次对焦后锁定
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
        // 触发对焦动作
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
        Log.v(TAG, "autoFocus() - 触发单次对焦");
        mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, null);
        // 重置AF触发,避免重复触发
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null);
    } catch (CameraAccessException e) {
        OnCameraErrorListener.handle(mCameraErrorCallback, e);
    }
}

2. 监听对焦完成状态并锁定参数

在你的mCaptureCallback的onCaptureCompleted方法中,判断对焦是否成功锁定,标记状态并保存锁定的对焦距离:

@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
    super.onCaptureCompleted(session, request, result);
    Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
    // 确认对焦已成功锁定
    if (afState != null && afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED) {
        focused = true;
        // 保存锁定的对焦距离,后续连拍复用
        float lockedFocusDistance = result.get(CaptureResult.LENS_FOCUS_DISTANCE);
        // 预览切换为锁定状态,避免预览时重新对焦
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
        mPreviewRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, lockedFocusDistance);
        mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, null);
    }
}

3. 连拍时复用锁定的对焦参数

修改拍摄逻辑,当自动对焦已锁定时,直接关闭AF模式并使用锁定的对焦距离,不再使用连续对焦:

// 假设已在全局变量中保存lockedFocusDistance
if (focusMode == Mode.MANUAL) {
    captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
    captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);
} else if (focusMode == Mode.AUTO) {
    if (!focused) {
        // 未完成对焦时,先触发单次对焦
        captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
        captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
    } else {
        // 已锁定对焦,关闭AF并复用锁定的对焦距离
        captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
        captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, lockedFocusDistance);
    }
}
// 重置AF触发,防止影响后续请求
captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null);

4. 连拍完成后恢复预览对焦

连拍结束后,重置对焦锁定状态,恢复预览的自动对焦能力:

// 连拍结束后调用此方法
public void resetFocusLock() {
    focused = false;
    try {
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
        mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, null);
    } catch (CameraAccessException e) {
        OnCameraErrorListener.handle(mCameraErrorCallback, e);
    }
}

关键注意点

  • 绝对避免在连拍过程中使用CONTROL_AF_MODE_CONTINUOUS_PICTURE,该模式会持续调整对焦,导致后续照片失焦。
  • 必须等待CONTROL_AF_STATE_FOCUSED_LOCKED状态触发后再开始连拍,确保对焦真正完成。
  • 所有连拍请求都要关闭AF模式并复用锁定的LENS_FOCUS_DISTANCE,保证每张照片对焦参数一致。

内容的提问来源于stack exchange,提问作者Akshar Kalathiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:07:37