diff --git a/MIGRATION.md b/MIGRATION.md index 125bb10b..f4db9613 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -12,5 +12,6 @@ - getSnapshotSize(): removed. The size of snapshots (pictures and videos) is equal to the preview size as returned by getPreviewSize(). - 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. - isCapturingVideo(): renamed to isTakingVideo(). diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewCallbacksTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewCallbacksTest.java index 4e3b57a6..80a47c04 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewCallbacksTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewCallbacksTest.java @@ -141,6 +141,14 @@ public class CameraViewCallbacksTest extends BaseTest { verify(listener, times(1)).onVideoTaken(null); } + @Test + public void testDispatchOnPictureTaken() { + completeTask().when(listener).onPictureTaken(null); + camera.mCameraCallbacks.dispatchOnPictureTaken(null); + assertNotNull(task.await(200)); + verify(listener, times(1)).onPictureTaken(null); + } + @Test public void testDispatchOnZoomChanged() { completeTask().when(listener).onZoomChanged(anyFloat(), any(float[].class), any(PointF[].class)); @@ -210,76 +218,6 @@ public class CameraViewCallbacksTest extends BaseTest { verify(listener, times(1)).onCameraError(error); } - @Test - public void testProcessJpeg() { - int[] viewDim = new int[]{ 200, 200 }; - int[] imageDim = new int[]{ 1000, 1600 }; - - // With crop flag: expect a 1:1 ratio. - int[] output = testProcessImage(true, true, viewDim, imageDim); - LOG.i("testProcessJpeg", output); - assertEquals(output[0], 1000); - assertEquals(output[1], 1000); - - // Without crop flag: expect original ratio. - output = testProcessImage(true, false, viewDim, imageDim); - LOG.i("testProcessJpeg", output); - assertEquals(output[0], imageDim[0]); - assertEquals(output[1], imageDim[1]); - } - - @Test - public void testProcessYuv() { - int[] viewDim = new int[]{ 200, 200 }; - int[] imageDim = new int[]{ 1000, 1600 }; - - // With crop flag: expect a 1:1 ratio. - int[] output = testProcessImage(false, true, viewDim, imageDim); - LOG.i("testProcessYuv", output); - assertEquals(output[0], 1000); - assertEquals(output[1], 1000); - - // Without crop flag: expect original ratio. - output = testProcessImage(false, false, viewDim, imageDim); - LOG.i("testProcessYuv", output); - assertEquals(output[0], imageDim[0]); - assertEquals(output[1], imageDim[1]); - } - - private int[] testProcessImage(boolean jpeg, boolean crop, int[] viewDim, int[] imageDim) { - // End our task when onPictureTaken is called. Take note of the result. - final Task jpegTask = new Task<>(true); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - jpegTask.end((byte[]) invocation.getArguments()[0]); - return null; - } - }).when(listener).onPictureTaken(any(PictureResult.class)); - - // Fake our own dimensions. - camera.setTop(0); - camera.setBottom(viewDim[1]); - camera.setLeft(0); - camera.setRight(viewDim[0]); - - // Ensure the image will (not) be cropped. - mockPreview.setIsCropping(crop); - - // Create fake JPEG array and trigger the process. - if (jpeg) { - camera.mCameraCallbacks.processPicture(mockJpeg(imageDim[0], imageDim[1]), true, false); - } else { - camera.mCameraCallbacks.processSnapshot(mockYuv(imageDim[0], imageDim[1]), true, false); - } - - // Wait for result and get out dimensions. - byte[] result = jpegTask.await(3000); - assertNotNull("Image was processed", result); - Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length); - return new int[]{ bitmap.getWidth(), bitmap.getHeight() }; - } - @Test public void testProcessFrame() { Frame mock = mock(Frame.class); diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java index 08810b89..5a5d0850 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java @@ -38,7 +38,7 @@ import static org.mockito.Mockito.mock; */ @RunWith(AndroidJUnit4.class) @MediumTest -@Ignore +// @Ignore public class IntegrationTest extends BaseTest { @Rule @@ -135,10 +135,10 @@ public class IntegrationTest extends BaseTest { } } - private byte[] waitForPicture(boolean expectSuccess) { - final Task pic = new Task<>(true); + private PictureResult waitForPicture(boolean expectSuccess) { + final Task pic = new Task<>(true); doEndTask(pic, 0).when(listener).onPictureTaken(any(PictureResult.class)); - byte[] result = pic.await(5000); + PictureResult result = pic.await(5000); if (expectSuccess) { assertNotNull("Can take picture", result); } else { @@ -528,17 +528,17 @@ public class IntegrationTest extends BaseTest { @Test public void testCapturePicture_size() throws Exception { - // TODO v2: might have to change this waitForOpen(true); - Size size = camera.getPictureSize(); camera.takePicture(); - byte[] jpeg = waitForPicture(true); - Bitmap b = CameraUtils.decodeBitmap(jpeg, Integer.MAX_VALUE, Integer.MAX_VALUE); - // Result can actually have swapped dimensions - // Which one, depends on factors including device physical orientation - assertTrue(b.getWidth() == size.getHeight() || b.getWidth() == size.getWidth()); - assertTrue(b.getHeight() == size.getHeight() || b.getHeight() == size.getWidth()); + PictureResult result = waitForPicture(true); + Bitmap bitmap = CameraUtils.decodeBitmap(result.getJpeg(), Integer.MAX_VALUE, Integer.MAX_VALUE); + assertEquals(result.getSize(), size); + assertEquals(bitmap.getWidth(), size.getWidth()); + assertEquals(bitmap.getHeight(), size.getHeight()); + assertNotNull(result.getJpeg()); + assertNull(result.getLocation()); + assertFalse(result.isSnapshot()); } @Test @@ -564,17 +564,18 @@ public class IntegrationTest extends BaseTest { @Test public void testCaptureSnapshot_size() throws Exception { - // TODO v2: might have to change this waitForOpen(true); - Size size = camera.getPreviewSize(); camera.takePictureSnapshot(); - byte[] jpeg = waitForPicture(true); - Bitmap b = CameraUtils.decodeBitmap(jpeg, Integer.MAX_VALUE, Integer.MAX_VALUE); - // Result can actually have swapped dimensions - // Which one, depends on factors including device physical orientation - assertTrue(b.getWidth() == size.getHeight() || b.getWidth() == size.getWidth()); - assertTrue(b.getHeight() == size.getHeight() || b.getHeight() == size.getWidth()); + + PictureResult result = waitForPicture(true); + Bitmap bitmap = CameraUtils.decodeBitmap(result.getJpeg(), Integer.MAX_VALUE, Integer.MAX_VALUE); + assertEquals(result.getSize(), size); + assertEquals(bitmap.getWidth(), size.getWidth()); + assertEquals(bitmap.getHeight(), size.getHeight()); + assertNotNull(result.getJpeg()); + assertNull(result.getLocation()); + assertTrue(result.isSnapshot()); } //endregion diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 587e0688..5220b9f3 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -47,7 +47,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver { public final static int PERMISSION_REQUEST_CODE = 16; - final static boolean DEFAULT_CROP_OUTPUT = false; final static boolean DEFAULT_PLAY_SOUNDS = true; // Self managed parameters @@ -73,7 +72,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver { // Threading private Handler mUiHandler; - private WorkerHandler mWorkerHandler; private WorkerHandler mFrameProcessorsHandler; public CameraView(@NonNull Context context) { @@ -152,7 +150,6 @@ public class CameraView extends FrameLayout implements LifecycleObserver { mCameraCallbacks = new Callbacks(); mCameraController = instantiateCameraController(mCameraCallbacks); mUiHandler = new Handler(Looper.getMainLooper()); - mWorkerHandler = WorkerHandler.get("CameraViewWorker"); mFrameProcessorsHandler = WorkerHandler.get("FrameProcessorsWorker"); // Views