Android camera unexplainable rotation on capture for some devices (not in EXIF)

Scott Merritt picture Scott Merritt · Oct 4, 2010 · Viewed 30.7k times · Source

What I'm doing seems like it should be simple, but I'm still lost after I've read every possible Stackoverflow answer I can find and Googled every article I can find.

I'm using a preview SurfaceView and capturing an image from an activity that is set for screenOrientation="landscape" in my AndroidManifest.xml.

I followed the sample Camera app code and thought things were working until I tried my app on a few Motorola devices running 1.5.

I have the OrientationEventListener running OK and I use reflection to see if set the rotation as such:

final int latchedOrientation = roundOrientation(mLastOrientation + 90);

Parameters parameters = preview.camera.getParameters();

JPLog.d("Setting camera rotation = %d", latchedOrientation);
try {
    // if >= 2.0
    Method method = Camera.Parameters.class.getMethod("setRotation",
        int.class);

    if(method != null) {
        method.invoke(parameters, latchedOrientation);
    }

} catch(Throwable t) {
    // if < 2.0
    parameters.set("rotation", latchedOrientation);
}

preview.camera.setParameters(parameters);

NexusOne (OS 2.2) - Works great. latchedOrientation = 0, picture OK without any rotation in the EXIF header.

T-Mobile G1 (OS 1.6) - Also works great. latchedOrientation = 0, picture OK.

Motorola Backflip (OS 1.5) - Image rotated. latchedOrientation = 0, picture has no EXIF rotation in it.

Motorola CLIQ (OS 1.5) - Image rotated. latchedOrientation = 0, picture has no EXIF rotation in it.

What's going on with these Motorola devices? I thought my problem was the Motorola camera driver wasn't rotating the images, so found the Sanselan EXIF reading classes for Android and was preparing to rotate them myself. Funny thing is, there is EXIF headers but no rotation element.

If I set the rotation manually to 90 degrees, the images come out perfect the Motorola devices, but now the G1 and the NexusOne have images that are rotated 90 degrees (not what I want). There has to be something I'm not getting here.

I'm doubting this is a 1.5 issue, or else someone would've posted info on it?

Answer

Rukmal Dias picture Rukmal Dias · Jun 15, 2012

I had this issue and I used this method to capture the image. (Without creating a custom camera)

final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
startActivityForResult(intent, 0);

and did the rest in onActivityResult(int requestCode, int resultCode, Intent data) {}

But the original image (Actual SD card image) was correct and Bitmap was rotated when I fetched like this. Bitmap bmp = BitmapFactory.decodeStream(..

The solution:

    try {
        File f = new File(SD_CARD_IMAGE_PATH);
        ExifInterface exif = new ExifInterface(f.getPath());
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        int angle = 0;

        if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
            angle = 90;
        } 
        else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
            angle = 180;
        } 
        else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
            angle = 270;
        }

        Matrix mat = new Matrix();
        mat.postRotate(angle);

        Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, null);
        Bitmap correctBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);                 
    }
    catch (IOException e) {
        Log.w("TAG", "-- Error in setting image");
    }   
    catch(OutOfMemoryError oom) {
        Log.w("TAG", "-- OOM Error in setting image");
    }