Thursday, August 23, 2012

Check orientation of images/captures

A lot of times, you would need your app to either pick an image from the gallery or use the device's camera for capturing a picture that your app could use. I have seen a lot of apps, do it plain wrong. Especially, the orientation of the images.

The default gallery app, reads the orientation properly, and displays the images/thumbnails properly. So, our apps can also handle images in various orientations properly. And the good news is, it's very easy to handle.

There's a class called ExifInterface. Most of the times, when you have a similar situation, you would almost never want a full-scaled image to be shown in your app. Most often, we use a thumbnail view for the purpose. The following code would get you a re-sized bitmap, from your original file.

Say for example, we have this path to the actual image file. imagePath

1. Create a Bitmap from the file

Bitmap b = BitmapFactory.decodeFile(imagePath);

2. Resize the Bitmap by scaling it to appropriate level
int width = b.getWidth();
int height = b.getHeight();
int newWidth = 150;
int newHeight = 150;
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// Bitmap resizedBitmap = Bitmap.createBitmap(b, 0, 0, width, height, matrix, true);
// resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 70, out);

3. Handle orientation of the image
ExifInterface exif = new ExifInterface(imagePath);
String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
if (orientation.equals(ExifInterface.ORIENTATION_NORMAL)) {
        // Do nothing. The original image is fine.
} else if (orientation.equals(ExifInterface.ORIENTATION_ROTATE_90+"")) {
        matrix.postRotate(90);
} else if (orientation.equals(ExifInterface.ORIENTATION_ROTATE_180+"")) {
        matrix.postRotate(180);
} else if (orientation.equals(ExifInterface.ORIENTATION_ROTATE_270+"")) {
        matrix.postRotate(270);
}

4. Save the new bitmap 
out = new FileOutputStream(new File("some output file path"));
Bitmap resizedBitmap = Bitmap.createBitmap(b, 0, 0, width, height, matrix, true);
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 70, out);
Now your output file would be an image that is resized and handled properly for orientation of the images. You could directly use the "resized" bitmap, but I prefere files.



4 comments:

  1. Hi Bibek, Thanks for posting this great tutorial,

    I am facing a problem, ExifInterface is not working, It is always returning 0 to me. I am testing on LG Optimus device, Any suggestion ?

    ReplyDelete
    Replies
    1. Ah!!! That's weird. Can you just check with some other device? Which version of Android is it running?

      Delete
    2. Yes, tested on Samsung Galaxy Ace GT-5830i too, same response, Android version is 2.3.6. For both the devices I am getting 0 for exif.getAttribute(ExifInterface.TAG_ORIENTATION).

      Also One more thing I noticed that In Samsung device, captured image are not rotating while with the LG Device it is rotated by 90' clock wise.

      Delete
    3. Then, for Samsung, the value is right. But for the LG one, it's not returning the correct value. I have tried this in Samsung, HTC phones and tablets(Samsung), and it works ok.

      On your LG device, try taking a picture in landscape or reverse landscape and then see what values you get. If it always returns a 0, then it might be a device specific problem.

      Delete