From c119069e4a235232a10b3f0cbb02cf4c1c637f07 Mon Sep 17 00:00:00 2001 From: Levente Lorincz Date: Tue, 27 Aug 2024 10:22:44 +0300 Subject: [PATCH] fix(bank-sdk): Added forced autofocus before image capture PM-100 --- .../camera/api/OldCameraController.java | 39 +++------- .../camera/api/camerax/CameraXController.kt | 75 ++++++++++--------- 2 files changed, 51 insertions(+), 63 deletions(-) diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/OldCameraController.java b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/OldCameraController.java index 231e368d04..633347a9db 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/OldCameraController.java +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/OldCameraController.java @@ -444,33 +444,18 @@ public CompletableFuture takePicture() { // as being stopped before it is really stopped mPreviewRunning = false; - CompletableFuture focusFuture = new CompletableFuture<>(); - if (isUsingFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE, mCamera)) { - // When continuous focus mode is used no auto-focus run is needed - focusFuture.complete(true); - } else { - // Continuous focus mode is not used and we need to do an auto-focus run - focusFuture = focus(); - } - - focusFuture.handle(new CompletableFuture.BiFun() { - @Override - public Void apply(final Boolean aBoolean, final Throwable throwable) { - takePicture(new Camera.PictureCallback() { - @Override - public void onPictureTaken(final byte[] bytes, final Camera camera) { - mTakingPictureFuture.set(null); - final Photo photo = PhotoFactory.newPhotoFromJpeg(bytes, - getDisplayOrientationForCamera(mActivity), - getDeviceOrientation(mActivity), - getDeviceType(mActivity), - Document.Source.newCameraSource()); - LOG.info("Picture taken"); - pictureTaken.complete(photo); - } - }); - return null; - } + focus().handle((CompletableFuture.BiFun) (aBoolean, throwable) -> { + takePicture((bytes, camera) -> { + mTakingPictureFuture.set(null); + final Photo photo = PhotoFactory.newPhotoFromJpeg(bytes, + getDisplayOrientationForCamera(mActivity), + getDeviceOrientation(mActivity), + getDeviceType(mActivity), + Document.Source.newCameraSource()); + LOG.info("Picture taken"); + pictureTaken.complete(photo); + }); + return null; }); return pictureTaken; diff --git a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/camerax/CameraXController.kt b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/camerax/CameraXController.kt index 7ba42658d4..6b65b056a3 100644 --- a/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/camerax/CameraXController.kt +++ b/capture-sdk/sdk/src/main/java/net/gini/android/capture/internal/camera/api/camerax/CameraXController.kt @@ -307,49 +307,52 @@ internal class CameraXController(val activity: Activity) : CameraInterface { return pictureFuture } - imageCaptureUseCase?.takePicture(ContextCompat.getMainExecutor(activity), - object : ImageCapture.OnImageCapturedCallback() { - override fun onCaptureSuccess(image: ImageProxy) { - // Not playing shutter sound because on some devices (for eg. Samsung Galaxy S9) it - // always plays at 100% volume - // mediaActionSound?.play(MediaActionSound.SHUTTER_CLICK) + focus().thenApply { + imageCaptureUseCase?.takePicture(ContextCompat.getMainExecutor(activity), + object : ImageCapture.OnImageCapturedCallback() { + override fun onCaptureSuccess(image: ImageProxy) { + // Not playing shutter sound because on some devices (for eg. Samsung Galaxy S9) it + // always plays at 100% volume + // mediaActionSound?.play(MediaActionSound.SHUTTER_CLICK) + + vibrate(SHUTTER_VIBRATION_DURATION_MS) + + val byteArray = try { + image.toCroppedByteArray() + } catch (e: CameraException) { + LOG.error("Failed to take picture", e) + pictureFuture.completeExceptionally(e) + image.close() + return + } + + val photo = PhotoFactory.newPhotoFromJpeg( + byteArray, + image.imageInfo.rotationDegrees, + DeviceHelper.getDeviceOrientation(activity), + DeviceHelper.getDeviceType(activity), + Document.Source.newCameraSource() + ) - vibrate(SHUTTER_VIBRATION_DURATION_MS) + LOG.info("Picture taken with resolution {}x{}", image.cropRect.width(), + image.cropRect.height()) - val byteArray = try { - image.toCroppedByteArray() - } catch (e: CameraException) { - LOG.error("Failed to take picture", e) - pictureFuture.completeExceptionally(e) + pictureFuture.complete(photo) image.close() return } - val photo = PhotoFactory.newPhotoFromJpeg( - byteArray, - image.imageInfo.rotationDegrees, - DeviceHelper.getDeviceOrientation(activity), - DeviceHelper.getDeviceType(activity), - Document.Source.newCameraSource() - ) - - LOG.info("Picture taken with resolution {}x{}", image.cropRect.width(), - image.cropRect.height()) - - pictureFuture.complete(photo) - image.close() - } - - override fun onError(exception: ImageCaptureException) { - LOG.error("Failed to take picture", exception) - pictureFuture.completeExceptionally( - CameraException( - exception, - CameraException.Type.SHOT_FAILED + override fun onError(exception: ImageCaptureException) { + LOG.error("Failed to take picture", exception) + pictureFuture.completeExceptionally( + CameraException( + exception, + CameraException.Type.SHOT_FAILED + ) ) - ) - } - }) + } + }) + } return pictureFuture }