10

I'm writing an app that can be sent a photo URI from the "Share via" menu in Android.

The kind of URI you get is content://media/external/images/media/556 however ExifInterface wants a standard file name. So how do I read the exif data (I just want orientation) of that file? Here's my (non-working) code:

Uri uri = (Uri)extras.getParcelable(Intent.EXTRA_STREAM);
ContentResolver cr = getContentResolver();
InputStream is = cr.openInputStream(uri);
Bitmap bm = BitmapFactory.decodeStream(is);

// This line doesn't work:
ExifInterface exif = new ExifInterface(uri.toString()); 
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

Any help (other than "you have to write your own ExifInterface class") is appreciated!

Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • did you try new ExifInterface(uri.getPath()); also, you may be able to query the content uri for orientation. – Tom Fobear Dec 27 '11 at 20:50

2 Answers2

17

I found the answer randomly in the Facebook Android SDK examples. I haven't tested it, but it looks like it should work. Here's the code:

public static int getOrientation(Context context, Uri photoUri) {
    /* it's on the external media. */
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);

    int result = -1;
    if (null != cursor) {
        if (cursor.moveToFirst()) {
            result = cursor.getInt(0);
        }
        cursor.close();
    }

    return result;
}
zgc7009
  • 3,371
  • 5
  • 22
  • 34
Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • 4
    hello @timmmm, I tired this code,for finding the orientation of image using photouri. But cursor is throwing nullpointer exception may be it is not getting photouri. Could you suggest any solution for it. – Dory Jul 22 '13 at 11:07
  • @timmmm in the code above you forgot to close cursor - it's a memory leak – GregoryK Mar 16 '16 at 20:00
  • 1
    @Gregory Facebook forgot! Thanks for fixing the code. Btw this is why garbage collection is rubbish - you can't use RAII. – Timmmm Mar 17 '16 at 09:54
  • 1
    Note that this returns the literal orientation in degrees, not the enum representing the value like ExifInterface does. – Justin Meiners Apr 30 '16 at 01:59
  • @JustinMeiners I'm using ExifInterface and StrictMode is picking a detectLeakedClosableObject and killing my app (penaltyDeath) – frankelot Oct 17 '16 at 04:11
  • For image uri's not coming from a media store you can open the URI as a stream and then read the exif data using this library https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html – startoftext Mar 21 '17 at 19:56
1

You can get an ExifInterface using a filename string or InputStream, by doing importing the support ExifInterface in your build.gradle file:

compile 'com.android.support:exifinterface:26.1.0'

then:

private getExifInterfaceFromUri(Uri uri) throws IOException{
    FileInputStream fi = new FileInputStream(uri.getPath());

    return new ExifInterface(stream);
}

Remember that in Android there are multiple Uri types and you may need to use a Content Resolver and other approaches to get the real path from an Uri.

Vitor Hugo Schwaab
  • 1,545
  • 20
  • 31