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
相关产品推荐
相关产品推荐

