How can I edit My image EXIF data for image rotation - android

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.

Related

Image still rotated after Editing Exif Data

In My app the User captures an image from the gallery or camera it is then converted to PDF, Now my problem is that images captured from the samsung devices are rotated,
I am trying to edit the exif data but it does not work,
there is no errors the image just stays rotated
I am new to android and the entire EXIF data thing goes over my head, some advice would be awesome
private void PDFCreation(){
PdfDocument document=new PdfDocument();
PdfDocument.PageInfo pageInfo;
PdfDocument.Page page;
Canvas canvas;
int i;
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);
ExifInterface exif;
int rotate = 0;
try
{
exif = new ExifInterface(selectedPhoto);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0)
{
int w = image.getWidth();
int h = image.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
try
{
image = Bitmap.createBitmap(image, 0, 0, w, h, mtx, false);
}
catch(OutOfMemoryError e)
{
e.printStackTrace();
//image = Bitmap.createBitmap(image, 0, 0, w/2, h/2, mtx, false);
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
image=createBitmap(image, 0, 0,
image.getWidth(), image.getHeight(),
matrix, true);
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";
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();
}
document.close();
}

Android Studio - How to avoidOutOfMemoryError when rotating images

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

how to solve image capturing automatically rotating 90 degrees in android?

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);
}

Save rotated Bitmap

itI take a picture from the camera and I simply want to save it with the correct orientation.
I know their is quite a few post about that subject but even after reading all the answers I got stuck to save my rotated Bitmap.
So here si my code:
Bitmap bitmap = BitmapFactory.decodeFile(pictureFile
.getAbsolutePath());
Matrix matrix = new Matrix();
matrix.postRotate(finalOrientation);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
findViewById(R.id.image_preview).setVisibility(View.VISIBLE);
((ImageView) findViewById(R.id.image_preview)).setImageBitmap(rotatedBitmap);
findViewById(R.id.surfaceView).setVisibility(View.GONE);
if(outputStream != null)
{
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
As you can see I show up my Bitmap image in an image view to be sure it's in the correct orientation and it is. But it's only when I save (compress) it that it returns to her original state.
Thank you in advance!
This is not an answer, but I want to post some code that might shed light on what is going on, and it does not fit into a comment:
ExifInterface exif;
int rotate = 0;
try {
exif = new ExifInterface (file.getAbsolutePath());
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90: rotate = 1 /*90*/; break;
case ExifInterface.ORIENTATION_ROTATE_180: rotate = 2 /*180*/; break;
case ExifInterface.ORIENTATION_ROTATE_270: rotate = 3 /*270*/; break;
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.d(TAG,"~~~~~~ exifOrientation: rotate="+rotate);

Image oriention issue capture from camera

I was facing a problem image capture from camera it was showing image in landscape even though i capture that image in portrait then i found code online. But i think there is some problem with this code it sometimes didn't work (show image in landscape). So what's wrong there
private void adjustImageOrientation()
{
ExifInterface exif;
int rotate = 0;
try
{
exif = new ExifInterface(filepath);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0)
{
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
try
{
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
catch(OutOfMemoryError e)
{
e.printStackTrace();
//image = Bitmap.createBitmap(image, 0, 0, w/2, h/2, mtx, false);
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
// return image.copy(Bitmap.Config.ARGB_8888, true);
}

Categories

Resources