Camera equipment has played an important role in driving innovation on mobile devices, and camera exposure is a key factor in producing exceptional quality photos. In this article, I’ll break down some of the challenges that mobile developers face when dealing with camera exposure. Later, I’ll talk about how the new CameraX Exposure Compensation API can help developers address these challenges and make it easier to take high-quality photos quickly. Finally, I’ll show you how to use the API in your application.

background

In photography, exposure is one of the most important factors in determining the final image of the camera, so most photographers strive to optimize exposure. Automatic Exposure (AE) works well for most common shooting scenarios, such as automatic quick shots. However, under certain conditions, AE mode will make some compromises for the overall quality of the photo, and these compromises may not be what you want. One example is backlighting, for example, if you’re inside and facing a window or other light source, or outside with the sun just behind your subject. In these scenes, AE mode exposes the image properly for the bright background (the highlighted area of the photo), but subjects in the dark foreground become too dim or become silhouettes. Figure 1 shows three photos taken under the same conditions (indoor backlight) with different exposures.

AE does a good job of controlling the overall quality of the photos, but the higher exposure does capture more detail of the Android figures.

Traditionally, the photographer achieves a satisfactory exposure by adjusting three parameters:

  • Aperture: The opening of the lens, which controls the amount of light allowed into the camera
  • Shutter speed: The duration of exposure of a photograph
  • ISO (International Organization for Standardization): The sensitivity of a camera’s sensor to captured light

Each parameter has a special effect on the image: aperture can adjust the depth of field effect, shutter speed can blur the process of motion or freeze the moment of motion, and a higher ISO can increase the noise of the image. There is a fair amount of mathematical precision involved, but different combinations of these parameters can produce the same overall exposure and, in the process, a high level of perfect exposure. To assist in compensating exposure, CameraX implements an exposure compensation API.

Implement the exposure compensation API

The exposure compensation API adjusts the exposure compensation degree through the exposure compensation index according to the generated automatic exposure value. The exposure compensation index can be positive (to increase the brightness of the photo) or negative (to decrease the brightness of the photo). It maps the overall exposure range to the value range of the compensation index and the total exposure to the EV step. The camera device internally changes the exposure based on the exposure index, reducing the need to control other parameters and achieving the same effect.

In Figure 1, for example, the camera’s default configuration does not provide enough brightness for the subject we want to focus on, so we can use a positive exponential exposure compensation configuration to get double or quadruple exposure to highlight the subject. By changing the exposure compensation index, the camera internally controls the shutter speed, aperture and ISO to get the right exposure.

To get the compensation index, CameraX implements the following:

  1. CameraControl: : setExposureCompensationIndex, exposure compensation is used to set a new index.

  2. ExposureState for exposure compensation performance and current configuration, including:

  3. Support adjustment compensation

  4. The range of compensation supported

  5. The supported compensation step size

  6. Current compensation index value

Let’s take a look at how you can use the API in the CameraX app to create properly exposed photos.

Use the Exposure compensation API

To use the exposure compensation API in your application, you need to:

  • Query the exposure compensation range
  • Sets the new exposure compensation index
  • Continue after CameraX confirms

Query the exposure compensation index range

The range of exposure compensation depends on the configuration and hardware level of camera equipment. Applications can query supported value ranges on the ExposureState interface.

valCamera = cameraProvider. BindToLifecycle (...).val range = camera.cameraInfo.exposureState.exposureCompensationRange
Copy the code

Sets the new exposure compensation index

If the photo appears dark, set a positive exposure compensation index to increase the brightness based on the camera’s original corrected exposure. Similarly, if the photo looks too bright, set a negative value. This can be achieved by setExposureCompensationIndex () to implement:

interface CameraControl {
    fun setExposureCompensationIndex(value: Int): ListenableFuture<Int!>
}
Copy the code

By default, the value of the exposure compensation index starts at “0” and the new index value must vary within the range supported by the camera equipment. Otherwise CameraX will throw an IllegalArgument error. Note that if the camera does not support exposure compensation adjustment, the range of values returned by CameraX is [0,0].

For example, the following code increases the exposure compensation index when the user clicks a button in the UI until the exposure index reaches the maximum supported value:

var exposureIndex = 0
val camera = cameraProvider.bindToLifecycle(
    lifecycleOwner,
    getCameraSelector(),
    preview,
    imageCapture,
)

evButton.setOnClickListener {
    val range = camera.cameraInfo.exposureState.exposureCompensationRange
    if (range.contains(exposureIndex + 1)) {
        camera.cameraControl.setExposureCompensationIndex(++exposureIndex)
        val ev = camera.cameraInfo.exposureState.exposureCompensationStep.toFloat() * exposureIndex
        Log.i("CameraXLog"."EV: $ev")}}Copy the code

SetExposureCompensationIndex () is async function, each camera can only respond to a pending request. If the application before the call before was not response called again setExposureCompensationIndex (), request, before the new call request will replace the previous request will be cancelled and throw OperationCanceledException. Typically, the new index value is quickly enabled, and the exposure of the output stream changes with the binding use case. If the application needs to know the exact execution time and result of a particular request, it can register listeners on top of the ListenableFuture returned by the function.

Correlation compensation index and Exposure Value (EV)

The exposure value (EV) is a unit of measure used to indicate the difference in illuminance for exposure compensation. +1 EV means twice as much light, +2 EV means four times as much, and so on. Applications can apply the same exposure value to different cameras, or even different devices, to achieve similar exposures, but applications should not directly use the same index value for the same target effect, because each index value is unique to the camera.

In the compensation API, the exposure value is calculated by the following formula:

EV = exposure_compensation_index * compensation_step

The compensation_step mentioned in the formula above is the minimum unit of exposure that can be modified. Note that compensation_step also relies on camera equipment. You can query the compensation_step on ExposureState and calculate the exposure values as shown below:

valCamera = cameraProvider. BindToLifecycle (...).val exposureValue = camera.cameraInfo.exposureState.exposureCompensationStep.toFloat() * exposureIndex
Copy the code

For example, if exposure_compensation_index is equal to 6, and compensation_step is equal to the one-third of exposure, the exposure compensation is calculated as +2 EV, or twice the default exposure.

The step_size one-third of compensation_step is usually used, or ½, although occasionally, some devices may support 1 or even ¼. The maximum exposure supported is generally 2 EV or 3 EV.

Availability of the CameraX exposure compensation API

The Exposure compensation API was first released experimentally in Android. Camera: Camera-Core :1.0.0-beta09.

The API completed its experimental phase in version Android. Camera: Camera-Core: 1.0-alpha06 and became part of the official CameraX API.

For the latest release, check out the official CameraX release notes.

conclusion

Sample code for CameraX exposure compensation can be found on GitHub. Combined with other parts of the CameraX API, the Exposure compensation API can help developers create creative Android camera applications and stand out in the sea of mobile apps. If you’re interested in learning more about CameraX, check out the official documentation, and join the CameraX discussion group if you want to keep up to date with the latest developments. You are welcome to share your comments with us in the CameraX discussion group, or create CameraX Issues to submit your questions.

reading

  • setExposureCompensationIndex API
  • ExposureState API
  • CameraX version description
  • Codelab: Getting started with CameraX
  • Making the sample

Please click here to submit your feedback to us, or share your favorite content or questions. Your feedback is very important to us, thank you for your support!