שימוש בסשן של הגברת התאורה החלשה

כדי להפעיל ולהשבית את התכונה 'הגברת התאורה החלשה' של Google, משתמשים בהפעלה של התכונה 'הגברת התאורה החלשה'.

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")
}

Groovy

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 מסופק על ידי חבילת com.google.android.gms.cameralowlight של Google Play Services. מידע על גישה לממשקי API של Google Play Services זמין במסמכי העזרה של Google Play Services.

יצירת אובייקט של שיחה חוזרת

כשיוצרים את הסשן של שיפור התאורה, צריך להעביר לו אובייקט שמטמיע את הממשק 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.

יצירת סשן

כדי ליצור סשן עם תאורה חלשה, קוראים ל-method‏ 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 כדי להפעיל את רכיבי ה-listener. אם לא מציינים Executor, המאזינים פועלים ב-thread הראשי. בקוד הזה, אנחנו מניחים ש-lowLightBoostExecutor הוא Executor מתאים.

העברת תוצאות הצילום

כדי לדעת כמה להבהיר את התמונה, התכונה 'שיפור התאורה בתנאי תאורה חלשים' של Google צריכה מטא-נתונים מסוימים של המצלמה. צריך להעביר את TotalCaptureResult אל השיטה processCaptureResult(). אפשר לקבל את 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()‎.

התחלת התצוגה המקדימה של המצלמה

אחרי שיוצרים סשן של תאורה חלשה, אפשר להתחיל את זרם התצוגה המקדימה של המצלמה. מומלץ לעשות את זה בתוך הקריאה החוזרת (callback) של 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() בשיטה של הפעילות:

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;
  }
}

מידע חשוב על הקוד

  • אחרי שהסשן משוחרר, אסור לקרוא לאף אחת מהשיטות שלו. צריך לנקות את כל המשתנים שמצביעים על הסשן, כמו בקוד הזה.