sarabhai05
sarabhai05

Reputation: 598

Android : How to detect the image orientation (portrait or landscape) picked from gallery while setting on an imageview?

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

Upvotes: 41

Views: 84559

Answers (8)

İlker Elçora
İlker Elçora

Reputation: 650

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;
}

Upvotes: 1

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
}

}

Upvotes: 4

Deepak
Deepak

Reputation: 2009

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..

Upvotes: 62

Andrew Moreau
Andrew Moreau

Reputation: 57

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.

Upvotes: 3

lucasddaniel
lucasddaniel

Reputation: 1789

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

Upvotes: 0

ultimate
ultimate

Reputation: 727

                      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);

Upvotes: 3

ilmetu
ilmetu

Reputation: 558

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;
}

Upvotes: -1

sarabhai05
sarabhai05

Reputation: 598

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);

Upvotes: 6

Related Questions