5

In my android application i am loading image from device gallery.In that, i am facing issue regarding image orientation. When i load large resolution images from gallery, they are automatically rotated then display in my view. I tried various solution regarding this problem but couldn't get proper solution. I referred getOrientation() , and this links. I have tried both solutions but couldn't got desired result.The ExifInterface return proper data but then also they are not helpful as images are rotated because of their large resolution not because of camera orientation. Please help me to solve this solution.

Thank you.

Community
  • 1
  • 1
Zankhna
  • 4,470
  • 8
  • 60
  • 101

2 Answers2

26

Make one class named ExifUtils

public class ExifUtils {
/**
 * @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;
}

Now you can call it in your Activity by:

  ExifUtils.rotateBitmap("your Image path here", "your bitmap object here");

EDIT:

 public void decodeFile(String filePath) {

    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, o);

    // The new size we want to scale to
    final int REQUIRED_SIZE = 1024;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    Bitmap b1 = BitmapFactory.decodeFile(filePath, o2);
    Bitmap b= ExifUtils.rotateBitmap(filePath, b1);

    // image.setImageBitmap(bitmap);
}

now call this method

  decodeFile(imagepath);

Thanks!

Jonas
  • 6,812
  • 8
  • 31
  • 51
Piyush
  • 24,288
  • 6
  • 40
  • 72
  • i called it in my activity like this : `Bitmap b1 = BitmapFactory.decodeFile(imagePath); b = ExifUtils.rotateBitmap(imagePath, b1);` but not working. I think your solution is proper because in `ExifUtil` class it executes `case 6` which is correct. I don't know why not working . – Zankhna Dec 17 '13 at 13:08
  • Are these imports correct in class ? `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;` – Zankhna Dec 17 '13 at 13:11
  • No. i am just writing : `Bitmap b1 = BitmapFactory.decodeFile(imagePath);` and passing that `b1` in your function. – Zankhna Dec 17 '13 at 13:15
  • @zanky its my pleasure...wel come – Piyush Dec 17 '13 at 13:21
  • not working, I have a scale down image, I just call ExifUtils.rotateBitmap(picPath, smallBitmap); .. getExifOrientation returns 0.. ? – M. Usman Khan Feb 16 '16 at 13:41
1

This works well;

public class ExifUtils {

public static Bitmap getRotatedBitmap(Context context, Uri uri) {
    try {
        Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
        float width = (float) bitmap.getWidth();
        float height = (float) bitmap.getHeight();
        float max = Math.max(width / 1280.0f, height / 1280.0f);
        if (max > 1.0f) {
            bitmap = Bitmap.createScaledBitmap(bitmap, (int) (width / max), (int) (height / max), false);
        }
        Bitmap rotateBitmap = rotateBitmap(bitmap,
                new ExifInterface(context.getContentResolver().openInputStream(uri))
                        .getAttributeInt(ExifInterface.TAG_ORIENTATION, 1));
        if (rotateBitmap != bitmap) {
            bitmap.recycle();
        }
        return rotateBitmap;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

private static Bitmap rotateBitmap(Bitmap bitmap, int i) {
    Matrix matrix = new Matrix();
    switch (i) {
        case 2:
            matrix.setScale(-1.0f, 1.0f);
            break;
        case 3:
            matrix.setRotate(180.0f);
            break;
        case 4:
            matrix.setRotate(180.0f);
            matrix.postScale(-1.0f, 1.0f);
            break;
        case 5:
            matrix.setRotate(90.0f);
            matrix.postScale(-1.0f, 1.0f);
            break;
        case 6:
            matrix.setRotate(90.0f);
            break;
        case 7:
            matrix.setRotate(-90.0f);
            matrix.postScale(-1.0f, 1.0f);
            break;
        case 8:
            matrix.setRotate(-90.0f);
            break;
        default:
            return bitmap;
    }
    try {
        Bitmap createBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
        bitmap.recycle();
        return createBitmap;
    } catch (OutOfMemoryError e) {
        e.printStackTrace();
        return null;
    }
  }
}
Ahmet B.
  • 803
  • 7
  • 14