Sami Eltamawy Sami Eltamawy
  • Home
  • About Me
  • Knowledge Base
    • Articles
    • Book Recommendations
    • Press & Media
    • Videos
    • Online Courses
  • Contact Me
  • Login/Signup
  • Log in
  • Home
  • About Me
  • Knowledge Base
    • Articles
    • Book Recommendations
    • Press & Media
    • Videos
    • Online Courses
  • Contact Me
  • Login/Signup
  • Log in
  • Home
  • Technical
  • How To Fix The Camera Intent Rotated Image In Android

Articles Technical

11 Jun

How To Fix The Camera Intent Rotated Image In Android

  • By Sami Eltamawy
  • In Technical

When you capture an image on android using intentandroid.media.action.IMAGE_CAPTURE, it gets rotated 90 degrees on some devices. Here is how to solve this problem with the code snippets. I have tested it on Android 4.1 (Jelly Bean), Android 4.4 (KitKat) and Android 5.0 (Lollipop).

Steps

  1. Scale down the image if it was bigger than 1024×1024.
  2. Rotate the image to the right orientation only if it was rotated 90, 180 or 270 degrees.
  3. Recycle the rotated image for memory purposes.

Here is the code part:

Call the following method with the current Context and the image URI that you want to fix

/**
 * This method is responsible for solving the rotation issue if exist. Also scale the images to
 * 1024x1024 resolution
 *
 * @param context       The current context
 * @param selectedImage The Image URI
 * @return Bitmap image results
 * @throws IOException
 */
public static Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage)
        throws IOException {
    int MAX_HEIGHT = 1024;
    int MAX_WIDTH = 1024;

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
    BitmapFactory.decodeStream(imageStream, null, options);
    imageStream.close();

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    imageStream = context.getContentResolver().openInputStream(selectedImage);
    Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);

    img = rotateImageIfRequired(img, selectedImage);
    return img;
}

 

Here is the CalculateInSampleSize method from the pre-mentioned source:

/**
  * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding
  * bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates
  * the closest inSampleSize that will result in the final decoded bitmap having a width and
  * height equal to or larger than the requested width and height. This implementation does not
  * ensure a power of 2 is returned for inSampleSize which can be faster when decoding but
  * results in a larger bitmap which isn't as useful for caching purposes.
  *
  * @param options   An options object with out* params already populated (run through a decode*
  *                  method with inJustDecodeBounds==true
  * @param reqWidth  The requested width of the resulting bitmap
  * @param reqHeight The requested height of the resulting bitmap
  * @return The value to be used for inSampleSize
  */
private static int calculateInSampleSize(BitmapFactory.Options options,
                                         int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee a final image
        // with both dimensions larger than or equal to the requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

        // This offers some additional logic in case the image has a strange
        // aspect ratio. For example, a panorama may have a much larger
        // width than height. In these cases the total pixels might still
        // end up being too large to fit comfortably in memory, so we should
        // be more aggressive with sample down the image (=larger inSampleSize).

        final float totalPixels = width * height;

        // Anything more than 2x the requested pixels we'll sample down further
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;

        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }
    }
    return inSampleSize;
}

 

Then comes the method that will check the current image orientation to decide the rotation angle

/**
 * Rotate an image if required.
 *
 * @param img           The image bitmap
 * @param selectedImage Image URI
 * @return The resulted Bitmap after manipulation
 */
private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage) throws IOException {

    ExifInterface ei = new ExifInterface(selectedImage.getPath());
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            return rotateImage(img, 90);
        case ExifInterface.ORIENTATION_ROTATE_180:
            return rotateImage(img, 180);
        case ExifInterface.ORIENTATION_ROTATE_270:
            return rotateImage(img, 270);
        default:
            return img;
    }
}

 

Finally the rotation method itself

private static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
img.recycle();
return rotatedImg;
}

Tags:android
  • Share:
Sami Eltamawy
My name is Sami Eltamawy. I am an Application Security Manager at Meta (Formerly Facebook), and Co-Founder of Pet With It, insydo and Brandripplr. I am very passionate about technology, entrepreneurship, cybersecurity, self-development, helping others, and sharing everything I learn or experience.

You may also like

The Arab Cryptanalysts and Al-Kindi’s Method

The Arab Cryptanalysts and Al-Kindi’s Methods

  • 11/04/2022
  • by Sami Eltamawy
  • in Technical
Al-Kindi (801-873), Abu Yusuf Yaqub ibn Is-haq ibn as Sabbah ibn ‘omran ibn Ismail Al-Kindi, was...
What is spear phishing attack or gift card scam and how to detect it?
What is spear phishing attack or gift card scam and how to detect it?
28/02/2021
Facebook pixel targeting retargeting
Make The Most Out Of Your Marketing Budget Using Facebook Targeting/Retargeting
07/07/2017
How To Create A TabHost Of A ListView In Android?
11/06/2017

Latest Posts

Never Quit Your Job For These 10 Reasons
15Aug,2022
The Arab Cryptanalysts and Al-Kindi’s Method
The Arab Cryptanalysts and Al-Kindi’s Methods
11Apr,2022
The Reactive, Proactive and Approachable Helpful Colleague – How Can You Become A Truly Helpful Team Member?
05Sep,2021

Tags

android (2) culture (1) entrepreneurship (1) house (1) marketing (1) Media & Press (2) tech house (1)

Like My Page

Social Accounts

Menu

  • Courses
  • Articles
  • Contact
  • Success Stories
  • About Me
  • Log in

GET IN TOUCH

sami@samieltamawy.com

Dubai, UAE.

 

Social Links

  • Facebook
  • Linkedin
  • Instagram
  • Youtube

Podcast

Listen to the Tech Entrepreneurship Simplified podcast

All rights reserved - Sami Eltamawy

  • Home
  • Courses
  • Articles
  • Contact
  • About Me
  • Log in