Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with Android devices that do not honor EXIF orientation data?

I'm testing my app on HTC Desire with Android 2.2. and it works exactly as I'd love to. I use Sherlock packages to have same style on older devices as on newer.

My AVD is set to use the latest android, and it also looks ok. Then I've placed it to Samsung Galaxy S2, and as I work with camera and gallery images, they are rotated wrong. It seams that something on Samsung (camera app, android it self) does not or it does check EXIF and my images are oriented wrong. Portrait images are loaded in landscape, and landscape images are loaded in portrait.

  1. I guess I need to check EXIF somehow and ignore it in order to load images as they are?
  2. Bigger problem is - how to know if there are any other devices (some HTC, some HUAWEI some whatsoever) that will do similar problem? I thought all android devices behave the same way beside having 4 screen size groups...

Tnx.

like image 961
Balkyto Avatar asked Sep 25 '12 06:09

Balkyto


1 Answers

Without any code is hard to tell what's going on.

The most simple way i've found is to read the EXIF information and check if the image needs rotation. To read more on ExifInterface class on Android: http://developer.android.com/intl/es/reference/android/media/ExifInterface.html

That said, here is some example code:

/** An URI and a imageView */
public void setBitmap(ImageView mImageView, String imageURI){
    // Get the original bitmap dimensions
    BitmapFactory.Options options = new BitmapFactory.Options();            
    Bitmap bitmap = BitmapFactory.decodeFile(imageURI, options);
    float rotation = rotationForImage(getActivity(), Uri.fromFile(new File(imageURI)));

    if(rotation!=0){
        //New rotation matrix
        Matrix matrix = new Matrix();
        matrix.preRotate(rotation);
        mImageView.setImageBitmap(Bitmap.createBitmap(bitmap, 0, 0, reqHeight, reqWidth, matrix, true));
    } else {
        //No need to rotate
        mImageView.setImageBitmap(BitmapFactory.decodeFile(imageURI, options));
    }
}


/** Returns how much we have to rotate */
public static float rotationForImage(Context context, Uri uri) {
        try{
            if (uri.getScheme().equals("content")) {
                //From the media gallery
                String[] projection = { Images.ImageColumns.ORIENTATION };
                Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
                    if (c.moveToFirst()) {
                        return c.getInt(0);
                    }               
            } else if (uri.getScheme().equals("file")) {
                 //From a file saved by the camera
                    ExifInterface exif = new ExifInterface(uri.getPath());
                    int rotation = (int) exifOrientationToDegrees(exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL));
                    return rotation;
            }
            return 0;

        } catch (IOException e) {
            Log.e(TAG, "Error checking exif", e);
            return 0;
        }
}

/** Get rotation in degrees */
private static float exifOrientationToDegrees(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;
}

If there is an error you will see the log "Error checking EXIF" on rotationForImage function.

like image 162
nsemeniuk Avatar answered Nov 30 '22 23:11

nsemeniuk