Output path fix + orientation fix (#20)

* rotateImage function rewrite

* fix recycle

* output path fix

* only pass bitmap to functions

* Orientation fix
This commit is contained in:
Kristoffer K 2016-07-17 21:43:11 +02:00 committed by Florian Rival
parent 50ea225665
commit 3b8d1c1940
1 changed files with 130 additions and 50 deletions

View File

@ -2,14 +2,21 @@ package fr.bamlab.rnimageresizer;
import android.content.Context; import android.content.Context;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri; import android.net.Uri;
import android.provider.MediaStore;
import android.util.Pair;
import java.io.Closeable;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
@ -19,60 +26,39 @@ import java.util.Date;
*/ */
class ImageResizer { class ImageResizer {
private static Bitmap resizeImage(String imagePath, int maxWidth, int maxHeight, Context context) { private static Bitmap resizeImage(Bitmap image, int maxWidth, int maxHeight, Context context) {
try {
Bitmap image;
if (!imagePath.startsWith("content://") && !imagePath.startsWith("file://")) {
image = BitmapFactory.decodeFile(imagePath);
} else {
ContentResolver cr = context.getContentResolver();
Uri url = Uri.parse(imagePath);
InputStream input = cr.openInputStream(url);
image = BitmapFactory.decodeStream(input);
input.close();
}
if (image == null) { if (image == null) {
return null; // Can't load the image from the given path. return null; // Can't load the image from the given path.
}
if (maxHeight > 0 && maxWidth > 0) {
float width = image.getWidth();
float height = image.getHeight();
float ratio = Math.min((float)maxWidth / width, (float)maxHeight / height);
int finalWidth = (int) (width * ratio);
int finalHeight = (int) (height * ratio);
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
}
return image;
}catch (IOException ex) {
// No memory available for resizing.
} }
return null; if (maxHeight > 0 && maxWidth > 0) {
float width = image.getWidth();
float height = image.getHeight();
float ratio = Math.min((float)maxWidth / width, (float)maxHeight / height);
int finalWidth = (int) (width * ratio);
int finalHeight = (int) (height * ratio);
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
}
return image;
} }
public static Bitmap rotateImage(Bitmap b, float degrees) public static Bitmap rotateImage(Bitmap source, float angle)
{ {
if (degrees != 0 && b != null) { Bitmap retVal;
Matrix m = new Matrix();
m.setRotate(degrees, Matrix matrix = new Matrix();
(float) b.getWidth() / 2, (float) b.getHeight() / 2); matrix.postRotate(angle);
try { retVal = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
Bitmap b2 = Bitmap.createBitmap( //for memory purposes
b, 0, 0, b.getWidth(), b.getHeight(), m, true); if (retVal != source){
if (b != b2) { source.recycle();
b.recycle();
b = b2;
}
} catch (OutOfMemoryError ex) {
// No memory available for rotating. Return the original bitmap.
}
} }
return b;
return retVal;
} }
private static String saveImage(Bitmap bitmap, File saveDirectory, String fileName, private static String saveImage(Bitmap bitmap, File saveDirectory, String fileName,
@ -102,18 +88,112 @@ class ImageResizer {
return newFile.getAbsolutePath(); return newFile.getAbsolutePath();
} }
/**
* Get {@link File} object for the given Android URI.<br>
* Use content resolver to get real path if direct path doesn't return valid file.
*/
private static File getFileFromUri(Context context, Uri uri) {
// first try by direct path
File file = new File(uri.getPath());
if (file.exists()) {
return file;
}
// try reading real path from content resolver (gallery images)
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = context.getContentResolver().query(uri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String realPath = cursor.getString(column_index);
file = new File(realPath);
} catch (Exception ignored) {
} finally {
if (cursor != null) {
cursor.close();
}
}
return file;
}
/**
* Rotate the given image by reading the Exif value of the image (uri).<br>
* If no rotation is required the image will not be rotated.<br>
* New bitmap is created and the old one is recycled.
*/
public static int getOrientation(Bitmap bitmap, Context context, Uri uri) {
try {
File file = getFileFromUri(context, uri);
if (file.exists()) {
ExifInterface ei = new ExifInterface(file.getAbsolutePath());
return getOrientation(bitmap, ei);
}
} catch (Exception ignored) {
}
return 0;
}
/**
* Rotate the given image by given Exif value.<br>
* If no rotation is required the image will not be rotated.<br>
* New bitmap is created and the old one is recycled.
*/
public static int getOrientation(Bitmap bitmap, ExifInterface exif) {
int degrees;
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degrees = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degrees = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degrees = 270;
break;
default:
degrees = 0;
break;
}
return degrees;
}
public static String createResizedImage(Context context, String imagePath, int newWidth, public static String createResizedImage(Context context, String imagePath, int newWidth,
int newHeight, Bitmap.CompressFormat compressFormat, int newHeight, Bitmap.CompressFormat compressFormat,
int quality, int rotation, String outputPath) throws IOException { int quality, int rotation, String outputPath) throws IOException {
Bitmap resizedImage = ImageResizer.rotateImage(ImageResizer.resizeImage(imagePath, newWidth, newHeight, context), rotation);
Bitmap image;
if (!imagePath.startsWith("content://") && !imagePath.startsWith("file://")) {
image = BitmapFactory.decodeFile(imagePath);
} else {
ContentResolver cr = context.getContentResolver();
Uri url = Uri.parse(imagePath);
InputStream input = cr.openInputStream(url);
image = BitmapFactory.decodeStream(input);
input.close();
}
int orientation = getOrientation(image, context, Uri.parse(imagePath));
rotation = orientation+rotation;
//rotate & resize
Bitmap newImage = ImageResizer.resizeImage(ImageResizer.rotateImage(image, rotation), newWidth, newHeight, context);
//recycle old image
image.recycle();
File path = context.getCacheDir(); File path = context.getCacheDir();
if (outputPath != null || !outputPath.isEmpty()) { if (outputPath != null ) {
path = new File(outputPath); path = new File(outputPath);
} }
return ImageResizer.saveImage(resizedImage, path, return ImageResizer.saveImage(newImage, path,
Long.toString(new Date().getTime()), compressFormat, quality); Long.toString(new Date().getTime()), compressFormat, quality);
} }
} }