39

I am setting an image on the imageview picked from the gallery(camera album). If the picked image has landscape orientation, it displays perfectly but if the image in in portrait mode(i.e the image was clicked in portrait mode) it is displaying the image with a 90 degree rotation. Now I am trying to find out the orientation just before setting on imageview, but all the images are giving same orientation and same width-height. Here is my code :

Uri selectedImage = intent.getData();
if (selectedImage != null) {
    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);

    int str = new ExifInterface(selectedImage.getPath()).getAttributeInt("Orientation", 1000);
    Toast.makeText(this, "value:" + str, Toast.LENGTH_LONG).show();
    Toast.makeText(this, "width:" + bitmap.getWidth() + "height:" + bitmap.getHeight(), Toast.LENGTH_LONG).show();

portrait mode landscape mode

sarabhai05
  • 578
  • 1
  • 4
  • 12
  • can anyone help me i have same issue..http://stackoverflow.com/questions/28379130/how-to-set-camera-image-orientation –  Feb 07 '15 at 12:02

8 Answers8

60

Use ExifInterface for rotate image. Use this method for get correct value to be rotate captured image from camera.

public 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.i("RotateImage", "Exif orientation: " + orientation);
        Log.i("RotateImage", "Rotate value: " + rotate);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return rotate;
}

And put this code in Activity result method and get value to rotate image...

String selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};

Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();

int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();

int rotateImage = getCameraPhotoOrientation(MyActivity.this, selectedImage, filePath);

Hope this helps..

Deepak
  • 1,989
  • 1
  • 18
  • 20
  • 4
    exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); is always returning value 0 for any orientation image. – sarabhai05 Oct 05 '12 at 06:03
  • sorry i was making a mistake. your approach is working for me. Also the data.getData() returns Uri not String, pls have a look in ur code. – sarabhai05 Oct 05 '12 at 07:25
  • 10
    @Deepak Why do I have to call `context.getContentResolver().notifyChange(imageUri, null)`? – Maksim Sorokin Dec 09 '13 at 09:52
  • With the above code if you are not able to rotate image in clockwise direction with respect to the rotation angle please add one line while setting image to image view `imageView.setRotation(angle);` this line helped me . – Sagar Nov 01 '17 at 06:17
  • Thanks, but can I use same code for capturing video? – Yashoda Bane Mar 12 '19 at 11:58
  • I've tried this solution and it works just fine. All the answers are about how to solve this, and I couldn't find out anything about the reason why this rotation happens in portrait mode in Adnroid. Any idea why this kinda auto rotation happens (if I'm getting this right)? – Zahra Ahangari Oct 20 '22 at 03:15
6

This is also working for me:

String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = getContentResolver().query(imageUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
    orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
sarabhai05
  • 578
  • 1
  • 4
  • 12
3
                      if(bm.getWidth() > bm.getHeight())
                        {
                            Bitmap bMapRotate=null;
                            Matrix mat=new Matrix();
                            mat.postRotate(90);
                        bMapRotate = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), mat, true);
                        bm.recycle();
                        bm=null;
                        imageDisplayView.setImageBitmap(bMapRotate);
                        }else
                        imageDisplayView.setImageBitmap(bm);
ultimate
  • 717
  • 2
  • 10
  • 20
  • 2
    On some devices (like s3 and s4) the width are bigger than height even the image is portrait . that why we don't use this solution even if it look clean and perfect . – Jesus Dimrix Sep 04 '14 at 10:04
  • @JesusDimrix Yes, it may be a case. But if the image does not have orientation information in its header then we can use this way. – ultimate Sep 05 '14 at 13:57
  • i was going crazy trying to get this to workyour way is good enough for me galaxy s what? – Martin Seal May 02 '16 at 00:41
3

Here is a great solution I came across for this: >https://stackoverflow.com/a/34241250/8033090

One line solution:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

or

Picasso.with(context).load("file:" + photoPath).into(imageView);

This will autodetect rotation and place image in correct orientation

