Disco S2 Disco S2 - 1 month ago 31
Android Question

Android Camera Intent Saving Image Landscape When Taken Portrait

I have had a look around but there doesn't seem to be a solid answer/solution to the, very irritating, problem.

I take a picture in portrait orientation and when I hit save/discard the buttons are in the correct orientation also. The problem is when I then retrieve the image later on it is in landscape orientation (the picture has been rotated 90 degrees anti-clockwise)

I don' want to force the user to use the camera in a certain orientation.

Is there a way to maybe detect whether the photo was taken in portrait mode and then decode the bitmap and flip it the correct way up?

Answer

The picture is always taken in the orientation the camera is built into the device. To get your image rotated correctly you'll have to read the orientation information that is stored into the picture (EXIF meta data). There it is stored how the device was oriented, when the image was taken.

Here is some code that reads the EXIF data and rotates the image accordingly: file is the name of the image file.

BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);

BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
ExifInterface exif = new ExifInterface(file);
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) :  ExifInterface.ORIENTATION_NORMAL;

int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;

Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);