How can I avoid the OutOfMemoryError when I am rotating images in most simplest form. I am very new to Android Studio and Java. This is the static method of rotation of images
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation, Context context) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth()/2, bitmap.getHeight()/2, matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e) {
e.printStackTrace();
Toast.makeText(context, "Error:" + e, Toast.LENGTH_SHORT).show();
return null;
}
}
I don't know what your use-case is but you can get simple rotation without resorting to a matrix. It is fairly easy to run out of memory with large bitmaps.
This on the other hand, will rotate any given imageview by some random amount from 0 to 360 degrees, with fairly low overhead:
display = (ImageView) findViewById(R.id.someview);
int randomRot;
Random rand = new Random();
randomRot=rand.nextInt(360);
display.setRotation((float) randomRot);
yourImageView.setRotation(angle) with API>=11
Related
In my app the user gets an image from the camera or gallery, these images are then converted to a PDF Now my Problem is on some devices the image captured by the Camera is rotated 90 degrees, the devices are some samsung devices specifically an S7,
I know I need to edit the EXIF data of the image but I am new to android, and the entire EXIF data thing goes over my head completely any help would be aprecieated
This is where I call the selected image and convert it to a PDF
PdfDocument document=new PdfDocument();
// crate a page description
PdfDocument.PageInfo pageInfo;
PdfDocument.Page page;
Canvas canvas;
int i;
Bitmap image;
for (i=0; i < list.size(); i++) {
pageInfo=new PdfDocument.PageInfo.Builder(992, 1432, 1).create();
page=document.startPage(pageInfo);
canvas=page.getCanvas();
image=BitmapFactory.decodeFile(list.get(i));
image = Bitmap.createScaledBitmap(image, 980, 1420, true);
image.setDensity(DisplayMetrics.DENSITY_300);
canvas.setDensity(DisplayMetrics.DENSITY_300);
canvas.drawBitmap(image, 0, 0, null);
document.finishPage(page);
}
#SuppressWarnings("deprecation") String directory_path=Environment.getExternalStorageDirectory().getPath() + "/mypdf/";
File file=new File(directory_path);
if (!file.exists()) {
//noinspection ResultOfMethodCallIgnored
file.mkdirs();
}
#SuppressLint("SimpleDateFormat") String timeStamp=(new SimpleDateFormat("yyyyMMdd_HHmmss")).format(new Date());
String targetPdf=directory_path + timeStamp + ".pdf";
File filePath=new File(targetPdf);
try {
document.writeTo(new FileOutputStream(filePath));
} catch (IOException e) {
Log.e("main", "error " + e.toString());
Toasty.error(this, "Error making PDF" + e.toString(), Toast.LENGTH_LONG).show();
}
// close the document
document.close();
Add this to your build gradle:
implementation 'androidx.exifinterface:exifinterface:1.0.0'
get rotation data:
Bitmap bitmap = BitmapFactory.decodeFile(path);
ExifInterface exif;
try {
exif = new ExifInterface(path);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Bitmap bmRotated = MyUtility.rotateBitmap(bitmap, orientation);
}
} catch (IOException e) {
e.printStackTrace();
}
rotateBitmap() method:
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
mLog.i(TAG,"normal");
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
mLog.i(TAG,"ORIENTATION_FLIP_HORIZONTAL");
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
mLog.i(TAG,"ORIENTATION_ROTATE_180");
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
mLog.i(TAG,"ORIENTATION_FLIP_VERTICAL");
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
mLog.i(TAG,"ORIENTATION_TRANSPOSE");
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
mLog.i(TAG,"ORIENTATION_ROTATE_90");
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
mLog.i(TAG,"ORIENTATION_TRANSVERSE");
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
mLog.i(TAG,"ORIENTATION_ROTATE_270");
break;
default:
mLog.i(TAG,"UNKNOWN");
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}
Although I have had problems on a few samsung devices this works well. Give it a try.
I'm using Exif interface to get the desired orientation of the image but the bitmap I get is just a part of the original picture zoomed out to fit the imageView.How do I get the whole picture(Image Resolution - 2048 x 1152)?
bitmap1 = BitmapFactory.decodeFile(selectedImagePath);
int rotate = 0;
try {
ExifInterface exif = new ExifInterface(selectedImagePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
bitmap1 = Bitmap.createBitmap(bitmap1, 0, 0, bitmap1.getWidth(),bitmap1.getHeight(), matrix, true);
I captured image from camera and display image into imageview. It will display perfect but the captured image rotated 90 degrees automatically in some devices. I searched a lot about it but could not get proper solution. Please tell me the solution for it. Thanks in advance.
try this code
public Bitmap adjustImageOrientation(Bitmap image, File f) {
int rotate = 0;
try {
ExifInterface exif = new ExifInterface(f.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_NORMAL:
rotate = 0;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
if (rotate != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
image = Bitmap.createBitmap(image, 0, 0, image.getWidth(),
image.getHeight(), matrix, true);
}
return image;
}
Use this method to determine image rotation.
public int getCameraPhotoOrientation(Uri imageUri, String imagePath) {
int rotate = 0;
try {
_context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(
imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
}
return rotate;
}
And if the method wouldn't return Zero rotated the image.
int degree=getCameraPhotoOrientation(Uri.fromFile(tempFile), fPath);
if (degree!= 0) {
bitmap = tools.rotateOrientationCall(bitmap, degree);
}
Rotate your bitmap.
public Bitmap rotateOrientationCall(Bitmap src, float degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
}
I need rotate pictures to portrait. I made this method using exif:
private static Bitmap rotateBitmap(Bitmap sourceBitmap) throws java.io.IOException{
int width = sourceBitmap.getWidth();
int height = sourceBitmap.getHeight();
Matrix matrix = new Matrix();
ExifInterface ei = new ExifInterface(photoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch(orientation) {
case ExifInterface.ORIENTATION_NORMAL:
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
break;
}
if (orientation == ExifInterface.ORIENTATION_ROTATE_90 || orientation == ExifInterface.ORIENTATION_ROTATE_270) {
return Bitmap.createBitmap(sourceBitmap, 0, 0, width, height, matrix, true);
}
else {
return Bitmap.createBitmap(sourceBitmap, 0, 0, width, height, matrix, true);
}
}
In case of ORIENTATION_ROTATE_180 or ORIENTATION_NORMAL this method works fine.
In case of ORIENTATION_ROTATE_270 or ORIENTATION_ROTATE_90 this method stretches the picture in the width dimension. I tried to switch the width with the height and the application has crashed.
I need this method to rotate the bitmap and don't loss quality or scale it had before.
How can i do that?
I have this code in my Android app but in some devices such as LG F60 some photos made in application like Retrica are not shown in right rotaion.
exif = new ExifInterface(filePath);
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Matrix matrix = new Matrix ();
boolean flip = false;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
flip=true;
case ExifInterface.ORIENTATION_NORMAL:
matrix.postRotate(0);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
flip=true;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
flip=true;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
flip=true;;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
break;
}
if (flip){
matrix.postScale(-1.0f, 1.0f);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
Does anyone has idea what is the problem?