diff --git a/MIGRATION.md b/MIGRATION.md index f4db9613..fb301345 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -9,8 +9,10 @@ - capturePicture(): renamed to takePicture(). - captureSnapshot(): renamed to takePictureSnapshot(). - startCapturingVideo(): renamed to takeVideo(). Signature changed from long to int. -- getSnapshotSize(): removed. The size of snapshots (pictures and videos) is equal to - the preview size as returned by getPreviewSize(). +- getPreviewSize(): removed. +- getPictureSize(): the size is now equal to the output picture size (includes rotation). +- getSnapshotSize(): this is the size of pictures taken with takePictureSnapshot() and videos taken + with takeVideoSnapshot(). It includes rotation and cropping. - onVideoTaken(): now passing a VideoResult. Use VideoResult.getFile() to access the video file. - onPictureTaken(): now passing a PictureResult. Use PictureResult.getJpeg() to access the jpeg stream. - CameraUtils.BitmapCallback: has been moved in a separate BitmapCallback class. diff --git a/README.md b/README.md index 4eb700f3..049d6846 100644 --- a/README.md +++ b/README.md @@ -150,8 +150,8 @@ camera.addCameraListener(new CameraListener() { camera.takePicture(); ``` -You can also use `camera.takePictureSnapshot()` to capture a preview frame. This is faster, though will -ensure lower quality output. +You can also use `camera.takePictureSnapshot()` to capture a preview frame. This can be faster, +but the output is lower quality of course. ### Capturing Video @@ -339,7 +339,7 @@ just like `android:scaleType="centerCrop"` on an `ImageView`. ``` This means that part of the preview is hidden, and the image output will contain parts of the scene -that were not visible during the capture. +that were not visible during the capture (unless it is taken as a **snapshot**). ### Picture Size @@ -443,9 +443,6 @@ What to capture - either picture or video. This has a couple of consequences: - Sizing: picture and preview size are chosen among the available picture or video sizes, depending on the flag. The picture size is chosen according to the given [size selector](#picture-size). When `video`, in addition, we try to match the `videoQuality` aspect ratio. -- Picture capturing: due to sizing behavior, capturing pictures in `video` mode might lead to - inconsistent results. In this case it is encouraged to use `takePictureSnapshot` instead, which will - capture preview frames. This is fast and thus works well with slower camera sensors. - Picture capturing: while recording a video, image capturing might work, but it is not guaranteed (it's device dependent) - Permission behavior: when requesting a `video` session, the record audio permission will be requested. @@ -632,9 +629,8 @@ Other APIs not mentioned above are provided, and are well documented and comment |`setLocation(double, double)`|Sets latitude and longitude to be appended to picture/video metadata.| |`getLocation()`|Retrieves location data previously applied with setLocation().| |`startAutoFocus(float, float)`|Starts an autofocus process at the given coordinates, with respect to the view dimensions.| -|`getPreviewSize()`|Returns the size of the preview surface. If CameraView was not constrained in its layout phase (e.g. it was `wrap_content`), this will return the same aspect ratio of CameraView.| -|`getSnapshotSize()`|Returns `getPreviewSize()`, since a snapshot is a preview frame.| -|`getPictureSize()`|Returns the size of the output picture. The aspect ratio is consistent with `getPreviewSize()`.| +|`getSnapshotSize()`|Returns the size of snapshots (pictures or video), including any rotation and cropping.| +|`getPictureSize()`|Returns the size of the output picture, including any rotation.| Take also a look at public methods in `CameraUtils`, `CameraOptions`. diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java index dc292230..6fc2215d 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java @@ -14,8 +14,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.List; - import static org.junit.Assert.*; import static org.mockito.Mockito.*; @@ -76,7 +74,7 @@ public class CameraViewTest extends BaseTest { public void testNullBeforeStart() { assertFalse(cameraView.isStarted()); assertNull(cameraView.getCameraOptions()); - assertNull(cameraView.getPreviewSize()); + assertNull(cameraView.getSnapshotSize()); assertNull(cameraView.getPictureSize()); } diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java index fe8469ab..06ca6864 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java @@ -17,7 +17,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import java.io.File; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -565,7 +564,7 @@ public class IntegrationTest extends BaseTest { @Test public void testCaptureSnapshot_size() throws Exception { waitForOpen(true); - Size size = camera.getPreviewSize(); + Size size = camera.getSnapshotSize(); camera.takePictureSnapshot(); PictureResult result = waitForPicture(true); diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java index f514cd11..6f076bd2 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java @@ -231,7 +231,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera mPictureSize = null; mIsBound = false; mIsCapturingImage = false; - mIsCapturingVideo = false; + mIsTakingVideo = false; LOG.w("onStop:", "Clean up.", "Returning."); // We were saving a reference to the exception here and throwing to the user. @@ -317,7 +317,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera params.setGpsTimestamp(mLocation.getTime()); params.setGpsProcessingMethod(mLocation.getProvider()); - if (mIsCapturingVideo && mMediaRecorder != null) { + if (mIsTakingVideo && mMediaRecorder != null) { mMediaRecorder.setLocation((float) mLocation.getLatitude(), (float) mLocation.getLongitude()); } @@ -405,7 +405,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera @Override void setAudio(Audio audio) { if (mAudio != audio) { - if (mIsCapturingVideo) { + if (mIsTakingVideo) { LOG.w("Audio setting was changed while recording. " + "Changes will take place starting from next video"); } @@ -471,7 +471,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera schedule(mVideoQualityTask, true, new Runnable() { @Override public void run() { - if (mIsCapturingVideo) { + if (mIsTakingVideo) { // TODO: actually any call to getParameters() could fail while recording a video. // See. https://stackoverflow.com/questions/14941625/ mVideoQuality = old; @@ -505,7 +505,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera public void run() { LOG.v("takePicture: performing.", mIsCapturingImage); if (mIsCapturingImage) return; - if (mIsCapturingVideo && !mCameraOptions.isVideoSnapshotSupported()) return; + if (mIsTakingVideo && !mCameraOptions.isVideoSnapshotSupported()) return; mIsCapturingImage = true; final int sensorToOutput = offset(REF_SENSOR, REF_OUTPUT); @@ -561,7 +561,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera // This won't work while capturing a video. // Switch to takePicture. // TODO v2: what to do here? - if (mIsCapturingVideo) { + if (mIsTakingVideo) { takePicture(); return; } @@ -654,9 +654,9 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera schedule(mStartVideoTask, true, new Runnable() { @Override public void run() { - if (mIsCapturingVideo) return; + if (mIsTakingVideo) return; if (mSessionType == SessionType.VIDEO) { - mIsCapturingVideo = true; + mIsTakingVideo = true; // Create the video result CamcorderProfile profile = getCamcorderProfile(); @@ -739,8 +739,8 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera @WorkerThread private void stopVideoImmediately() { - LOG.i("stopVideoImmediately:", "is capturing:", mIsCapturingVideo); - mIsCapturingVideo = false; + LOG.i("stopVideoImmediately:", "is capturing:", mIsTakingVideo); + mIsTakingVideo = false; if (mMediaRecorder != null) { try { mMediaRecorder.stop(); diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java index ad49472c..5b6e01ed 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java @@ -70,7 +70,7 @@ abstract class CameraController implements private int mDeviceOrientation; protected boolean mIsCapturingImage = false; - protected boolean mIsCapturingVideo = false; + protected boolean mIsTakingVideo = false; protected int mState = STATE_STOPPED; @@ -406,7 +406,7 @@ abstract class CameraController implements } final boolean isTakingVideo() { - return mIsCapturingVideo; + return mIsTakingVideo; } //endregion diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 2b3fe077..7f5d2bbd 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -1213,14 +1213,14 @@ public class CameraView extends FrameLayout implements LifecycleObserver { /** - * Returns the size used for the preview, - * or null if it hasn't been computed (for example if the surface is not ready). - * This is the size of snapshots. + * Returns the size used for snapshots, or null if it hasn't been computed + * (for example if the surface is not ready). This is the preview size, rotated to match + * the output orientation, and cropped to the visible part. * - * @return a Size + * @return the size of snapshots */ @Nullable - public Size getPreviewSize() { + public Size getSnapshotSize() { if (getWidth() == 0 || getHeight() == 0) return null; // Get the preview size and crop according to the current view size. @@ -1238,10 +1238,10 @@ public class CameraView extends FrameLayout implements LifecycleObserver { /** - * Returns the size used for the capture, - * or null if it hasn't been computed yet (for example if the surface is not ready). + * Returns the size used for the capture, or null if it hasn't been computed + * (for example if the surface is not ready). The size is rotated to match the output orientation. * - * @return a Size + * @return the size of pictures */ @Nullable public Size getPictureSize() { @@ -1439,7 +1439,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver { @Override public void onCameraPreviewSizeChanged() { mLogger.i("onCameraPreviewSizeChanged"); - // Camera preview size, as returned by getPreviewSize(), has changed. + // Camera preview size has changed. // Request a layout pass for onMeasure() to do its stuff. // Potentially this will change CameraView size, which changes Surface size, // which triggers a new Preview size. But hopefully it will converge.