ממשק API של תוספי CameraX

‫CameraX מספקת Extensions API לגישה לתוספים שיצרני המכשירים הטמיעו במכשירי Android שונים. רשימת מצבי ההרחבות הנתמכים מופיעה במאמר בנושא הרחבות למצלמה.

רשימת המכשירים שתומכים בתוספים זמינה במאמר בנושא מכשירים נתמכים.

ארכיטקטורה של תוספים

בתמונה הבאה מוצגת ארכיטקטורת התוספים של המצלמה.

איור 1. ארכיטקטורה של תוספים למצלמה

אפליקציית CameraX יכולה להשתמש בתוספים דרך CameraX Extensions API. ‫CameraX Extensions API מנהל את השאילתות לגבי התוספים הזמינים, את ההגדרה של סשן מצלמה של תוסף ואת התקשורת עם ספריית Camera Extensions OEM. כך האפליקציה יכולה להשתמש ביכולות כמו צילום בלילה, HDR, אוטומטי, בוקה או ריטוש פנים.

הפעלת תוסף לצילום תמונות ולתצוגה מקדימה

לפני שמשתמשים ב-Extensions API, צריך לאחזר מופע ExtensionsManager באמצעות השיטה ExtensionsManager#getInstanceAsync(Context, CameraProvider). כך תוכלו לשלוח שאילתות לגבי מידע על זמינות התוסף. לאחר מכן מאחזרים תוסף מופעל CameraSelector. מצב ההרחבה יחול על תרחישי שימוש של צילום תמונות ותצוגה מקדימה כשקוראים למתודה bindToLifecycle()‎ עם ההרחבה CameraSelector מופעלת.

כדי להטמיע את התוסף במקרים של צילום תמונות ותצוגה מקדימה, אפשר להיעזר בדוגמת הקוד הבאה:

Kotlin

import androidx.camera.extensions.ExtensionMode
import androidx.camera.extensions.ExtensionsManager

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val lifecycleOwner = this

    val cameraProviderFuture = ProcessCameraProvider.getInstance(applicationContext)
    cameraProviderFuture.addListener({
        // Obtain an instance of a process camera provider
        // The camera provider provides access to the set of cameras associated with the device.
        // The camera obtained from the provider will be bound to the activity lifecycle.
        val cameraProvider = cameraProviderFuture.get()

        val extensionsManagerFuture =
            ExtensionsManager.getInstanceAsync(applicationContext, cameraProvider)
        extensionsManagerFuture.addListener({
            // Obtain an instance of the extensions manager
            // The extensions manager enables a camera to use extension capabilities available on
            // the device.
            val extensionsManager = extensionsManagerFuture.get()

            // Select the camera
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            // Query if extension is available.
            // Not all devices will support extensions or might only support a subset of
            // extensions.
            if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.NIGHT)) {
                // Unbind all use cases before enabling different extension modes.
                try {
                    cameraProvider.unbindAll()

                    // Retrieve a night extension enabled camera selector
                    val nightCameraSelector =
                        extensionsManager.getExtensionEnabledCameraSelector(
                            cameraSelector,
                            ExtensionMode.NIGHT
                        )

                    // Bind image capture and preview use cases with the extension enabled camera
                    // selector.
                    val imageCapture = ImageCapture.Builder().build()
                    val preview = Preview.Builder().build()
                    // Connect the preview to receive the surface the camera outputs the frames
                    // to. This will allow displaying the camera frames in either a TextureView
                    // or SurfaceView. The SurfaceProvider can be obtained from the PreviewView.
                    preview.setSurfaceProvider(surfaceProvider)

                    // Returns an instance of the camera bound to the lifecycle
                    // Use this camera object to control various operations with the camera
                    // Example: flash, zoom, focus metering etc.
                    val camera = cameraProvider.bindToLifecycle(
                        lifecycleOwner,
                        nightCameraSelector,
                        imageCapture,
                        preview
                    )
                } catch (e: Exception) {
                    Log.e(TAG, "Use case binding failed", e)
                }
            }
        }, ContextCompat.getMainExecutor(this))
    }, ContextCompat.getMainExecutor(this))
}

Java

