Как использовать усиление при слабом освещении

Используйте сеанс усиления при слабом освещении, чтобы включить или отключить функцию "Усиление при слабом освещении".

Kotlin

dependencies {
  val low_light_boost_version = "16.0.1-beta04"
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2")
  implementation("com.google.android.gms:play-services-base:18.7.0")
  implementation("com.google.android.gms:play-services-camera-low-light-boost:${low_light_boost_version}")
  implementation("com.google.android.gms:play-services-tasks:18.3.0")
}

Яркий

dependencies {
  def low_light_boost_version = "16.0.1-beta04"
  implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2'
  implementation 'com.google.android.gms:play-services-base:18.7.0'
  implementation 'com.google.android.gms:play-services-camera-low-light-boost:${low_light_boost_version}'
  implementation 'com.google.android.gms:play-services-tasks:18.3.0'
}

LowLightBoostSession предоставляется пакетом сервисов Google Play com.google.android.gms.cameralowlight. Информацию о том, как получить доступ к API сервисов Google Play, можно найти в документации по сервисам Google Play.

Создайте объект обратного вызова

При создании сеанса усиления слабого освещения вам нужно будет передать ему объект, реализующий интерфейс LowLightBoostCallback. Функции этого объекта вызываются, когда сеанс отключается или уничтожается. В следующем примере кода показано, как создать обратный вызов:

Kotlin

private fun createLowLightBoostCallback(): LowLightBoostCallback =
  object : LowLightBoostCallback() {
    override fun onSessionDestroyed() {
      Log.d(TAG, "onSessionDestroyed")
      lowLightBoostSession = null
    }

    override fun onSessionDisconnected(statusCode: Int) {
      Log.d(TAG, "onSessionDisconnected: error=$statusCode")
      lowLightBoostSession = null
    }
  }

Java

private LowLightBoostCallback createLowLightBoostCallback() {
  LowLightBoostCallback lowLightBoostCallback = new LowLightBoostCallback() {
    @Override
    public void onSessionDestroyed() {
      Log.d(TAG, "onSessionDestroyed");
      lowLightBoostSession = null;
    }

    @Override
    public void onSessionDisconnected(int statusCode) {
      Log.d(TAG, "onSessionCreationFailed: error=" + statusCode);
      lowLightBoostSession = null;
    }
  }
  return lowLightBoostCallback;
}

Важная информация об этом коде

  • В этом коде определяется закрытый метод createLowLightBoostCallback(), который создает объект обратного вызова. Вы вызовете этот метод, когда будете создавать сеанс усиления слабого освещения, как описано в разделе Создание сеанса.
  • Обратный вызов выполняется, когда сеанс отключается или уничтожается. При создании сеанса он не вызывается. Чтобы проверить, был ли сеанс успешно создан, изучите объект Task, возвращенный LowLightBoostClient.createSession.

Как создать сеанс

Чтобы создать сеанс для съемки при слабом освещении, вызовите метод LowLightBoostClient.createSession.

Kotlin

val options = LowLightBoostOptions(
  previewSurface,
  cameraId,
  previewWidth,
  previewHeight,
  enableLowLightBoost
)

launch {
  try {
    val lowLightBoostSession = lowLightBoostClient
      .createSession(options, createLowLightBoostCallback()).await()

    Log.d(TAG, "Session created successfully")

    // Get the surface from the LLB session;
    // give it to camera so camera can write frames to it
  } catch (e: CancellationException) {
    Log.w(TAG, "Session creation was canceled", e)
    lowLightBoostSession = null
  } catch (e: ApiException) {
    Log.e(TAG, "Session creation failed with ApiException:", e)
    lowLightBoostSession = null
  } catch (e: Exception) {
    Log.e(TAG, "Session creation failed with Exception", e)
    lowLightBoostSession = null
  }
}

Java

LowLightBoostOptions options = new LowLightBoostOptions(
  previewSurface,
  cameraId,
  previewWidth,
  previewHeight,
  enableLowLightBoost);

lowLightBoostClient
  .createSession(options, createLowLightBoostCallback())
  .addOnSuccessListener(
    lowLightBoostExecutor,
    (session) -> {
      Log.d(TAG, "Session created successfully");

      // Get the surface from the LLB session;
      // give it to camera so camera can write frames to it

    })
  .addOnFailureListener(
    lowLightBoostExecutor,
    (e) -> {
      ApiException apiException = (ApiException) e;
      Log.d(TAG, "Session creation failed: " + e);
      lowLightBoostSession = null;
    })
  .addOnCompleteListener(
    lowLightBoostExecutor,
    (task) -> Log.d(TAG, "Session creation complete"))
  .addOnCanceledListener(
    lowLightBoostExecutor,
    () -> {
      throw new RuntimeException("Session creation canceled");
    });

Важная информация об этом коде

  • Чтобы настроить сеанс, передайте объект LowLightBoostOptions в createSession(). Этот объект определяет такие параметры, как целевая поверхность, идентификатор используемой камеры и размеры предварительного просмотра.
  • В этом коде предполагается, что вы уже подключились к камере Camera2 и использовали полученную информацию, чтобы задать значения cameraId, previewWidth, previewHeight. Подробную информацию можно найти в документации по Camera2.
  • enableLowLightBoost – логическое значение, указывающее, должно ли усиление при слабом освещении быть включено или выключено по умолчанию.
  • createLowLightBoostCallback – это метод, который вы пишете для создания объекта обратного вызова. Этот объект вызывается, когда сеанс отключается или уничтожается.
  • Метод LowLightBoostClient.createSession() возвращает объект Task. Этот объект используется для настройки прослушивателей успешного и неудачного выполнения. Запишите видео в прослушивателе успешного выполнения.
  • Вы можете указать Executor для запуска прослушивателей. Если вы не укажете Executor, прослушиватели будут выполняться в основном потоке. В этом коде мы предполагаем, что lowLightBoostExecutor – это подходящий Executor.

