--- layout: page title: "Metering" subtitle: "Exposure and metering controls" description: "Exposure and metering controls" category: docs order: 4 date: 2019-09-04 19:39:03 disqus: 1 --- In CameraView grammar, metering is the act of measuring the scene brightness, colors and focus distance in order to automatically adapt the camera exposure, focus and white balance (AE, AF and AWB, often referred as 3A). We treat three different types on metering: [continuous metering](#continuous-metering), [picture metering](#picture-metering) and [touch metering](#touch-metering). You can also apply adjustment to the metered exposure through the [exposure correction](#exposure-correction) control. ### Continuous Metering By default, and if the device supports it, all three routines (AE, AF, AWB) are continuously metered as the device moves or the scene changes. - For AE, this is always enabled if supported - For AF, this is always enabled if supported - For AWB, this is enabled if the `WhiteBalance` parameter is set to `AUTO` [[docs]](#controls.html#camerawhitebalance) ### Picture Metering *In Camera1, picture metering is always enabled for pictures, and always disabled for picture snapshots. The following applies to Camera2 only.* The camera engine will try to trigger metering when a picture is requested, either with `takePicture()` or `takePictureSnapshot()`. This has two obvious consequences: - improves the picture quality - increases the latency, because metering takes time For these reasons, picture metering is **enabled** by default for HQ pictures and **disabled** by default for picture snapshots. However, the behavior can be changed with two flags and their respective XML attributes: ```java cameraView.setPictureMetering(true); // Meter before takePicture() cameraView.setPictureMetering(false); // Don't cameraView.setPictureSnapshotMetering(true); // Meter before takePictureSnapshot() cameraView.setPictureSnapshotMetering(false); // Don't ``` ### Touch Metering Touch metering is triggered by either a [Gesture](gestures.html) or by the developer itself, which can start touch metering on a specific point with the `startAutoFocus(float, float)` API. This action needs the coordinates of a point computed with respect to the view width and height. In both cases, the metering callbacks will be triggered: ```java cameraView.addCameraListener(new CameraListener() { @Override public void onAutoFocusStart(@NonNull PointF point) { // Touch metering was started by a gesture or by startAutoFocus(float, float). // The camera is currently trying to meter around that area. // This can be used to draw things on screen. } @Override public void onAutoFocusEnd(boolean successful, @NonNull PointF point) { // Touch metering operation just ended. If successful, the camera will have converged // to a new focus point, and possibly new exposure and white balance as well. // The point is the same that was passed to onAutoFocusStart. } }); ``` Touch metering is not guaranteed to be supported: check the `CameraOptions` to be sure. ##### Touch Metering Markers You can set a marker for drawing on screen in response to touch metering events. In XML, you should pass the qualified class name of your marker. ```java cameraView.setAutoFocusMarker(null); cameraView.setAutoFocusMarker(marker); ``` We offer a default marker (similar to the old `focusWithMarker` attribute in v1), which you can set in XML using the `@string/cameraview_default_autofocus_marker` resource, or programmatically: ```java cameraView.setAutoFocusMarker(new DefaultAutoFocusMarker()); ``` ##### Touch Metering Reset Delay You control control how a touch metering operation is reset after completed. Setting a value <= 0 or == Long.MAX_VALUE will not reset the metering values. This is useful for low end devices that have slow auto-focus capabilities. Defaults to 3 seconds. ```java cameraView.setCameraAutoFocusResetDelay(1000); // 1 second cameraView.setCameraAutoFocusResetDelay(0); // NO reset cameraView.setCameraAutoFocusResetDelay(-1); // NO reset cameraView.setCameraAutoFocusResetDelay(Long.MAX_VALUE); // NO reset ``` ### Exposure correction There are two ways to control the exposure correction value: - User can change the exposure correction with a [Gesture](gestures.html) - The developer can change this value with the `setExposureCorrection(float)` API, passing in the EV value, in camera stops. This value should be contained in the minimum and maximum supported values, as returned by `CameraOptions`. Both actions will trigger the exposure correction callback, which can be used, for example, to draw a seek bar: ```java cameraView.addCameraListener(new CameraListener() { @UiThread public void onExposureCorrectionChanged(float newValue, @NonNull float[] bounds, @Nullable PointF[] fingers) { // newValue: the new correction value // bounds: min and max bounds for newValue, as returned by CameraOptions // fingers: finger positions that caused the event, null if not caused by touch } }); ``` EV correction is not guaranteed to be supported: check the `CameraOptions` to be sure. ### Related XML Attributes ```xml ``` ### Related APIs |Method|Description| |------|-----------| |`setPictureMetering(boolean)`|Whether the engine should trigger 3A metering when a picture is requested. Defaults to true.| |`setPictureSnapshotMetering(boolean)`|Whether the engine should trigger 3A metering when a picture snapshot is requested. Defaults to false.| |`startAutoFocus(float, float)`|Starts the 3A touch metering routine at the given coordinates, with respect to the view system.| |`CameraOptions.isAutoFocusSupported()`|Whether touch metering (metering with respect to a specific region of the screen) is supported.| |`setExposureCorrection(float)`|Changes the exposure adjustment, in EV stops. A positive value means a brighter picture.| |`CameraOptions.getExposureCorrectionMinValue()`|The minimum value of negative exposure correction, in EV stops.| |`CameraOptions.getExposureCorrectionMaxValue()`|The maximum value of positive exposure correction, in EV stops.|