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:
parent
50ea225665
commit
3b8d1c1940
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue