From cebc0601d15925b31cb8550d8e1643f55f7b2b65 Mon Sep 17 00:00:00 2001 From: Nicolas Morin Date: Wed, 24 Jan 2018 09:29:09 +0100 Subject: [PATCH] Fix cropToPreview on Android --- .../lwansbrough/RCTCamera/MutableImage.java | 29 +++++++++---------- .../com/lwansbrough/RCTCamera/RCTCamera.java | 18 ++++++------ .../RCTCamera/RCTCameraModule.java | 22 ++++++++------ .../lwansbrough/RCTCamera/RCTCameraView.java | 5 +--- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java b/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java index d7a3987..a2f3a5a 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java @@ -85,24 +85,23 @@ public class MutableImage { } } - public void cropToPreview(int orientation, float xPercentage, float yPercentage) throws IllegalArgumentException { - int width = getWidth(); - int height = getHeight(); + public void cropToPreview(double previewRatio) throws IllegalArgumentException { + int pictureWidth = getWidth(), pictureHeight = getHeight(); + int targetPictureWidth, targetPictureHeight; - int x = (int) Math.round(height * xPercentage); - int y = (int) Math.round(width * yPercentage); - - if (orientation == Configuration.ORIENTATION_PORTRAIT) { - int cropWidth = width - (y*2); - int cropHeight = height - (x*2); - - this.currentRepresentation = Bitmap.createBitmap(this.currentRepresentation, y, x, cropWidth, cropHeight); + if (previewRatio * pictureHeight > pictureWidth) { + targetPictureWidth = pictureWidth; + targetPictureHeight = (int) (pictureWidth / previewRatio); } else { - int cropWidth = width - (x*2); - int cropHeight = height - (y*2); - - this.currentRepresentation = Bitmap.createBitmap(this.currentRepresentation, x, y, cropWidth, cropHeight); + targetPictureHeight = pictureHeight; + targetPictureWidth = (int) (pictureHeight * previewRatio); } + this.currentRepresentation = Bitmap.createBitmap( + this.currentRepresentation, + (pictureWidth - targetPictureWidth) / 2, + (pictureHeight - targetPictureHeight) / 2, + targetPictureWidth, + targetPictureHeight); } //see http://www.impulseadventure.com/photo/exif-orientation.html diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java index 2bcf3a1..9d09e2b 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java @@ -74,20 +74,20 @@ public class RCTCamera { return cameraInfo.previewHeight; } - public float getPreviewPaddingHeight(int type) { + public int getPreviewVisibleHeight(int type) { CameraInfoWrapper cameraInfo = _cameraInfos.get(type); if (null == cameraInfo) { return 0; } - return cameraInfo.previewPaddingHeight; + return cameraInfo.previewVisibleHeight; } - public float getPreviewPaddingWidth(int type) { + public int getPreviewVisibleWidth(int type) { CameraInfoWrapper cameraInfo = _cameraInfos.get(type); if (null == cameraInfo) { return 0; } - return cameraInfo.previewPaddingWidth; + return cameraInfo.previewVisibleWidth; } public Camera.Size getBestSize(List supportedSizes, int maxWidth, int maxHeight) { @@ -451,14 +451,14 @@ public class RCTCamera { } } - public void setPreviewPadding(int type, float width, float height) { + public void setPreviewVisibleSize(int type, int width, int height) { CameraInfoWrapper cameraInfo = _cameraInfos.get(type); if (cameraInfo == null) { return; } - cameraInfo.previewPaddingWidth = Math.abs(width); - cameraInfo.previewPaddingHeight = Math.abs(height); + cameraInfo.previewVisibleWidth = width; + cameraInfo.previewVisibleHeight = height; } private RCTCamera(int deviceOrientation) { @@ -491,8 +491,8 @@ public class RCTCamera { public int rotation = 0; public int previewWidth = -1; public int previewHeight = -1; - public float previewPaddingHeight = -1; - public float previewPaddingWidth = -1; + public int previewVisibleWidth = -1; + public int previewVisibleHeight = -1; public CameraInfoWrapper(Camera.CameraInfo info) { this.info = info; diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java index a6017e7..3392912 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java @@ -577,8 +577,6 @@ public class RCTCameraModule extends ReactContextBaseJavaModule * concurrently which would blow the memory (esp on smaller devices), and slow things down. */ private synchronized void processImage(MutableImage mutableImage, ReadableMap options, Promise promise) { - int orientation = _reactContext.getResources().getConfiguration().orientation; - boolean shouldFixOrientation = options.hasKey("fixOrientation") && options.getBoolean("fixOrientation"); if(shouldFixOrientation) { try { @@ -588,14 +586,20 @@ public class RCTCameraModule extends ReactContextBaseJavaModule } } + boolean needsReorient = false; + double previewRatio, pictureRatio = (double) mutableImage.getWidth() / (double) mutableImage.getHeight(); + try { + int type = options.getInt("type"); + previewRatio = (double) RCTCamera.getInstance().getPreviewVisibleWidth(type) / (double) RCTCamera.getInstance().getPreviewVisibleHeight(type); + needsReorient = (previewRatio > 1) != (pictureRatio > 1); + } catch (IllegalArgumentException e) { + previewRatio = pictureRatio; + } + boolean shouldCropToPreview = options.hasKey("cropToPreview") && options.getBoolean("cropToPreview"); if (shouldCropToPreview) { try { - int type = options.getInt("type"); - float paddingWidth = RCTCamera.getInstance().getPreviewPaddingWidth(type); - float paddingHeight = RCTCamera.getInstance().getPreviewPaddingHeight(type); - - mutableImage.cropToPreview(orientation, paddingWidth, paddingHeight); + mutableImage.cropToPreview(needsReorient ? 1.0 / previewRatio : previewRatio); } catch (IllegalArgumentException e) { promise.reject("Error cropping image to preview", e); } @@ -615,8 +619,8 @@ public class RCTCameraModule extends ReactContextBaseJavaModule jpegQualityPercent = options.getInt("jpegQuality"); } - int imgWidth = (orientation == Configuration.ORIENTATION_PORTRAIT) ? mutableImage.getHeight() : mutableImage.getWidth(); - int imgHeight = (orientation == Configuration.ORIENTATION_PORTRAIT) ? mutableImage.getWidth() : mutableImage.getHeight(); + int imgWidth = (needsReorient) ? mutableImage.getHeight() : mutableImage.getWidth(); + int imgHeight = (needsReorient) ? mutableImage.getWidth() : mutableImage.getHeight(); switch (options.getInt("target")) { case RCT_CAMERA_CAPTURE_TARGET_MEMORY: diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java index a5405cc..587d5b4 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java @@ -210,10 +210,7 @@ public class RCTCameraView extends ViewGroup { int viewFinderPaddingX = (int) ((width - viewfinderWidth) / 2); int viewFinderPaddingY = (int) ((height - viewfinderHeight) / 2); - float paddingXPercentage = (float)viewFinderPaddingX / (float)viewfinderWidth; - float paddingYPercentage = (float)viewFinderPaddingY / (float)viewfinderHeight; - - RCTCamera.getInstance().setPreviewPadding(_viewFinder.getCameraType(), paddingXPercentage, paddingYPercentage); + RCTCamera.getInstance().setPreviewVisibleSize(_viewFinder.getCameraType(), (int) width, (int) height); this._viewFinder.layout(viewFinderPaddingX, viewFinderPaddingY, viewFinderPaddingX + viewfinderWidth, viewFinderPaddingY + viewfinderHeight); this.postInvalidate(this.getLeft(), this.getTop(), this.getRight(), this.getBottom());