21

When I take a picture with Android's camera app, it detects the phone's orientation and saves the picture accordingly. So if I take a picture of a building, the roof will be on the topside, whether I hold the phone in landscape position or portrait.

However, when I use

Intent imageCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

to get a picture, the camera app doesn't react to the orientation. If I hold the phone vertically (portrait), the resulting picture will be rotated, with said building's roof to the left of the screen.

How can I set the intent so that the camera will take the orientation into account?

Or can I deduce in some way in what orientation the picture was taken and rotate it myself afterwards?

Or is there another way?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arcantos
  • 1,052
  • 1
  • 13
  • 28

4 Answers4

27

I found the answer. The Exif of the image has an indicator of the orientation. Just in case, Exif can be viewed in Android like this:

ExifInterface exif = new ExifInterface("filepath");  
exif.getAttribute(ExifInterface.TAG_ORIENTATION);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arcantos
  • 1,052
  • 1
  • 13
  • 28
  • 1
    Only available from API Level 10 and on... I'm using this method, but would like a method that would work on lower API versions – Andrew Mackenzie Jun 19 '11 at 13:25
  • 4
    All the orientation stuff looks like API Level 5 to me: http://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION That's Android 2.0: http://developer.android.com/guide/appendix/api-levels.html I'm using it in 2.1 / Api level 7 successfully. – Stan Kurdziel Feb 02 '12 at 10:40
  • 1
    I have implement this feature in our application for image issue. Really Good Feature for image orientation display and manage in developing application........ – Manoj Kumar Apr 04 '12 at 09:28
  • No exif information for me in HTC Widfire S, Android 2.3.6 :( – Andras Balázs Lajtha May 25 '12 at 08:12
11

Read from Exif if available, otherwise read from MediaStore

public static int getImageOrientation(Context context, String imagePath) {
    int orientation = getOrientationFromExif(imagePath);
    if(orientation <= 0) {
        orientation = getOrientationFromMediaStore(context, imagePath);
    }

    return orientation;
}

private static int getOrientationFromExif(String imagePath) {
    int orientation = -1;
    try {
        ExifInterface exif = new ExifInterface(imagePath);
        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
                ExifInterface.ORIENTATION_NORMAL);

        switch (exifOrientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                orientation = 270;

                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                orientation = 180;

                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                orientation = 90;

                break;

            case ExifInterface.ORIENTATION_NORMAL:
                orientation = 0;

                break;
            default:
                break;
        }
    } catch (IOException e) {
        Log.e(LOG_TAG, "Unable to get image exif orientation", e);
    }

    return orientation;
}

private static int getOrientationFromMediaStore(Context context, String imagePath) {
    Uri imageUri = getImageContentUri(context, imagePath);
    if(imageUri == null) {
        return -1;
    }

    String[] projection = {MediaStore.Images.ImageColumns.ORIENTATION};
    Cursor cursor = context.getContentResolver().query(imageUri, projection, null, null, null);

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

    return orientation;
}

private static Uri getImageContentUri(Context context, String imagePath) {
    String[] projection = new String[] {MediaStore.Images.Media._ID};
    String selection = MediaStore.Images.Media.DATA + "=? ";
    String[] selectionArgs = new String[] {imagePath};
    Cursor cursor = context.getContentResolver().query(IMAGE_PROVIDER_URI, projection, 
            selection, selectionArgs, null);

    if (cursor != null && cursor.moveToFirst()) {
        int imageId = cursor.getInt(0);
        cursor.close();

        return Uri.withAppendedPath(IMAGE_PROVIDER_URI, Integer.toString(imageId));
    } 

    if (new File(imagePath).exists()) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DATA, imagePath);

        return context.getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    } 

    return null;
}
user2832184
  • 139
  • 1
  • 2
4

For a quick fix, you can check if the image's width is bigger than the image's height. It means it's landscape and you can change it to portrait.

private Bitmap fromGallery(final Uri selectedImageUri) {
    try {
        Bitmap bm = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);

        ExifInterface exif = new ExifInterface(selectedImageUri.getPath());
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        int angle = 0;
        switch (orientation) {

            case ExifInterface.ORIENTATION_ROTATE_90:
                angle = 90;
                break;

            case ExifInterface.ORIENTATION_ROTATE_180:
                angle = 180;
                break;

            case ExifInterface.ORIENTATION_ROTATE_270:
                angle = 270;
                break;

            default:
                angle = 0;
                break;
        }

        Matrix mat = new Matrix();

        if (angle == 0 && bm.getWidth() > bm.getHeight())
            mat.postRotate(90);
        else
            mat.postRotate(angle);

        return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mat, true);

    }
    catch (IOException e) {
        Log.e("", "-- Error in setting image");
    }
    catch (OutOfMemoryError oom) {
        Log.e("", "-- OOM Error in setting image");
    }
    return null;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
savepopulation
  • 11,736
  • 4
  • 55
  • 80
2

I used a file provider and nothing worked except making a temporary copy and reading the data from it.

public static int getOrientation(Context context, Uri uri) {

    int rotate = 0;

    try {

        ParcelFileDescriptor parcelFileDescriptor =
                context.getContentResolver().openFileDescriptor(uri, "r");

        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();

        FileInputStream input = new FileInputStream(fileDescriptor);

        File tempFile = File.createTempFile("exif", "tmp");

        String tempFilename = tempFile.getPath();

        FileOutputStream output = new FileOutputStream(tempFile.getPath());

        int read;

        byte[] bytes = new byte[4096];

        while ((read = input.read(bytes)) != -1) {
            output.write(bytes, 0, read);
        }

        input.close();
        output.close();

        ExifInterface exif = new ExifInterface(tempFile.getAbsolutePath());
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
        }

    } catch (Exception e) {
        Log.i(TAG, e.getLocalizedMessage());
    }

    return rotate;
}

bonus rotate function

public static Bitmap rotateImage(Context context, Uri uri, int orientation) throws IOException {

    ParcelFileDescriptor parcelFileDescriptor =
            context.getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();

    if (orientation > 0) {
        Matrix matrix = new Matrix();
        matrix.postRotate(orientation);

        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }

    return bitmap;
}
Ricardo Saracino
  • 1,345
  • 2
  • 16
  • 37