Picasso is a very powerful library for handling images in your app includes: Complex image transformations with minimal memory use. It can take a second to load but I just put some text behind the image view that says "Loading image" and when the image loads it covers the text.

  • Does not work for me. The pictures taken on Galaxy S8 or Galaxy S9 are still rotated even with Picasso or Glide – Denys Lobur Jun 25 '18 at 13:46
  • @DenysLobur are u found solution ? i stack with this too. Have problem with galaxy s8 – Peter Jul 13 '18 at 11:54
  • Hey @Peter, I guess I found solution. You basically need to implement this https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html. Samsung phones give 'val rotationConstant = ExifInterface.ORIENTATION_*' as some value, like 1, 3, 6 etc., while other phones (Xiaomi, in my case) give 'val rotationConstant = ExifInterface.ORIENTATION_UNDEFINED' which equals to 0. Then, knowing the rotation constant, you can rotate your image the way you like or rotate it to 0 in case of not Samsung phones – Denys Lobur Oct 08 '18 at 12:36
2

Using kotlin and considering the change in uri and in exif in new android versions:

 var exif: ExifInterface? = null;
 try {
    when (Build.VERSION.SDK_INT) {
        in Int.MIN_VALUE..24 -> exif = ExifInterface(imageUri.path)
        else -> exif = ExifInterface(getContentResolver().openInputStream(data.extras.get("data")))
     }
 } catch (e: IOException) {
     e.printStackTrace();
 }
 val orientation = exif?.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
 bmp = rotateBitmap(bmp, orientation ?: ExifInterface.ORIENTATION_NORMAL)

And the rotateBitmap function is:

un rotateBitmap(bitmap: Bitmap, orientation: Int): Bitmap {
val matrix = Matrix()
when (orientation) {
    ExifInterface.ORIENTATION_NORMAL -> return bitmap
    ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.setScale(-1f, 1f)
    ExifInterface.ORIENTATION_ROTATE_180 -> matrix.setRotate(180f)
    ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
        matrix.setRotate(180f)
        matrix.postScale(-1f, 1f)
    }
    ExifInterface.ORIENTATION_TRANSPOSE -> {
        matrix.setRotate(90f)
        matrix.postScale(-1f, 1f)
    }
    ExifInterface.ORIENTATION_ROTATE_90 -> matrix.setRotate(90f)
    ExifInterface.ORIENTATION_TRANSVERSE -> {
        matrix.setRotate(-90f)
        matrix.postScale(-1f, 1f)
    }
    ExifInterface.ORIENTATION_ROTATE_270 -> matrix.setRotate(-90f)
    else -> return bitmap
}
try {
    val bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    bitmap.recycle()
    return bmRotated
} catch (e: OutOfMemoryError) {
    e.printStackTrace()
    return null
}

}

1

Using the EXIF information is not reliable on some android devices. (ExifInterface orientation return always 0)

This is working for me:

Rotate bitmap

public static Bitmap rotateBitmap(Context context, Uri photoUri, Bitmap bitmap) 
{
    int orientation = getOrientation(context, photoUri);
    if (orientation <= 0) {
        return bitmap;
    }

    Matrix matrix = new Matrix();
    matrix.postRotate(orientation);
    bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
    return bitmap;
}

Get orientation from MediaStore

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

    if (cursor.getCount() != 1) {
        cursor.close();
        return -1;
    }

    cursor.moveToFirst();
    int orientation = cursor.getInt(0);
    cursor.close();
    cursor = null;
    return orientation;
}
İlker Elçora
  • 610
  • 5
  • 13
0

Another solution is to use the ExifInterface from support library: ExifInterface from support library

lucasddaniel
  • 1,779
  • 22
  • 22
-1

This work for me :

private String getOrientation(Uri uri){
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    String orientation = "landscape";
    try{
        String image = new File(uri.getPath()).getAbsolutePath();
        BitmapFactory.decodeFile(image, options);
        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;
        if (imageHeight > imageWidth){
            orientation = "portrait";
        }
    }catch (Exception e){
        //Do nothing
    }
    return orientation;
}
ilmetu
  • 448
  • 11
  • 27