/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package my.home.common;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.widget.ImageView;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created by legendmohe on 15/9/20.
 */
public class ImageUtil {

    public static Bitmap scaleAndRotateImageFile(Bitmap bitmap, String path, int maxW, int maxH, ImageView.ScaleType scaleType) {
        bitmap = rotateBitmap(bitmap, path);
        if (bitmap == null)
            return null;

        int actualWidth = bitmap.getWidth();
        int actualHeight = bitmap.getHeight();
        // Then compute the dimensions we would ideally like to decode to.
        int desiredWidth = getResizedDimension(maxW, maxH,
                actualWidth, actualHeight, scaleType);
        int desiredHeight = getResizedDimension(maxH, maxW,
                actualHeight, actualWidth, scaleType);

        bitmap = Bitmap.createScaledBitmap(bitmap, desiredWidth, desiredHeight, true);
        return bitmap;
    }

    public static Bitmap scaleImageFile(Context context, Uri uri, int maxW, int maxH, ImageView.ScaleType scaleType) throws FileNotFoundException {
        BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
        decodeOptions.inJustDecodeBounds = true;

        InputStream imageStream = null;
        imageStream = context.getContentResolver().openInputStream(uri);
        BitmapFactory.decodeStream(imageStream, null, decodeOptions);

        int actualWidth;
        int actualHeight;
        actualWidth = decodeOptions.outWidth;
        actualHeight = decodeOptions.outHeight;

        // Then compute the dimensions we would ideally like to decode to.
        int desiredWidth = getResizedDimension(maxW, maxH,
                actualWidth, actualHeight, scaleType);
        int desiredHeight = getResizedDimension(maxH, maxW,
                actualHeight, actualWidth, scaleType);

        // Decode to the nearest power of two scaling factor.
        decodeOptions.inJustDecodeBounds = false;
        decodeOptions.inSampleSize =
                findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
        imageStream = context.getContentResolver().openInputStream(uri);
        Bitmap tempBitmap = BitmapFactory.decodeStream(imageStream, null, decodeOptions);

        // If necessary, scale down to the maximal acceptable size.
        Bitmap bitmap;
        if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth ||
                tempBitmap.getHeight() > desiredHeight)) {
            bitmap = Bitmap.createScaledBitmap(tempBitmap,
                    desiredWidth, desiredHeight, true);
            tempBitmap.recycle();
        } else {
            bitmap = tempBitmap;
        }

        return bitmap;
    }

    public static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary,
                                          int actualSecondary, ImageView.ScaleType scaleType) {
        // If no dominant value at all, just return the actual.
        if ((maxPrimary == 0) && (maxSecondary == 0)) {
            return actualPrimary;
        }

        // If ScaleType.FIT_XY fill the whole rectangle, ignore ratio.
        if (scaleType == ImageView.ScaleType.FIT_XY) {
            if (maxPrimary == 0) {
                return actualPrimary;
            }
            return maxPrimary;
        }

        // If primary is unspecified, scale primary to match secondary's scaling ratio.
        if (maxPrimary == 0) {
            double ratio = (double) maxSecondary / (double) actualSecondary;
            return (int) (actualPrimary * ratio);
        }

        if (maxSecondary == 0) {
            return maxPrimary;
        }

        double ratio = (double) actualSecondary / (double) actualPrimary;
        int resized = maxPrimary;

        // If ScaleType.CENTER_CROP fill the whole rectangle, preserve aspect ratio.
        if (scaleType == ImageView.ScaleType.CENTER_CROP) {
            if ((resized * ratio) < maxSecondary) {
                resized = (int) (maxSecondary / ratio);
            }
            return resized;
        }

        if ((resized * ratio) > maxSecondary) {
            resized = (int) (maxSecondary / ratio);
        }
        return resized;
    }

    public static int findBestSampleSize(
            int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) {
        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio) {
            n *= 2;
        }
        return (int) n;
    }

    public static Bitmap rotateBitmap(Bitmap bitmap, String photoFilePath) {
        // Read EXIF Data
        ExifInterface exif;
        try {
            exif = new ExifInterface(photoFilePath);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        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;
        // Rotate Bitmap
        Matrix matrix = new Matrix();
        matrix.setRotate(rotationAngle, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return rotatedBitmap;
    }
}

@@ -1123,17 +1123,23 @@
 itmap = 
-r
+createR
 otateBit
@@ -1608,33 +1608,46 @@
 Type);%0A%0A        
-b
+Bitmap resultB
 itmap = Bitmap.c
@@ -1712,32 +1712,64 @@
 e);%0A        
-return b
+bitmap.recycle();%0A        return resultB
 itmap;%0A    %7D
@@ -5473,25 +5473,31 @@
 atic Bitmap 
-r
+createR
 otateBitmap(

Update ImageUtil.java