DEV Community

Cover image for Capture With cameraX
Apoorv Nath Mishra
Apoorv Nath Mishra

Posted on

Capture With cameraX

Hello Readers! This was the first time I was gonna write something on Medium. After roaming around for a month and drowning in numerous topics, I thought why not explore our little (aah! not so little) android.

Nowadays, the hot talk in android is about and around the Jetpack Support Library, and why not, it has given the developers a seamless workflow and extensive control over what they design, without being frustrated about the device-specific nuisance.
Today, I shall get you a tour of the workflow of a very recent addition to the jetpack library family that's the cameraX (hurrey!!!!!).

Dependencies & Permissions

In the dependency block of the build.gradle(Module:app) file in the Gradle Scripts, add the following snippet.

def camerax_version = “1.0.0-beta07”
implementation “androidx.camera:camera-camera2:$camerax_version”
implementation “androidx.camera:camera-lifecycle:$camerax_version”
implementation “androidx.camera:camera-view:1.0.0-alpha14”
Enter fullscreen mode Exit fullscreen mode

Also, make sure to check for the compile options to be,

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
Enter fullscreen mode Exit fullscreen mode

Finally, in the AndroidManifest.xml file, add the user-permissions as,

<uses-feature android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />
Enter fullscreen mode Exit fullscreen mode

Sync the Gradle, and then you are good to go with your work.

Prompt User-Permissions

If the user doesn’t give above-mentioned permissions to the app, nothing will work, hence with the launch of the app first check for the permissions and then proceed.

Check if permissions granted, if yes, start camera, else, request for permissions.

private final String[] REQUIRED_PERMISSIONS = new String[]{"android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE"};
private int REQUEST_CODE_PERMISSIONS = 1001;
private boolean allPermissionsGranted(){

    for(String permission : REQUIRED_PERMISSIONS){
        if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){
            return false;
        }
    }
    return true;
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    if(requestCode == REQUEST_CODE_PERMISSIONS){
        if(allPermissionsGranted()){
            startCamera();
        } else{
            Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show();
            this.finish();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, once we have all the required permissions, we shall start the camera, for that implement the startCamera() function.

startCamera()

Now we shall work over the Activity class for camera.

PreviewView mPreviewView;
final ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
Enter fullscreen mode Exit fullscreen mode

Now, inside the onCreate() method, initialize the instance variables and bind a camera provider so that we can bind the image analysis case to it.

private void startCamera() {

    final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);

    cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                // No errors need to be handled for this Future.
                // This should never be reached.
            }

    }, ContextCompat.getMainExecutor(this));
}
Enter fullscreen mode Exit fullscreen mode

Now, we shall bind the image analysis to the camera provider created in the onCreate method and listens for changes in the camera’s rotation.

bindPreview(ProcessCameraProvider)
void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
    Preview preview = new Preview.Builder()
            .build();

    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(camInstance)
            //.requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

    ImageAnalysis imageAnalysis = new ImageAnalysis.Builder().build();

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

    ImageCapture imageCapture = builder.build();

    preview.setSurfaceProvider(mPreviewView.getSurfaceProvider());

    Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview, imageCapture);
}
Enter fullscreen mode Exit fullscreen mode

Now finally, if we look into the output results, in the Camera Activity, we can see the camera-enabled.

Finally, we shall work on the capturing of the image.

Image Capture

The image capture use case is designed for capturing high-resolution, high-quality photos and provides auto-white-balance, auto-exposure, and auto-focus (3A) functionality, in addition to simple manual camera controls. The caller is responsible for deciding how to use the captured picture, including the following options:

  • takePicture(Executor, OnImageCapturedCallback): This method provides an in-memory buffer of the captured image.
  • takePicture(OutputFileOptions, Executor, OnImageSavedCallback): This method saves the captured image to the provided file location.

This time, we shall work on the second caller constructor.

imageCapture(outputFileOptions, executor, new ImageCapture.OnImageSavedCallback () {})

File file = new File(mDateFormat.format(new Date())+ ".jpg");
ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(file).build();
imageCapture.takePicture(outputFileOptions, executor, new ImageCapture.OnImageSavedCallback () {
   @Override
   public void onImageSaved(@NonNull ImageCapture.OutputFileResults      outputFileResults) {
    new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() { 
       //do whatever you want with the image saved in <file>.
 }
    });
}
@Override
public void onError(@NonNull ImageCaptureException error) {
    error.printStackTrace();
}
});
Enter fullscreen mode Exit fullscreen mode

I have not mentioned anything about the activity layouts.
Refer to my GitHub repo for the same, in case you need more insights.


I hope you might find this article worthy assistant for beginning with CameraX.
Drop your suggestions, for this, is my first article here :)

Top comments (0)