7

I want to find out the EXIF rotation of an picture. When the picture is displayed in the gallery, it isn't rotated, but after loading the image with the EXIF information 'rotate left' the picture is displayed rotated.

Now i want to ask the user, if he wants to use the rotated image or the original.

I get an Uri to that method and store it an in Bitmap

    InputStream inputStream = PaintroidApplication.applicationContext.getContentResolver().openInputStream(bitmapUri);
    BitmapFactory.decodeStream(inputStream, null, options);
    inputStream.close();

Now i want to use the ExifInterface to determinate the rotation, but ExifInterface requires a path:

        ExifInterface exif = new ExifInterface(bitmapUri.getPath());
        rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

Now i have a problem with the path and logcat shows the following message:

E/JHEAD﹕ can't open '/document/image:15035'

How can i solve this problem or is there an other solution to find out the EXIF information?

BrainPain
  • 81
  • 1
  • 1
  • 3

3 Answers3

6

I have encountered this same issue. The pickers provided by the api in V19 and above may give you this result. Give the code below a try, should solve your issue.


Your modified code

String path = FileUtility.getRealPathFromURI(context, Uri.parse(bitmapUri.getPath());
ExifInterface exif = new ExifInterface(path);
rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

FileUtility.java

/**
 * Gets the real path from file
 * @param context
 * @param contentUri
 * @return path
 */
public static String getRealPathFromURI(Context context, Uri contentUri) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        return getPathForV19AndUp(context, contentUri);
    } else {
        return getPathForPreV19(context, contentUri);
    }
}

/**
 * Handles pre V19 uri's
 * @param context
 * @param contentUri
 * @return
 */
public static String getPathForPreV19(Context context, Uri contentUri) {
    String res = null;

    String[] proj = { MediaStore.Images.Media.DATA };
    Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
    if(cursor.moveToFirst()){;
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        res = cursor.getString(column_index);
    }
    cursor.close();

    return res;
}

/**
 * Handles V19 and up uri's
 * @param context
 * @param contentUri
 * @return path
 */
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPathForV19AndUp(Context context, Uri contentUri) {
    String wholeID = DocumentsContract.getDocumentId(contentUri);

    // Split at colon, use second item in the array
    String id = wholeID.split(":")[1];
    String[] column = { MediaStore.Images.Media.DATA };

    // where id is equal to
    String sel = MediaStore.Images.Media._ID + "=?";
    Cursor cursor = context.getContentResolver().
            query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    column, sel, new String[]{ id }, null);

    String filePath = "";
    int columnIndex = cursor.getColumnIndex(column[0]);
    if (cursor.moveToFirst()) {
        filePath = cursor.getString(columnIndex);
    }

    cursor.close();
    return filePath;
}
the-ginger-geek
  • 7,041
  • 4
  • 27
  • 45
  • 1
    this code almost works for me. thanks. one thing to add is DocumentsContract.getDocumentId(contentUri) only work if the DocumentsContract.isDocumentUri return true. so i went with if it is >=19 and isDocumentUri then use getPathForV19AndUp. otherwise use getPathForPreV19. – RyanShao Oct 29 '15 at 09:48
  • The type of the variable is in the name but you can read up on it in the documentation as well. https://developer.android.com/reference/android/support/media/ExifInterface#getattributeint – the-ginger-geek Apr 06 '20 at 09:16
2

You can read ExifInterface from file uri like this:

val inputStream = context.contentResolver.openInputStream(fileUri)
val exif = ExifInterface(inputStream)
val rotate = when (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) {
        ExifInterface.ORIENTATION_ROTATE_270 -> 270
        ExifInterface.ORIENTATION_ROTATE_180 -> 180
        ExifInterface.ORIENTATION_ROTATE_90 -> 90
        else -> 0
    }
inputStream.close()
Axbor Axrorov
  • 2,720
  • 2
  • 17
  • 35
1

The problem is on the permissions. Add the permission android.permission.READ_EXTERNAL_STORAGE to your manifest.

Ze Luis
  • 236
  • 2
  • 15