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

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

Kotlin

dependencies {
  val low_light_boost_version = "16.0.0-beta01"
  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.0-beta01"
  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. במסמכי העזרה של Google Play Services מוסבר איך לגשת לממשקי ה-API של Google Play Services.

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

כשיוצרים את סשן התגבור בתאורה נמוכה, צריך להעביר לו אובייקט שמטמיע את הממשק LowLightBoostCallback. הפונקציות של האובייקט הזה נקראות כשהסשן מנותק או נהרס. הקוד הבא מראה איך יוצרים קריאה חוזרת (callback):

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 שכותבים כדי ליצור את אובייקט ה-callback. האובייקט הזה נקרא כשהסשן מנותק או נהרס.
  • השיטה LowLightBoostClient.createSession() מחזירה אובייקט Task. משתמשים באובייקט הזה כדי להגדיר מאזינים להצלחה ולכישלון. תיעוד הסרטון בתוך ה-listener של האירוע 'הצלחה'
  • אפשר לציין Executor כדי להפעיל את המאזינים. אם לא מציינים 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() מגדיר אובייקט קריאה חוזרת (callback) שמטמיע את הממשק SceneDetectorCallback. כשהבהירות של הסצנה משתנה, המערכת קוראת לשיטה onSceneBrightnessChanged() של האובייקט הזה. במסגרת ההטמעה, צריך לשנות את ממשק המשתמש של המצלמה בהתאם.
  • אפשר לציין Executor כדי להריץ את הקריאה החוזרת. אם לא מציינים Executor, פונקציית ה-callback פועלת בשרשור הראשי. בקוד הזה, אנחנו מניחים ש-lowLightBoostExecutor הוא Executor מתאים.
  • הפונקציה lowLightBoostSession.getCameraSurface() מחזירה את Surface עם הסרטון שצולם.

סיום הסשן

כשהמצלמה כבר לא פעילה, מבטלים את סשן ההגברה בתנאי תאורה נמוכה על ידי שליחת הפקודה LowLightBoostSession.release(). חשוב במיוחד לוודא שמשחררים את הסשן כשהפעילות נהרסת. כדי לעשות זאת, צריך להפעיל את השיטה ב-method‏ 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;
  }
}

נקודות עיקריות לגבי הקוד הזה

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