Search code examples
androidbitmapuriexif

Using exif to rotate an image


i was following this link Android get Orientation of a camera Bitmap? And rotate back -90 degrees to rotate my image if/when necessary, but its not working for me, i get this error

05-28 23:29:30.049 9735-9735/ss.sealstudios.com.socialstories E/JHEAD: can't open '/document/508'

but checking it like below looks like there pointing in the right place

05-28 23:29:30.049 9735-9735/ss.sealstudios.com.socialstories I/System.out: bitmap uri content://com.android.providers.downloads.documents/document/508 0

//the 0 on the end is me checking for the rotation

i was wondering if this was build version specific like getting the real path from a URI as running this code on my marshmallow device gives me an entirely different result (this result, ie: error codes, is from a kitkat device), but this has defeated me for some weeks now following all sorts of answers to no avail, can anyone weigh in and help me please, here's what I'm trying to do

   if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data 
   != null 
   && data.getData() != null) 
  {

        Uri uri = data.getData();


        try {
            BitmapFactory.Options bitmapOptions = new 
            BitmapFactory.Options();
            bitmapOptions.inSampleSize = (int) 4;
            InputStream inputStream = 
            getContentResolver().openInputStream(uri);
            Bitmap scaledBitmap = BitmapFactory.decodeStream(inputStream, 
            null, bitmapOptions);
            ExifInterface exif = new ExifInterface(uri.getPath());
            int rotation = 
            exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,  
            ExifInterface.ORIENTATION_NORMAL);
            int rotationInDegrees = exifToDegrees(rotation);
            System.out.println("bitmap uri " + uri + " " + rotation);
            Matrix matrix = new Matrix();

            if (rotation != 0f){
                matrix.preRotate(rotationInDegrees);
                Bitmap.createBitmap(scaledBitmap, 0, 
                0,scaledBitmap.getWidth(),scaledBitmap.getHeight(), 
                matrix, true);
                imageView.setImageBitmap(scaledBitmap);

            }else
                imageView.setImageBitmap(scaledBitmap);

        } catch (IOException e) {
            e.printStackTrace();
        }


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

many thanks


Solution

  • ExifInterface exif = new ExifInterface(uri.getPath());
    

    This will not work. If you call getPath() on a Uri, you are doing it wrong, as that is meaningless for most Uri values, particularly those with a content scheme, as your has.

    Since the SDK's ExifInterface only works with local files, you will need other EXIF code. I use some code from the AOSP for this. That version of ExifInterface can work with an InputStream, so you can get a fresh InputStream for the content identified by the Uri and pass that to the alternative ExifInterface.