Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<Image />` 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

Expand Down
54 changes: 35 additions & 19 deletions android/src/main/java/com/reactnativeimageresizer/ImageResizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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();
}

Expand Down