Передача результатов записи

Чтобы определить, насколько нужно осветлить видео, функции "Усиление слабого света" требуются определенные метаданные камеры. В метод processCaptureResult() необходимо передать объект TotalCaptureResult. Получить TotalCaptureResult можно в методе обратного вызова onCaptureCompleted().

Kotlin

  val captureCallback = CameraCaptureSession.CaptureCallback() {
    override fun onCaptureCompleted(
      session: CameraCaptureSession,
      request: CaptureRequest,
      result: TotalCaptureResult
    ) {
      super.onCaptureCompleted(session, request, result)
      lowLightBoostSession?.processCaptureResult(result)
    }
  }

Java

  CameraCaptureSession.CaptureCallback captureCallback =
    new CameraCaptureSession.CaptureCallback() {
      @Override
      public void onCaptureCompleted(
        @NonNull CameraCaptureSession session,
        @NonNull CaptureRequest request,
        @NonNull TotalCaptureResult result) {
          super.onCaptureCompleted(session, request, result)
          if (lowLightBoostSession != null) {
            lowLightBoostSession.processCaptureResult(result);
          }
        }
      };

Важная информация об этом коде

  • В этом коде показан только код CaptureCallback, относящийся к Google LLB. В этих обратных вызовах, скорее всего, будет другой код.
  • Передача TotalCaptureResult позволяет Google LLB анализировать данные об автоматической экспозиции и другие метаданные, необходимые для распознавания сцены и определения того, насколько нужно усилить освещенность кадра.
  • При создании сеанса камеры необходимо передать объект captureCallback, например с помощью setSingleRepeatingRequest().

Запустить предпросмотр камеры

После создания сеанса для съемки при слабом освещении можно запустить поток предварительного просмотра камеры. Это нужно сделать в обратном вызове onSuccess(), который вы передаете в сеанс при слабом освещении, как описано в разделе Создание сеанса. В следующем коде показано, как записать видео:

Kotlin

MainActivity.this.lowLightBoostSession =
  lowLightBoostSession
MainActivity.this.lowLightBoostSession
  .setSceneDetectorCallback(
    (lowLightBoostSession, boostStrength) -> {
      Log.d(TAG, "onSceneBrightnessChanged: " +
        "boostStrength=$boostStrength")
      // boostStrength > 0.5 indicates a low light scene.
      // Update UI accordingly.
    },
    lowLightBoostExecutor
  )
try {
  startCaptureSession(
    lowLightBoostSession.getCameraSurface())
    // Start a Camera2 session here. Pass the LLB surface
    // to the camera so the camera can write frames to it.
} catch (e: CameraAccessException) {
  Log.e(TAG, "Failed to start capture session", e)
  // Must try again or start the capture session without LLB.
}

Java

MainActivity.this.lowLightBoostSession =
  lowLightBoostSession;
MainActivity.this.lowLightBoostSession
  .setSceneDetectorCallback(
    (lowLightBoostSession, boostStrength) -> {
      Log.d(TAG, "onSceneBrightnessChanged: " +
        "boostStrength=" + boostStrength);
      // boostStrength > 0.5 indicates a low light scene.
      // Update UI accordingly.
    },
    lowLightBoostExecutor
  );
try {
  startCaptureSession(
    lowLightBoostSession.getCameraSurface());
    // Start a Camera2 session here. Pass the LLB surface
    // to the camera so the camera can write frames to it.
} catch (CameraAccessException e) {
  Log.e(TAG, "Failed to start capture session", e);
  // Must try again or start the capture session without LLB.
}

Важная информация об этом коде

  • lowLightBoostSession – сеанс, созданный на этапе Создание сеанса.
  • setSceneDetectorCallback() определяет объект обратного вызова, реализующий интерфейс SceneDetectorCallback. Сеанс вызывает метод onSceneBrightnessChanged() этого объекта, когда меняется яркость сцены. Ваша реализация должна соответствующим образом корректировать пользовательский интерфейс камеры.
  • Вы можете указать Executor для выполнения обратного вызова. Если вы не укажете Executor, обратный вызов будет выполнен в основном потоке. В этом коде мы предполагаем, что lowLightBoostExecutor – это подходящий Executor.
  • lowLightBoostSession.getCameraSurface() возвращает Surface с записанным видео.

Освободить сеанс

Когда камера больше не активна, завершите сеанс усиления при слабом освещении, вызвав LowLightBoostSession.release(). В частности, не забудьте завершить сеанс, когда действие будет уничтожено. Для этого вызовите метод в методе onDestroy() своего объекта activity:

Kotlin

override protected void onDestroy() {
  super.onDestroy()
  if (lowLightBoostSession != null) {
    lowLightBoostSession.release()
    lowLightBoostSession = null
  }
}

Java

@Override
protected void onDestroy() {
  super.onDestroy();
  if (lowLightBoostSession != null) {
    lowLightBoostSession.release();
    lowLightBoostSession = null;
  }
}

Важная информация об этом коде

  • После освобождения сеанса не следует вызывать какие-либо из его методов. Вам следует очистить все переменные, указывающие на сеанс, как это сделано в коде.