Я создаю приложение камеры, в котором показываю предварительный просмотр, а затем есть два варианта автоматической фокусировки и вторая ручная панель поиска для настройки фокуса. Но вот моя проблема: когда я нажимаю кнопку захвата, мне нужно сделать 10 изображений с разными значениями ISO. У меня есть добавлен цикл со счетчиком для захвата 10 изображений со значением, настроенным после первого изображения, оно теряет фокус, а остальная часть моего изображения становится размытой и не в фокусе. Как я могу заблокировать фокус, если пользователь выбирает автоматическую фокусировку, потому что в ручном режиме я просто подаю значение во время захват, но в случае автоматической фокусировки, как я могу заблокировать фокус для всех 10 изображений
К сожалению, я не могу поделиться своим кодом, но буду очень признателен за любые общие рекомендации или примеры, которые вы можете предоставить, чтобы помочь мне решить эту проблему. Спасибо вам за вашу помощь!
когда пользователь нажимает на предварительный просмотр, я звоню
public void autoFocus() {
try {
focusSeekBar.setCurrentValue(0);
setFocusMode(Mode.AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
Log.v(TAG, "autoFocus()");
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, null);
// set seekbar to focus distance
} catch (CameraAccessException e) {
OnCameraErrorListener.handle(mCameraErrorCallback, e);
}
}
это во время процесса захвата, у меня есть один флаг, когда пользователь нажимает автофокус, я устанавливаю фокус на true
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 && !focused) {
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
}
По сути, вам нужно перевести состояние автофокусировки в состояние FOCUSED_LOCKED.
И, как сказано в документации, вам необходимо выполнить явный триггер AF, для чего для параметра CaptureRequest#CONTROL_AF_TRIGGER установлено значение CONTROL_AF_TRIGGER_START. (Обратите внимание, что значение CONTROL_AF_TRIGGER
должно быть установлено в неповторяющемся запросе, а не в повторяющемся запросе захвата, чтобы избежать повторного срабатывания)
Итак, ваш процесс захвата должен быть примерно следующим:
CONTROL_AF_TRIGGER_START
.FOCUSED_LOCKED
(или NOT_FOCUSED_LOCKED
в случае сбоя) в обратном вызове повторяющегося запроса захвата.CONTROL_AF_TRIGGER_CANCEL
, чтобы AF больше не блокировался.void preCapture() {
startAfTrigger(); // triggers AF which will eventually lead to locking the lens
awaitFocusLock(); // wait for the locking to be completed
invokeMainCapture(); // this is where you do the 10 captures you were originally doing
cancelAfTrigger(); // release the lens lock
}
void startAfTrigger() {
requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // keeping the same as in repeating request
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); // explicit AF trigger start
mCaptureSession.capture(requestBuilder.build(), captureCallback, null); // non-repeating request
// waits until the capture request has been processed by framework, basically wait until CaptureCallback#onCaptureCompleted is called once
captureCallback.await();
}
void awaitFocusLock() {
// waits until the capture request has a CaptureResult that satisfies the condition in CaptureResultVerifier#isVerified()
mCaptureCallback.await(new CaptureResultVerifier { // the mCaptureCallback should be the callback instance set for repeating request
boolean isVerified(TotalCaptureResult captureResult) {
int afState = captureResult.get(CaptureResult.CONTROL_AF_STATE);
return afState == CameraMetadata.CONTROL_AF_STATE_FOCUSED_LOCKED || // lens locked and focus succeeded
afState == CameraMetadata.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; // lens locked, but failed to get good focus
}
})
}
void cancelAfTrigger() {
requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // keeping the same as in repeating request
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mCaptureSession.capture(requestBuilder.build(), captureCallback, null); // non-repeating request
// waits until the capture request has been processed by framework, basically wait until CaptureCallback#onCaptureCompleted is called once
captureCallback.await();
}
Более подробную информацию о состоянии автофокусировки и связанных с ним переходах можно найти на странице https://source.android.com/docs/core/camera/camera3_3Amodes#af-state.