Блокировка фокуса Android Camera 2 API

Я создаю приложение камеры, в котором показываю предварительный просмотр, а затем есть два варианта автоматической фокусировки и вторая ручная панель поиска для настройки фокуса. Но вот моя проблема: когда я нажимаю кнопку захвата, мне нужно сделать 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);
        }
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По сути, вам нужно перевести состояние автофокусировки в состояние FOCUSED_LOCKED.

И, как сказано в документации, вам необходимо выполнить явный триггер AF, для чего для параметра CaptureRequest#CONTROL_AF_TRIGGER установлено значение CONTROL_AF_TRIGGER_START. (Обратите внимание, что значение CONTROL_AF_TRIGGER должно быть установлено в неповторяющемся запросе, а не в повторяющемся запросе захвата, чтобы избежать повторного срабатывания)

Итак, ваш процесс захвата должен быть примерно следующим:

  1. Прежде чем начать захват, отправьте одиночный (неповторяющийся) запрос на захват с помощью CONTROL_AF_TRIGGER_START.
  2. Подождите, пока состояние AF не перейдет в FOCUSED_LOCKED (или NOT_FOCUSED_LOCKED в случае сбоя) в обратном вызове повторяющегося запроса захвата.
  3. Выполните свой обычный процесс захвата, то есть основную часть захвата.
  4. Отмените триггер AF с помощью 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.

Другие вопросы по теме