Android CameraX: Control and Query the Camera.
Introduction
Since its announcement and Alpha launch during this year’s Google I/O, there’s been a lot of excitement around CameraX, which is part of the Jetpack suite of libraries that aim to help developers build high quality apps easier. This post takes a step back from CameraX’s use cases, and goes over a couple of APIs that allow querying and controlling the camera.
If you’re new to CameraX or would like a refresher, check out this article.
Control the Camera
An API that allows you to control the camera directly, which in consequence affects the output of all bound use cases. CameraControl
can be used to configure the camera’s zoom, exposure compensation, focus and metering and enabling or disabling the torch (if the camera supports it).
CameraControl
can immediately be used after getting a Camera
instance. Yet the operations it provides are asynchronous, and uses the ListenableFuture
API to provide callbacks for the operation’s success or failure.
Query the Camera
An API that allows querying the camera to retrieve information about it. It provides the following information:
- Zoom state: Wraps information about the current zoom ratio and linear zoom, as well as the min and max zoom values the camera supports.
- Torch state and flash availability:
CameraInfo
provides the state of the camera’s torch, which is either on or off, and allows querying whether the camera supports flash. - Exposure state: Provides information about the camera’s exposure compensation, such as its index, range and step. The exposure compensation index and step define the camera’s exposure value as follows:
Exposure Value = Exposure Index * Exposure Step
- Sensor rotation:
CameraInfo
provides the camera’s sensor rotation in degrees both relative to the device’s natural orientation (Portrait in general, but can also be landscape for wide device, like tablets) and relative to a given rotation.
CameraInfo
provides most of the above information wrapped in LiveData
, this allows you to continually observe their changes. If you only need the current value of one of them, you can use LiveData.getValue()
.
Tap-To-Focus
Autofocus is provided by default when using CameraX, but you can also manually specify the region the camera should focus on. This can be done with the help of the MeteringPointFactory
class, which allows converting coordinates from a Surface (e.g. the preview Surface) into a MeteringPoint
with corresponding camera sensor coordinates.
Tap-to-focus is dependent on a viewfinder. CameraX’s recommended viewfinder API, PreviewView
provides a MeteringPointFactory
out of the box which allows converting UI coordinates into camera sensor coordinates. You can use it to focus on tapped regions on the viewfinder.
A couple of things are happening here.
- An
OnTouchListener
is attached to the camera’s viewfinder, where only events of typeACTION_UP
are handled. This event is received at the end of the tap gesture, once the pointer (e.g. the finger) is raised off the screen. - Using the coordinates of the tap, a
MeteringPoint
is created using theMeteringPointFactory
fromPreviewView
. This factory takes in a set of preview coordinates, and creates aMeteringPoint
that specifies a region in sensor coordinates for focusing and/or metering. This conversion takes into account the device’s orientation and any transformations that are applied to the camera preview such as cropping, translation and rotation. - A
FocusMeteringAction
is then created in order to configure and trigger a focus and/or metering action, this action takes in one or multiple focus/metering areas, and optionallyMeteringMode
s that specify how these areas are used for 3A (auto focus, auto exposure, auto white balancing) regions. - The
FocusMeteringAction
is then passed toCameraControl
in order to initiate the focus and metering action. Since this is an asynchronous operation, aListenableFuture
is returned. You can use it to be notified when the focus and metering action finishes successfully or fails. You can also use this as a signal if you’re displaying a focus animation, such as fading in, displaying then fading out a focus ring around the focus region.
Pinch-To-Zoom
CameraX allows you to enable pinch-to-zoom, where the camera zooms in and out depending on how the user pinches the viewfinder. The implementation is straightforward, and requires attaching a ScaleGestureDetector
to the viewfinder.
Below is an example demonstrating pinch-to-zoom with PreviewView
.
In the snippet above:
- An
OnTouchListener
is attached to the viewfinder. Each incoming event is passed to aScaleGestureDetector
. - A
ScaleGestureDetector
is created using a context and anOnGestureDetectedListener
. - Inside the
OnScaleGestureListener
is where the camera’s zoom ratio is updated. The current camera zoom ratio is retrieved usingCameraInfo
, and then multiplied by the gesture’s scale delta, which represents by how much the scale has changed, and depends on the pinch gesture. The result is passed toCameraControl.setZoomRatio()
, which updates both the zoom ratio and linear zoom value, as thus changes the output of the preview (and any other bound use cases).
Zoom Slider
CameraX provides a way to enable zooming in and out using a slider, where the zoom changes linearly between the min zoom and max zoom, represented by 0 and 1 respectively.
In the snippet above, a SeekBar
is used as a slider, its value ranges from 0 to 100. CameraControl.setZoomPercentage()
expects a -float- value between 0 and 1. Calling this method updates the preview and both the zoom ratio and percentage used by the camera.
Conclusion
In summary:
- Control the camera independently of the use cases using the high level
CameraControl
class. Any changes made throughCameraControl
, such as updating the zoom ratio, affects the output of all the bound use cases. - Query camera related information and observe their changes using
CameraInfo
. It allows retrieving the camera’s zoom ratio, torch state, and much more. - Have more control over focus regions by implementing tap-to-focus, it’s simple to sett up using CameraX’s recommender viewfinder,
PreviewView
. - Zoom in and out of the camera by either implementing pinch-to-zoom or using a zoom slider.
Want more CameraX goodness? Check out: