Arcantos
Arcantos

Reputation: 1072

How can I find the orientation of a picture taken with Intent MediaStore.ACTION_IMAGE_CAPTURE?

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?

Upvotes: 21

Views: 22776

Answers (4)

savepopulation
savepopulation

Reputation: 11921

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

Upvotes: 4

Arcantos
Arcantos

Reputation: 1072

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

Upvotes: 27

Ricardo Saracino
Ricardo Saracino

Reputation: 1420

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

Upvotes: 2

user2832184
user2832184

Reputation: 139

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

Upvotes: 11

Related Questions