Переключите вспышку в Camera2 API

Моя проблема в том, что когда я переключаюсь между различными режимами флэш-памяти, а затем хочу захватить изображение, мой captureBuilder не устанавливает выбранный режим флэш-памяти. Это работает только когда я закрываю и снова открываю камеру.

Я взял https://github.com/googlesamples/android-Camera2Basic в качестве отправной точки.

мой метод:

   private void captureStillPicture() {
  try {
     final Activity activity = (Activity) context;
     if (null == activity || null == mCameraDevice) {
        return;
     }
     // This is the CaptureRequest.Builder that we use to take a picture.
     CaptureRequest.Builder captureBuilder =
           mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
     captureBuilder.addTarget(mImageReader.getSurface());

     // Use the same AE and AF modes as the preview.
     captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
           CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
     setCurrentFlash(captureBuilder);

     // Orientation
     int rotation = activity.getWindowManager()
           .getDefaultDisplay()
           .getRotation();
     captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));

     CameraCaptureSession.CaptureCallback captureCallback =
           new CameraCaptureSession.CaptureCallback() {

              @Override
              public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                    @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                 super.onCaptureCompleted(session, request, result);
                 Toast.makeText(context, "image captured", Toast.LENGTH_SHORT)
                       .show();
                 unlockFocus();
              }
           };

              mCaptureSession.stopRepeating();
     mCaptureSession.capture(captureBuilder.build(), captureCallback, null);
  } catch (CameraAccessException e) {
     Log.e(this.getClass()
           .getSimpleName(), e.getMessage(), e);
  }

Это метод setCurrentFlash:

   private void setCurrentFlash(CaptureRequest.Builder requestBuilder) {
  if (mFlashSupported) {
     switch (flashMode.name()) {
        case FLASH_AUTO:
           requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                 CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
           break;
        case FLASH_ON:
           requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                 CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
           break;
        case FLASH_OFF:
           requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
           break;
        default:
           requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                 CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
           break;
     }
  }

Любые идеи, почему строитель не устанавливает вспышку правильно перед съемкой?

***** РЕДАКТИРОВАТЬ *****

Решил проблему, установив flash на previewRequestBuilder при вызове runPrecaptureSequence(), как предложил Эдди Талвала

   private void runPrecaptureSequence() {
  try {
     // This is how to tell the camera to trigger.
     setCurrentFlash(previewRequestBuilder);
     previewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
           CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
     // Tell #mCaptureCallback to wait for the precapture sequence to be set.
     state = STATE_WAITING_PRECAPTURE;
     captureSession.capture(previewRequestBuilder.build(), mCaptureCallback, backgroundHandler);
  } catch (CameraAccessException e) {
     e.printStackTrace();
  }

1 ответ

Решение

Вы хотите обновить режим флеш-памяти в вашем запросе на предварительный просмотр; Обычно устройство камеры хочет знать желаемый режим вспышки, когда вы запускаете последовательность предварительной съемки (с помощью AE_PRECAPTURE_TRIGGER), чтобы она знала, должна ли она включить предварительную вспышку, что необходимо для определения конечной мощности вспышки.

Обычная последовательность событий:

  1. Установите предварительный режим вспышки в желаемый режим
  2. Подождите, пока пользователь нажмет кнопку спуска
  3. Выполните один запрос предварительного просмотра с установленным триггером предварительного захвата (но в противном случае сохраните запрос предварительного просмотра при повторении).
  4. Подождите, пока AE_STATE_PRECAPTURE перестанет быть состоянием AE в ваших результатах захвата
  5. Выполните окончательный запрос захвата (сохраняйте тот же режим прошивки)
  6. Получите окончательный JPEG в вашем ImageReader

(Это игнорирует обеспечение хорошего фокуса, что обычно делается до / параллельно с запуском последовательности предварительного захвата)

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