import androidx.camera.extensions.ExtensionMode;
import androidx.camera.extensions.ExtensionsManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final LifecycleOwner lifecycleOwner = this;

    final ListenableFuture cameraProviderFuture =
            ProcessCameraProvider.getInstance(getApplicationContext());

    cameraProviderFuture.addListener(() -> {
      try {
          // Obtain an instance of a process camera provider
          // The camera provider provides access to the set of cameras associated with the
          // device. The camera obtained from the provider will be bound to the activity
          // lifecycle.
          final ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

          final ListenableFuture extensionsManagerFuture =
                  ExtensionsManager.getInstanceAsync(getApplicationContext(), cameraProvider);
          extensionsManagerFuture.addListener(() -> {
              // Obtain an instance of the extensions manager
              // The extensions manager enables a camera to use extension capabilities available
              // on the device.
              try {
                  final ExtensionsManager extensionsManager = extensionsManagerFuture.get();

                  // Select the camera
                  final CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

                  // Query if extension is available.
                  // Not all devices will support extensions or might only support a subset of
                  // extensions.
                  if (extensionsManager.isExtensionAvailable(
                          cameraSelector,
                          ExtensionMode.NIGHT
                  )) {
                      // Unbind all use cases before enabling different extension modes.
                      cameraProvider.unbindAll();

                      // Retrieve extension enabled camera selector
                      final CameraSelector nightCameraSelector = extensionsManager
                              .getExtensionEnabledCameraSelector(cameraSelector, ExtensionMode.NIGHT);

                      // Bind image capture and preview use cases with the extension enabled camera
                      // selector.
                      final ImageCapture imageCapture = new ImageCapture.Builder().build();
                      final Preview preview = new Preview.Builder().build();
                      // Connect the preview to receive the surface the camera outputs the frames
                      // to. This will allow displaying the camera frames in either a TextureView
                      // or SurfaceView. The SurfaceProvider can be obtained from the PreviewView.
                      preview.setSurfaceProvider(surfaceProvider);

                      cameraProvider.bindToLifecycle(
                              lifecycleOwner,
                              nightCameraSelector,
                              imageCapture,
                              preview
                      );
                  }
              } catch (ExecutionException | InterruptedException e) {
                  throw new RuntimeException(e);
              }
          }, ContextCompat.getMainExecutor(this));

      } catch (ExecutionException | InterruptedException e) {
          throw new RuntimeException(e);
      }

  }, ContextCompat.getMainExecutor(this));
}

השבתת התוסף

כדי להשבית את התוספים של הספק, צריך לבטל את הקישור של כל תרחישי השימוש ולקשר מחדש את תרחישי השימוש של צילום התמונות והתצוגה המקדימה באמצעות בורר מצלמות רגיל. לדוגמה, אפשר להגדיר מחדש את המצלמה האחורית באמצעות CameraSelector.DEFAULT_BACK_CAMERA.

פניות קשורות

ממשק ה-API של CameraX Extensions מיושם בספרייה camera-extensions. התוספים תלויים במודולי הליבה של CameraX ‏ (core, ‏camera2,‏ lifecycle).

מגניב

dependencies {
  def camerax_version = "1.2.0-rc01"
  implementation "androidx.camera:camera-core:${camerax_version}"
  implementation "androidx.camera:camera-camera2:${camerax_version}"
  implementation "androidx.camera:camera-lifecycle:${camerax_version}"
  //the CameraX Extensions library
  implementation "androidx.camera:camera-extensions:${camerax_version}"
    ...
}

Kotlin

dependencies {
  val camerax_version = "1.2.0-rc01"
  implementation("androidx.camera:camera-core:${camerax_version}")
  implementation("androidx.camera:camera-camera2:${camerax_version}")
  implementation("androidx.camera:camera-lifecycle:${camerax_version}")
  // the CameraX Extensions library
  implementation("androidx.camera:camera-extensions:${camerax_version}")
    ...
}

הסרה של API מדור קודם

עם השקת Extensions API החדש ב-1.0.0-alpha26, ‏ Extensions API מדור קודם שהושק באוגוסט 2019 הוצא משימוש. החל מגרסה 1.0.0-alpha28, הוצאנו את Extensions API מדור קודם מהספרייה. אפליקציות שמשתמשות ב-Extensions API החדש צריכות עכשיו לקבל CameraSelector עם תוסף מופעל ולהשתמש בו כדי לקשר את תרחישי השימוש.

אפליקציות שמשתמשות ב-Extensions API מהדור הקודם צריכות לעבור ל-Extensions API החדש כדי להבטיח תאימות עתידית לגרסאות הקרובות של CameraX.

מקורות מידע נוספים

מידע נוסף על CameraX זמין במקורות המידע הבאים.

Codelab

  • תחילת העבודה עם CameraX
  • דוגמת קוד

    אפליקציית דוגמה של CameraX Extensions

    מקורות אחרים

    CameraX Vendor Extensions

    כלי האימות של תוספי ספקים ב-CameraX