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

כדי להפעיל ולהשבית את התכונה 'הגברת התאורה החלשה' של 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;
  }
}

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

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