diff --git a/README.md b/README.md index 68d16d65..56885c2f 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ The promise resolves with an object containing: `path`, `uri`, `name`, `size` (b # Limitations - If you are using `@react-native-camera-roll/camera-roll` **with new architecture enabled this library is not going to work**. If you try to display an image with the `uri` of the library using `` you are going to have the following error: `No suitable image URL loader found for ph://...`. This error come from the ReactNative `ImageLoader`, which is the one we are currently using. Help/PR for solving this are welcome. Until then, we recommend using `react-native-image-picker`. +- Image EXIF orientation are correctly handled on Android only, But not yet on IOS [#402](https://github.com/bamlab/react-native-image-resizer/issues/402). ## 👉 About Bam diff --git a/android/src/main/java/com/reactnativeimageresizer/ImageResizer.java b/android/src/main/java/com/reactnativeimageresizer/ImageResizer.java index 4c176bc7..d1482655 100644 --- a/android/src/main/java/com/reactnativeimageresizer/ImageResizer.java +++ b/android/src/main/java/com/reactnativeimageresizer/ImageResizer.java @@ -189,12 +189,11 @@ private static Bitmap resizeImage(Bitmap image, int newWidth, int newHeight, /** * Rotate the specified bitmap with the given angle, in degrees. */ - public static Bitmap rotateImage(Bitmap source, float angle) + public static Bitmap rotateImage(Bitmap source, Matrix matrix, float angle) { Bitmap retVal; - - Matrix matrix = new Matrix(); matrix.postRotate(angle); + try { retVal = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true); } catch (OutOfMemoryError e) { @@ -316,39 +315,57 @@ public static boolean copyExif(Context context, Uri imageUri, String dstPath){ /** * Get orientation by reading Image metadata */ - public static int getOrientation(Context context, Uri uri) { + public static Matrix getOrientationMatrix(Context context, Uri uri) { try { // ExifInterface(InputStream) only exists since Android N (r24) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { InputStream input = context.getContentResolver().openInputStream(uri); ExifInterface ei = new ExifInterface(input); - return getOrientation(ei); + return getOrientationMatrix(ei); } File file = getFileFromUri(context, uri); if (file.exists()) { ExifInterface ei = new ExifInterface(file.getAbsolutePath()); - return getOrientation(ei); + return getOrientationMatrix(ei); } } catch (Exception ignored) { } - return 0; + return new Matrix(); } /** * Convert metadata to degrees */ - public static int getOrientation(ExifInterface exif) { - int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); + public static Matrix getOrientationMatrix(ExifInterface exif) { + Matrix matrix = new Matrix(); + int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); switch (orientation) { + case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: + matrix.setScale(-1, 1); + break; + case ExifInterface.ORIENTATION_TRANSPOSE: + matrix.setRotate(90); + matrix.postScale(-1, 1); + break; case ExifInterface.ORIENTATION_ROTATE_90: - return 90; + matrix.setRotate(90); + break; + case ExifInterface.ORIENTATION_FLIP_VERTICAL: + matrix.setRotate(180); + matrix.postScale(-1, 1); + break; case ExifInterface.ORIENTATION_ROTATE_180: - return 180; + matrix.setRotate(180); + break; + case ExifInterface.ORIENTATION_TRANSVERSE: + matrix.setRotate(270); + matrix.postScale(-1, 1); + break; case ExifInterface.ORIENTATION_ROTATE_270: - return 270; - default: - return 0; - } + matrix.setRotate(270); + break; + } + return matrix; } /** @@ -549,15 +566,14 @@ public static Bitmap createResizedImage(Context context, Uri imageUri, int newWi // get wrong dimensions if we want the new dimensions to be after rotation. // NOTE: This will "fix" the image using it's exif info if it is rotated as well. Bitmap rotatedImage = sourceImage; - int orientation = getOrientation(context, imageUri); - rotation = orientation + rotation; - rotatedImage = ImageResizer.rotateImage(sourceImage, rotation); + Matrix matrix = getOrientationMatrix(context, imageUri); + rotatedImage = ImageResizer.rotateImage(sourceImage, matrix, rotation); if(rotatedImage == null){ throw new IOException("Unable to rotate image. Most likely due to not enough memory."); } - if (rotatedImage != rotatedImage) { + if (rotatedImage != sourceImage) { sourceImage.recycle(); }