[Announcement] Introduce new Extensions APIs and the removal of the legacy Extensions APIs

121 views
Skip to first unread message

Julie Wu

unread,
Aug 13, 2021, 3:47:12 AM8/13/21
to camerax-d...@android.com
Dear developers, 

Since camera-extensions 1.0.0-alpha26, we have introduced the new extensions APIs which are easier to use and more consistent than previous legacy extensions APIs. Starting from 1.0.0-alpha28, which will be released soon, the legacy extensions API will be removed. You have to switch to the new extensions APIs, but don’t worry about it too much because it should be quite straightforward for the migration. 

 

To enable the extension and use the new extensions API, developers have to follow 3 steps: 
(1) Get the ExtensionsManager instance 

(2) Get an extension-enabled cameraSelector if extension is available 

(3) Call bindToLifecycle using this extension-enabled cameraSelector

See the following sample codes:

 

ProcessCameraProvider mCameraProvider = ...


// Calls the getInstance function to retrieve a ListenableFuture object

ListenableFuture<ExtensionsManager> future =

                ExtensionsManager.getInstance(getApplicationContext());


// Obtains the ExtensionsManager instance from the returned ListenableFuture object

future.addListener(() -> {

    try {

        ExtensionsManager extensionsManager = future.get();


        CameraSelector selector = CameraSelector.DEFAULT_BACK_CAMERA; 

                                    

        // Checks whether bokeh is supported

        if (extensionsManager.isExtensionAvailable(mCameraProvider, selector, 

                    ExtensionMode.BOKEH)) {

            // Gets the bokeh enabled camera selector if bokeh is supported

            selector = extensionsManager.getExtensionCameraSelector(selector, 

                                                 ExtensionMode.BOKEH);


            // Binds use case with the bokeh enabled camera selector

            ImageCapture imageCapture = new ImageCapture.Builder().build();

            Preview preview = new Preview.Builder().build();

            mCameraProvider.bindToLifecycle(mLifecycleOwner, selector, 

                    imageCapture, preview);

        }

    } catch (ExecutionException | InterruptedException e) {

        // This should not happen unless the future is cancelled or the thread is 

        // interrupted by applications.

    }

}, ContextCompat.getMainExecutor(context));

 

As you can see, the new extensions APIs allow developers to enable the extension directly on the camera, while previously with the legacy extensions APIs, developers needed to enable extension modes to Preview and ImageCapture by the corresponding extender class separately. To make the extension modes work well, both Preview and ImageCapture need to apply the same extension mode at the same time. The legacy extender design increased the complexity of code writing and also increased the chance of missing extension mode on either Preview or ImageCapture. The code written with the legacy extensions APIs looks like the following:

 

private ProcessCameraProvider mCameraProvider = ...


// Calls the init function to retrieve a ListenableFuture object

ListenableFuture<ExtensionsManager.ExtensionsAvailability> future = 

        ExtensionsManager.init(getApplicationContext());


// Obtains the ExtensionsManager instance from the returned ListenableFuture object

future.addListener(() -> {

    try {

        ExtensionsManager.ExtensionsAvailability availability = future.get();


        if (availability == LIBRARY_UNAVAILABLE_ERROR_LOADING 

               || availability == LIBRARY_UNAVAILABLE_MISSING_IMPLEMENTATION) {

            throw new RuntimeException("Failed to load up extensions "

                        + "implementation");

        }


        List<UseCase> useCases = new ArrayList<>();

        Preview.Builder previewBuilder = new Preview.Builder();


        // Creates a Preview extender according to the effect mode

        PreviewExtender previewExtender = new BokehPreviewExtender.create(

                    previewBuilder);


        // Checks the effect availability and enables the extension mode

        if (previewExtender.isExtensionAvailable(DEFAULT_BACK_CAMERA)) {

            previewExtender.enableExtension(DEFAULT_BACK_CAMERA);

        }


        useCases.add(previewBuilder.build());


        ImageCapture.Builder imageCaptureBuilder = new ImageCapture.Builder();


        // Creates an ImageCapture extender according to the effect mode

        ImageCaptureExtender imageCaptureExtender = new BokehImageCaptureExtender

                .create(imageCaptureBuilder);


        // Checks the effect availability and enables the extension mode

        if (imageCaptureExtender.isExtensionAvailable(DEFAULT_BACK_CAMERA)) {

            imageCaptureExtender.enableExtension(DEFAULT_BACK_CAMERA);

        }


        useCases.add(imageCaptureBuilder.build());


        // Binds use cases with the extension enabled camera selector

        mCameraProvider.bindToLifecycle(lifecycleOwner, DEFAULT_BACK_CAMERA, 

        useCases);

    } catch (ExecutionException | InterruptedException e) {

        // This should not happen unless the future is cancelled or the thread is 

        // interrupted by applications.

    }

}, ContextCompat.getMainExecutor(context));

 

Please start using the new Extensions API and let us know your feedback about it. You can also check our CameraX extensions API guides here

 

Please also note that the camera-extensions library depends on the latest version of 1.1.0 core/camera2/lifecycle libraries which are released at the same time. So if you declare core/camera2/lifecycle dependencies that are older in your build.gradle, these will be overridden by camera-extensions dependencies.


If you have any further questions, please reach out to the development team at camerax-d...@android.com or file an issue with us at http://bit.ly/39L3VvX.


Thank you,
- Julie on behalf of CameraX development team

Reply all
Reply to author
Forward
0 new messages