Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
fix flipped / rotated image by getting exif orientation
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.os.Build;
public class ExifUtil {
/**
* @see http://sylvana.net/jpegcrop/exif_orientation.html
*/
public static Bitmap rotateBitmap(String src, Bitmap bitmap) {
try {
int orientation = getExifOrientation(src);
if (orientation == 1) {
return bitmap;
}
Matrix matrix = new Matrix();
switch (orientation) {
case 2:
matrix.setScale(-1, 1);
break;
case 3:
matrix.setRotate(180);
break;
case 4:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case 5:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case 6:
matrix.setRotate(90);
break;
case 7:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case 8:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return oriented;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
private static int getExifOrientation(String src) throws IOException {
int orientation = 1;
try {
/**
* if your are targeting only api level >= 5
* ExifInterface exif = new ExifInterface(src);
* orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
*/
if (Build.VERSION.SDK_INT >= 5) {
Class<?> exifClass = Class.forName("android.media.ExifInterface");
Constructor<?> exifConstructor = exifClass.getConstructor(new Class[] { String.class });
Object exifInstance = exifConstructor.newInstance(new Object[] { src });
Method getAttributeInt = exifClass.getMethod("getAttributeInt", new Class[] { String.class, int.class });
Field tagOrientationField = exifClass.getField("TAG_ORIENTATION");
String tagOrientation = (String) tagOrientationField.get(null);
orientation = (Integer) getAttributeInt.invoke(exifInstance, new Object[] { tagOrientation, 1});
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return orientation;
}
}
@joshuapinter

This comment has been minimized.

Copy link

@joshuapinter joshuapinter commented Mar 15, 2014

This is fantastic, thanks for sharing. Truly.

@naveedahmad99

This comment has been minimized.

Copy link

@naveedahmad99 naveedahmad99 commented May 13, 2014

out of memory Exception in my case.

@ademar111190

This comment has been minimized.

Copy link

@ademar111190 ademar111190 commented Aug 15, 2014

about exif, why not uses it instead reflection:

ExifInterface exifInterface = new ExifInterface(src);
return exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

and about switch why not uses consts instead magic numbers?

switch (orientation) {
    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;
    }
@ngocnv27121982

This comment has been minimized.

Copy link

@ngocnv27121982 ngocnv27121982 commented Jun 3, 2015

U can download app library for developer
https://play.google.com/store/apps/details?id=com.libraries.developers

i see it has sourcecode vary lib ulits for android and it reslove problem of U

@green22sanjay

This comment has been minimized.

Copy link

@green22sanjay green22sanjay commented Aug 7, 2015

Awsome Man.

@paulirwin

This comment has been minimized.

Copy link

@paulirwin paulirwin commented Oct 19, 2015

@ademar111190: The author did both of those things to support SDK levels < 5, as they mentioned in the comment. If you are targeting >= 5, you can certainly do your approach as the ExifInterface type will be available to you.

@ka05

This comment has been minimized.

Copy link

@ka05 ka05 commented Jun 13, 2016

Thank you kindly sir! :) greatly appreciated!

@GeorgeProgrammer

This comment has been minimized.

Copy link

@GeorgeProgrammer GeorgeProgrammer commented Jul 5, 2016

This code is really good. Thank you !!! Can you help me with one problem?? Please, i have a camera application and my app work all time when the device have Android < 6.0. I think i must change the manifest...

@WhatFreshHellIsThis

This comment has been minimized.

Copy link

@WhatFreshHellIsThis WhatFreshHellIsThis commented Dec 15, 2016

Shouldn't this line:
if (Build.VERSION.SDK_INT >= 5) {

Actually be <5? Because if not then the comment above it directly contradicts it.
This seems to be incorrect.

@dfsilva

This comment has been minimized.

Copy link

@dfsilva dfsilva commented Jan 20, 2018

thanks man

@CassioRubens

This comment has been minimized.

Copy link

@CassioRubens CassioRubens commented Feb 13, 2018

Thank you

@lonelyenvoy

This comment has been minimized.

Copy link

@lonelyenvoy lonelyenvoy commented Feb 24, 2018

Awesome. Thanks man

@otonii

This comment has been minimized.

Copy link

@otonii otonii commented Apr 4, 2018

Thank you!

@yusufcaglar-zz

This comment has been minimized.

Copy link

@yusufcaglar-zz yusufcaglar-zz commented Apr 8, 2018

Perfect. Just dont forget to delete bitmap.recycle() line if you gonna use bitmap variable again in the future.

@kevinkia65

This comment has been minimized.

Copy link

@kevinkia65 kevinkia65 commented Feb 1, 2019

I get this error: error: variable photoFile might not have been initialized.

I am using this code as follows:

String imagePath = photoFile.getAbsolutePath(); // photoFile is a File class.
Bitmap myBitmap = BitmapFactory.decodeFile(imagePath);

Bitmap orientedBitmap = ExifUtil.rotateBitmap(imagePath, myBitmap);

@joemather

This comment has been minimized.

Copy link

@joemather joemather commented Nov 13, 2020

Xamarin.Android variant here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment