Add cameraPictureMetering and cameraPictureSnapshotMetering

pull/580/head
Mattia Iavarone 6 years ago
parent a8fddc482f
commit f7e9372caf
  1. 19
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  2. 125
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  3. 18
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
  4. 4
      cameraview/src/main/res/values/attrs.xml

@ -171,7 +171,10 @@ public class CameraViewTest extends BaseTest {
// Self managed
GestureParser gestures = new GestureParser(empty);
assertEquals(cameraView.getPlaySounds(), CameraView.DEFAULT_PLAY_SOUNDS);
assertEquals(cameraView.getAutoFocusResetDelay(), CameraView.DEFAULT_AUTOFOCUS_RESET_DELAY_MILLIS);
assertEquals(cameraView.getUseDeviceOrientation(), CameraView.DEFAULT_USE_DEVICE_ORIENTATION);
assertEquals(cameraView.getPictureMetering(), CameraView.DEFAULT_PICTURE_METERING);
assertEquals(cameraView.getPictureSnapshotMetering(), CameraView.DEFAULT_PICTURE_SNAPSHOT_METERING);
assertEquals(cameraView.getGestureAction(Gesture.TAP), gestures.getTapAction());
assertEquals(cameraView.getGestureAction(Gesture.LONG_TAP), gestures.getLongTapAction());
assertEquals(cameraView.getGestureAction(Gesture.PINCH), gestures.getPinchAction());
@ -649,6 +652,22 @@ public class CameraViewTest extends BaseTest {
assertFalse(cameraView.getUseDeviceOrientation());
}
@Test
public void testSetPictureMetering() {
cameraView.setPictureMetering(true);
assertTrue(cameraView.getPictureMetering());
cameraView.setPictureMetering(false);
assertFalse(cameraView.getPictureMetering());
}
@Test
public void testSetPictureSnapshotMetering() {
cameraView.setPictureSnapshotMetering(true);
assertTrue(cameraView.getPictureSnapshotMetering());
cameraView.setPictureSnapshotMetering(false);
assertFalse(cameraView.getPictureSnapshotMetering());
}
@Test
public void testSetFlash() {
cameraView.set(Flash.TORCH);

@ -107,6 +107,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
final static long DEFAULT_AUTOFOCUS_RESET_DELAY_MILLIS = 3000;
final static boolean DEFAULT_PLAY_SOUNDS = true;
final static boolean DEFAULT_USE_DEVICE_ORIENTATION = true;
final static boolean DEFAULT_PICTURE_METERING = true;
final static boolean DEFAULT_PICTURE_SNAPSHOT_METERING = false;
// Self managed parameters
private boolean mPlaySounds;
@ -182,6 +184,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
int videoBitRate = a.getInteger(R.styleable.CameraView_cameraVideoBitRate, 0);
int audioBitRate = a.getInteger(R.styleable.CameraView_cameraAudioBitRate, 0);
long autoFocusResetDelay = (long) a.getInteger(R.styleable.CameraView_cameraAutoFocusResetDelay, (int) DEFAULT_AUTOFOCUS_RESET_DELAY_MILLIS);
boolean pictureMetering = a.getBoolean(R.styleable.CameraView_cameraPictureMetering, DEFAULT_PICTURE_METERING);
boolean pictureSnapshotMetering = a.getBoolean(R.styleable.CameraView_cameraPictureSnapshotMetering, DEFAULT_PICTURE_SNAPSHOT_METERING);
// Size selectors and gestures
SizeSelectorParser sizeSelectors = new SizeSelectorParser(a);
@ -228,6 +232,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setAudio(controls.getAudio());
setAudioBitRate(audioBitRate);
setPictureSize(sizeSelectors.getPictureSizeSelector());
setPictureMetering(pictureMetering);
setPictureSnapshotMetering(pictureSnapshotMetering);
setVideoSize(sizeSelectors.getVideoSizeSelector());
setVideoCodec(controls.getVideoCodec());
setVideoMaxSize(videoMaxSize);
@ -280,7 +286,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Instantiates the camera engine.
*
@ -547,7 +552,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return false;
}
/**
* Clears any action mapped to the given gesture.
* @param gesture which gesture to clear
@ -556,7 +560,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mapGesture(gesture, GestureAction.NONE);
}
/**
* Returns the action currently mapped to the given gesture.
*
@ -569,13 +572,11 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mGestureMap.get(gesture);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true; // Steal our own events.
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
@ -598,7 +599,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return true;
}
// Some gesture layout detected a gesture. It's not known at this moment:
// (1) if it was mapped to some action (we check here)
// (2) if it's supported by the camera (CameraEngine checks)
@ -691,7 +691,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mLifecycle.addObserver(this);
}
/**
* Starts the camera preview, if not started already.
* This should be called onResume(), or when you are ready with permissions.
@ -708,7 +707,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Checks that we have appropriate permissions.
* This means checking that we have audio permissions if audio = Audio.ON.
@ -736,7 +734,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return true;
}
/**
* If audio is on we will ask for RECORD_AUDIO permission.
* If the developer did not add this to its manifest, throw and fire warnings.
@ -760,7 +757,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Stops the current preview, if any was started.
* This should be called onPause().
@ -772,7 +768,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
if (mCameraPreview != null) mCameraPreview.onPause();
}
/**
* Destroys this instance, releasing immediately
* the camera resource.
@ -865,7 +860,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Controls the preview engine. Should only be called
* if this CameraView was never added to any window
@ -959,7 +953,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getCameraOptions();
}
/**
* Sets exposure adjustment, in EV stops. A positive value will mean brighter picture.
*
@ -985,7 +978,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Returns the current exposure correction value, typically 0
* at start-up.
@ -995,7 +987,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getExposureCorrectionValue();
}
/**
* Sets a zoom value. This is not guaranteed to be supported by the current device,
* but you can take a look at {@link CameraOptions#isZoomSupported()}.
@ -1012,7 +1003,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setZoom(zoom, null, false);
}
/**
* Returns the current zoom value, something between 0 and 1.
* @return the current zoom value
@ -1021,7 +1011,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getZoomValue();
}
/**
* Controls the grids to be drawn over the current layout.
*
@ -1036,7 +1025,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mGridLinesLayout.setGridMode(gridMode);
}
/**
* Gets the current grid mode.
* @return the current grid mode
@ -1046,7 +1034,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mGridLinesLayout.getGridMode();
}
/**
* Controls the color of the grid lines that will be drawn
* over the current layout.
@ -1077,7 +1064,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setHdr(hdr);
}
/**
* Gets the current hdr value.
* @return the current hdr value
@ -1087,7 +1073,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getHdr();
}
/**
* Set location coordinates to be found later in the EXIF header
*
@ -1103,7 +1088,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setLocation(location);
}
/**
* Set location values to be found later in the EXIF header
*
@ -1113,7 +1097,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setLocation(location);
}
/**
* Retrieves the location previously applied with setLocation().
*
@ -1124,7 +1107,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getLocation();
}
/**
* Sets desired white balance to current camera session.
*
@ -1140,7 +1122,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setWhiteBalance(whiteBalance);
}
/**
* Returns the current white balance behavior.
* @return white balance value.
@ -1150,7 +1131,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getWhiteBalance();
}
/**
* Sets which camera sensor should be used.
*
@ -1163,7 +1143,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setFacing(facing);
}
/**
* Gets the facing camera currently being used.
* @return a facing value.
@ -1173,7 +1152,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getFacing();
}
/**
* Toggles the facing value between {@link Facing#BACK}
* and {@link Facing#FRONT}.
@ -1195,7 +1173,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getFacing();
}
/**
* Sets the flash mode.
*
@ -1210,7 +1187,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setFlash(flash);
}
/**
* Gets the current flash mode.
* @return a flash mode
@ -1220,7 +1196,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getFlash();
}
/**
* Controls the audio mode.
*
@ -1250,7 +1225,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Gets the current audio value.
* @return the current audio value
@ -1260,7 +1234,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getAudio();
}
/**
* Sets an {@link AutoFocusMarker} to be notified of autofocus start, end and fail events
* so that it can draw elements on screen.
@ -1272,7 +1245,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mMarkerLayout.onMarker(MarkerLayout.TYPE_AUTOFOCUS, autoFocusMarker);
}
/**
* Sets the current delay in milliseconds to reset the focus after an autofocus process.
*
@ -1284,7 +1256,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setAutoFocusResetDelay(delayMillis);
}
/**
* Returns the current delay in milliseconds to reset the focus after an autofocus process.
* @return the current autofocus reset delay in milliseconds.
@ -1292,7 +1263,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
@SuppressWarnings("unused")
public long getAutoFocusResetDelay() { return mCameraEngine.getAutoFocusResetDelay(); }
/**
* Starts an autofocus process at the given coordinates, with respect
* to the view width and height.
@ -1306,7 +1276,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.startAutoFocus(null, new PointF(x, y));
}
/**
* <strong>ADVANCED FEATURE</strong> - sets a size selector for the preview stream.
* The {@link SizeSelector} will be invoked with the list of available sizes, and the first
@ -1328,7 +1297,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setPreviewStreamSizeSelector(selector);
}
/**
* Set the current session type to either picture or video.
*
@ -1341,7 +1309,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setMode(mode);
}
/**
* Gets the current mode.
* @return the current mode
@ -1351,7 +1318,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getMode();
}
/**
* Sets a capture size selector for picture mode.
* The {@link SizeSelector} will be invoked with the list of available sizes, and the first
@ -1364,6 +1330,61 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setPictureSizeSelector(selector);
}
/**
* Whether the engine should perform a metering sequence before taking pictures requested
* with {@link #takePicture()}. A metering sequence includes adjusting focus, exposure
* and white balance to ensure a good quality of the result.
*
* When this parameter is true, the quality of the picture increases, but the latency
* increases as well. Defaults to true.
*
* This is a CAMERA2 only API. On CAMERA1, picture metering is always enabled.
*
* @see #setPictureSnapshotMetering(boolean)
* @param enable true to enable
*/
public void setPictureMetering(boolean enable) {
mCameraEngine.setPictureMetering(enable);
}
/**
* Whether the engine should perform a metering sequence before taking pictures requested
* with {@link #takePicture()}. See {@link #setPictureMetering(boolean)}.
*
* @see #setPictureMetering(boolean)
* @return true if picture metering is enabled
*/
public boolean getPictureMetering() {
return mCameraEngine.getPictureMetering();
}
/**
* Whether the engine should perform a metering sequence before taking pictures requested
* with {@link #takePictureSnapshot()}. A metering sequence includes adjusting focus,
* exposure and white balance to ensure a good quality of the result.
*
* When this parameter is true, the quality of the picture increases, but the latency
* increases as well. To keep snapshots fast, this defaults to false.
*
* This is a CAMERA2 only API. On CAMERA1, picture snapshot metering is always disabled.
*
* @see #setPictureMetering(boolean)
* @param enable true to enable
*/
public void setPictureSnapshotMetering(boolean enable) {
mCameraEngine.setPictureSnapshotMetering(enable);
}
/**
* Whether the engine should perform a metering sequence before taking pictures requested
* with {@link #takePictureSnapshot()}. See {@link #setPictureSnapshotMetering(boolean)}.
*
* @see #setPictureSnapshotMetering(boolean)
* @return true if picture metering is enabled
*/
public boolean getPictureSnapshotMetering() {
return mCameraEngine.getPictureSnapshotMetering();
}
/**
* Sets a capture size selector for video mode.
@ -1425,7 +1446,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mListeners.add(cameraListener);
}
/**
* Remove a {@link CameraListener} that was previously registered.
*
@ -1435,7 +1455,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mListeners.remove(cameraListener);
}
/**
* Clears the list of {@link CameraListener} that are registered
* to camera events.
@ -1444,7 +1463,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mListeners.clear();
}
/**
* Adds a {@link FrameProcessor} instance to be notified of
* new frames in the preview stream.
@ -1460,7 +1478,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Remove a {@link FrameProcessor} that was previously registered.
*
@ -1475,7 +1492,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Clears the list of {@link FrameProcessor} that have been registered
* to preview frames.
@ -1488,7 +1504,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Asks the camera to capture an image of the current scene.
* This will trigger {@link CameraListener#onPictureTaken(PictureResult)} if a listener
@ -1504,7 +1519,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.takePicture(stub);
}
/**
* Asks the camera to capture a snapshot of the current preview.
* This eventually triggers {@link CameraListener#onPictureTaken(PictureResult)} if a listener
@ -1520,7 +1534,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.takePictureSnapshot(stub);
}
/**
* Starts recording a video. Video will be written to the given file,
* so callers should ensure they have appropriate permissions to write to the file.
@ -1560,7 +1573,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
});
}
/**
* Starts recording a video. Video will be written to the given file,
* so callers should ensure they have appropriate permissions to write to the file.
@ -1628,10 +1640,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
takeVideoSnapshot(file);
}
// TODO: pauseVideo and resumeVideo? There is mediarecorder.pause(), but API 24...
/**
* Stops capturing video or video snapshots being recorded, if there was any.
* This will fire {@link CameraListener#onVideoTaken(VideoResult)}.
@ -1699,7 +1709,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Returns the size used for pictures taken with {@link #takePicture()},
* or null if it hasn't been computed (for example if the surface is not ready),
@ -1714,7 +1723,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getPictureSize(Reference.OUTPUT);
}
/**
* Returns the size used for videos taken with {@link #takeVideo(File)},
* or null if it hasn't been computed (for example if the surface is not ready),
@ -1729,7 +1737,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getVideoSize(Reference.OUTPUT);
}
// If we end up here, we're in M.
@TargetApi(Build.VERSION_CODES.M)
private void requestPermissions(boolean requestCamera, boolean requestAudio) {
@ -1751,7 +1758,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
@SuppressLint("NewApi")
private void playSound(int soundType) {
if (mPlaySounds) {
@ -1760,7 +1766,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
}
/**
* Controls whether CameraView should play sound effects on certain
* events (picture taken, focus complete). Note that:
@ -1774,7 +1779,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setPlaySounds(playSounds);
}
/**
* Gets the current sound effect behavior.
*
@ -1821,7 +1825,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setVideoCodec(codec);
}
/**
* Gets the current encoder for video recordings.
* @return the current video codec
@ -1831,7 +1834,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getVideoCodec();
}
/**
* Sets the maximum size in bytes for recorded video files.
* Once this size is reached, the recording will automatically stop.
@ -1843,7 +1845,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setVideoMaxSize(videoMaxSizeInBytes);
}
/**
* Returns the maximum size in bytes for recorded video files, or 0
* if no size was set.
@ -1855,7 +1856,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getVideoMaxSize();
}
/**
* Sets the maximum duration in milliseconds for video recordings.
* Once this duration is reached, the recording will automatically stop.
@ -1867,7 +1867,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
mCameraEngine.setVideoMaxDuration(videoMaxDurationMillis);
}
/**
* Returns the maximum duration in milliseconds for video recordings, or 0
* if no limit was set.
@ -1879,7 +1878,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getVideoMaxDuration();
}
/**
* Returns true if the camera is currently recording a video
* @return boolean indicating if the camera is recording a video
@ -1888,7 +1886,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.isTakingVideo();
}
/**
* Returns true if the camera is currently capturing a picture
* @return boolean indicating if the camera is capturing a picture

@ -167,6 +167,8 @@ public abstract class CameraEngine implements
@SuppressWarnings("WeakerAccess") protected float mZoomValue;
@SuppressWarnings("WeakerAccess") protected float mExposureCorrectionValue;
@SuppressWarnings("WeakerAccess") protected boolean mPlaySounds;
@SuppressWarnings("WeakerAccess") protected boolean mPictureMetering;
@SuppressWarnings("WeakerAccess") protected boolean mPictureSnapshotMetering;
// Can be private
@VisibleForTesting Handler mCrashHandler;
@ -1008,6 +1010,22 @@ public abstract class CameraEngine implements
return mAutoFocusResetDelayMillis > 0 && mAutoFocusResetDelayMillis != Long.MAX_VALUE;
}
public final void setPictureMetering(boolean enable) {
mPictureMetering = enable;
}
public final boolean getPictureMetering() {
return mPictureMetering;
}
public final void setPictureSnapshotMetering(boolean enable) {
mPictureSnapshotMetering = enable;
}
public final boolean getPictureSnapshotMetering() {
return mPictureSnapshotMetering;
}
//endregion
//region Abstract setters and APIs

@ -141,6 +141,10 @@
<attr name="cameraUseDeviceOrientation" format="boolean"/>
<attr name="cameraPictureMetering" format="boolean|reference"/>
<attr name="cameraPictureSnapshotMetering" format="boolean|reference"/>
<attr name="cameraExperimental" format="boolean" />
</declare-styleable>

Loading…
Cancel
Save