32

I'm getting picture to my app from camera / gallery intent. In many phones picture that I read from the intent / Uri is already rotated to correct orientation. For example N1, Legend, Desire that is the case.

But then on some phones ( for example Milestone1, GalaxyS) the picture is always in landscape more no matter which way the picture was taken. This means that in my application portrait picture is presented wrong way to the user. I tried to read EXIF info of the picture but orientation tag is always 0. There has to be a way to find out the right orientation of the picture because in Milestone1 the gallery application shows the portrait pictures correctly.

How do I know if I need to rotate the picture myself before showing it to the user?

Thank you for you help!

Juhani
  • 5,076
  • 5
  • 33
  • 35
  • 1
    Did you get this solved? I'm having the exact same issue. – Eric Novins Mar 29 '11 at 18:13
  • No, I never found a solution for this. I ended up adding a button to UI for manually rotating the image in the cases it doesn't work – Juhani Mar 29 '11 at 20:45
  • 2
    Here's how i've resolved this issue; http://stackoverflow.com/a/8864367/137404 – Tolga E Jul 16 '12 at 17:32
  • It Worked for me.. ! Solved Solution [Solved : How to rotate image to its default orientation selected from gallery in android](http://stackoverflow.com/questions/40758952/solved-how-to-rotate-image-to-its-defauld-orientation-selected-from-gallery-in) – Muhammad Jamal Nov 23 '16 at 08:08

12 Answers12

25

Florian answer is working for gallery images.

The following code works for captured images, havn't tried with gallery images but i believe it should work. Hope this helps anybody.

Code :

public static int getCameraPhotoOrientation(Context context, 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;
         }


         Log.v(TAG, "Exif orientation: " + orientation);
     } catch (Exception e) {
         e.printStackTrace();
     }
    return rotate;
 }

EDIT: As can be read in the comments, some devices do not support Exif information, havn't checked which but i think HTC doesn't. be sure to check what devices and create an alternative.

spydon
  • 9,372
  • 6
  • 33
  • 63
eric.itzhak
  • 15,752
  • 26
  • 89
  • 142
  • 1
    Which devices you've tried? I've used pretty much exactly the same code but it doesn't work on all devices due to the fact that not all devices include EXIF data to the returned images. Motorola & Samsung devices tend to have the problem. – Juhani Jun 18 '12 at 14:50
  • I tried it on Samsung Galaxy S1 and it worked. – eric.itzhak Jun 18 '12 at 15:31
  • Still works on newest Samsung devices, especially 4.3 where this bug still persists. Seems to be fixed in 4.4 – Demonick Aug 06 '14 at 06:28
  • 2
    @eric.itzhak what's the purpose of the line "context.getContentResolver().notifyChange(imageUri, null);" ? – Malachiasz Nov 04 '15 at 13:32
  • not working on htc one m8 (6.0) and Nexus 5x (8.1.1) always return 1 – Ahmad Arslan Nov 16 '17 at 06:58
16

The following method returns the orientation of an image in degrees. It works with images from the gallery. Return values for:

  • normal landscape: 0
  • normal portrait: 90
  • upside-down landscape: 180
  • upside-down portrait: 270
  • image not found: -1

The code:

public static int getOrientation(Context context, Uri photoUri) {
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[] { MediaStore.Images.ImageColumns.ORIENTATION },
            null, null, null);

    try {
        if (cursor.moveToFirst()) {
            return cursor.getInt(0);
        } else {
            return -1;
        }
    } finally {
        cursor.close();
    }
}
Florian Fankhauser
  • 3,615
  • 2
  • 26
  • 30
3
        int rotate = 0;
        try {
            File imageFile = new File(sourcepath);
            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) {
            e.printStackTrace();
        }
        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
vineet pal
  • 131
  • 1
  • 3
2

This is the best answer I have found, by ramaral. https://stackoverflow.com/a/20480741/2258389
Works great for gallery or camera

Community
  • 1
  • 1
Jason
  • 213
  • 1
  • 3
  • 13
1
Matrix matrix = new Matrix();

ExifInterface exifReader = new ExifInterface(filePath);

int orientation = exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);

if (orientation ==ExifInterface.ORIENTATION_NORMAL) {

      // Do nothing. The original image is fine.

} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {

       matrix.postRotate(90);

} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {

       matrix.postRotate(180);

} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {

      matrix.postRotate(270);

}
Sirko
  • 72,589
  • 19
  • 149
  • 183
Anh Duy
  • 81
  • 1
  • 2
1

I have the same problem with S1, and I noted even if you open the image using stock gallery app it will open in landscape mode(the phone doesn’t know the correct orientation for photo).
And if you rotate the phone to portrait in camera app the icons (take pic, focus and settings) will not rotated, try that in S2 or any device support landscape/portrait camera those icons will be rotated.

What I am sure the stock camera app doesn’t support taking photos in prorate mode.

JafarKhQ
  • 8,676
  • 3
  • 35
  • 45
1

You have to create the gallery object using contentresolver first and then pass the uri created to the image capture intent. Then you can look at the exif data, NOT the gallery orientation data.

Eric Novins
  • 431
  • 3
  • 15
  • Awesome thanks for the reply. I'll try if this solves our problem ASAP. – Juhani Apr 05 '11 at 09:42
  • Right, it turns out I don't really understand what you mean by creating a gallery object using content resolver. Could you please point me to the right place of the API of the object type you mean or to an example code describing the process. Thank you! – Juhani Apr 05 '11 at 10:08
  • After searching around I found an example of how to do this here: http://geek.gankahhwee.com/2010/11/19/android-invoking-camera-to-take-picturevideo/. Unfortunately, after writing some code using getContentResolver() to create my Uri I still have the same problem of EXIF orientation always being "0". – Zac Seth Apr 12 '11 at 15:42
0

Use it this way!

private static int exifToDegrees(int exifOrientation) {
    if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
        return 90;
    } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
        return 180;
    } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
        return 270;
    }
    return 0;
}

And in the code,

Bitmap newImage = Bitmap.createBitmap(actualImage, 0, 0, width, height, matrix, true);

Simple!

nithinreddy
  • 6,167
  • 4
  • 38
  • 44
0

What I am doing : first check the orientation of image taken by camera using its meta data information , and If we found this in portrait then we have to rotate the image by 90 and display otherwise only display.

For getting the Information about orientation of image we can use Exif interface. That's It!

g4gaj
  • 85
  • 2
  • 11
0

The simple exiftodegree answers only consistently work when you have taken a photo and i use it for such. For those of you experiencing issues with choosing a photo and getting the correct orientation, see my answer here: Image Orientation - Android

Community
  • 1
  • 1
A.Sanchez.SD
  • 1,950
  • 2
  • 18
  • 23
0

I already did that for a project, because I had the same problem (Android thinking you'll only do a picture on landscape). What I did was detecting the phone orientation at the time, and then rotate the image. It supposes the orientation is still the same when the intent is received, though.

Valentin Rocher
  • 11,667
  • 45
  • 59
  • This solution isn't really an option for us :( We need to make our app to work every time otherwise the quality won't be acceptable. There must a better way as the gallery application can handle the orientation correctly on both phones. – Juhani Dec 23 '10 at 12:17
0

This looks like the same problem that was solved in this question: Android: Bitmaps loaded from gallery are rotated in ImageView

Community
  • 1
  • 1
Loktar
  • 546
  • 3
  • 11