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

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

מגניב

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 היא method שכותבים כדי ליצור את אובייקט הקריאה החוזרת. האובייקט הזה מופעל כשהחיבור של הסשן מנותק או כשהסשן נמחק.
  • השיטה 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;
  }
}

נקודות חשובות לגבי הקוד הזה

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