CameraX is a API Wrapper which simplifies Camera2 API in android. Even though the pipiined stucture in Camera2 is really efficient, the usability and simplicity of Camera API [Deprecated] are lost. This API aims to bring them back !
This repo is divided into 2 sections -
This picture sums up the whole working of Camera2 API really well.
Basically the steps followed for performing any camera related task are -
First things first We will be using the following objects for all the camera tasks.
- cameraManager - Helps to browse the availabe hardware to choose the appropriate camera device.
- cameraCharacterstics - Stores the hardware properties of each camera device.
- cameraId - Stores the ID of the camera.
- cameraDevice - Stores the camera instance.
{
CameraManger cameraManger = null;
CameraCharacterstics cameraCharacterstics = null;
String cameraId = null;
CameraDevice cameraDevice = null;
}
1. Obtain a CameraManager instance
- Get details of all the available camera devices.
- Details are stored as CameraCharacterstics objects.
- Choose the most suitable camera device and store its ID.
cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
for (String id : cameraId) {
cameraCharacteristics = cameraManager.getCameraCharacteristics(camId);
if ( ... suitable ... ) {
cameraId = id;
break;
}
}
2. Use the CameraManages instance to Open the camera device
- Needs a CameraDevice.StateCallback to handle what happends once a camera is opened or couldn't be opened.
- Upon opening, store the reference to the Camera Device given in the callback.
cameraManager.openCamera(camId, new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
// We'll be using this camera device for all the tasks.
cameraDevice = camera;
.
. // Use this cameraDevice to perform the required action.
.
}
}, null);
3. Use the obtained camera device to create a CaptureRequest1
Capture request has details regarding the type of capture being made.
- To create it, a list of surfaces have to be given, ones which will show the output from the camera.
- Use a CaptureRequest.Builder to build a request.
- Add each surface as a target, to the builder.
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// Add targets to the builder.
for (Surface surface : surfaces)
builder.addTarget(surface);
// Build and return the request.
return builder.build();
4. Use this request to create a capture session
Capture session needs a capture request, a CameraCaptureSession.StateCallback and a handler.
- Create a state callback to handle the session status.
- Upon successfull configuration, use the session to set a repeating/burst request.
- While doing it, another callback has to passed which is the one that deals with the final capture result.
CameraCaptureSession.StateCallback callback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
captureSession = session;
try {
session.setRepeatingRequest(request, captureCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
captureSession = null;
}
};
Capture callback takes care of the data that comes from the camera device.
CameraCaptureSession.CaptureCallback callback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession ses, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
// The result stores all the goodness that we want.
}
};
Even thought this pipelines architecture is very clear and tweak-able, using camera for simple applications could be a overhead.Now lets have a look at CameraX!
1. Create a CameraX instance
Constructor needs the current activity for context, a name for the camera instance and an integer specifying which camera will be used by the object. (Front/Back which is stored as a constant in the CameraX class)
// Inside an AppCompatActivity Subclass
CameraX camera = new CameraX(this, "Camera-Name", CameraX.CAMERA_BACK);
- Instance Name is used for debugging purposes and is included in the debug log messages.
2. Set the output surfaces
Provide a List of Objects that store the outputs surfaces ( either SurfaceViews or TextureViews ). Camera2 API requires conversion of the output screens into surfaces but CameraX does it for you.
SurfaceView s = (SurfaceView) findViewById(R.id.surfaceView);
TextureView t = (TextureView) findViewById(R.id.textureView);
List<Object> surfaces = new ArrayList<>(2);
surfaces.add(s);
surfaces.add(t);
// Pass this list to the cameraX instance.
cameraX.setOutputSurfaces(surfaces);
3. Create a live preview
To create a live preview, the only thing you need to do is call startLivePreview!
- You can pass a CameraCaptureSession.CaptureCallback to startLivePreview in case you want to use the output feed from the camera during the preview.
// Defualt capture callback automatically provided.
cameraX.startLivePreview(null);
cameraX.pauseLivePreview(null);
// Do something
cameraX.resumeLivePreview(null);
cameraX.stopLivePreview(null);
- As shown above, you can pause, resume and stop the preview with simple calls.
- Currently CameraX is in its infancy. New features will be added over time.
- Definitely easier to use that Camera2 ( for simple applications that use the camera )
- Not the most efficient but will definitely get better over time.
Currently only live preview is supported but in future the following will be added. Feel free to contribute your own features! I'd love to see them.
- Picture Capture
- Video Capture
- Burst Shots
- Full control over camera
Gooood day! 🍰🍰🍰
License CC-BY