-
-
Save 9re/1990019 to your computer and use it in GitHub Desktop.
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; | |
} | |
} |
out of memory Exception in my case.
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;
}
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
Awsome Man.
@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.
Thank you kindly sir! :) greatly appreciated!
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...
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.
thanks man
Thank you
Awesome. Thanks man
Thank you!
Perfect. Just dont forget to delete bitmap.recycle() line if you gonna use bitmap variable again in the future.
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);
Xamarin.Android variant here.
This is fantastic, thanks for sharing. Truly.