package com.sxjs.common.util.imagecompress; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.media.ExifInterface; import android.net.Uri; import android.text.TextUtils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; /** * Created on : June 18, 2016 */ class ImageUtil { private ImageUtil() { } static Bitmap getScaledBitmap(Context context, Uri imageUri, float maxWidth, float maxHeight, Bitmap.Config bitmapConfig) { String filePath = FileUtil.getRealPathFromURI(context, imageUri); Bitmap scaledBitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); //by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If //you try the use the bitmap here, you will get null. options.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(filePath, options); if (bmp == null) { InputStream inputStream = null; try { inputStream = new FileInputStream(filePath); BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); } catch (FileNotFoundException exception) { exception.printStackTrace(); } catch (IOException exception) { exception.printStackTrace(); } } int actualHeight = options.outHeight; int actualWidth = options.outWidth; if (actualWidth < 0 || actualHeight < 0) { Bitmap bitmap2 = BitmapFactory.decodeFile(filePath); actualWidth = bitmap2.getWidth(); actualHeight = bitmap2.getHeight(); } float imgRatio = (float) actualWidth / actualHeight; float maxRatio = maxWidth / maxHeight; //width and height values are set maintaining the aspect ratio of the image if (actualHeight > maxHeight || actualWidth > maxWidth) { if (imgRatio < maxRatio) { imgRatio = maxHeight / actualHeight; actualWidth = (int) (imgRatio * actualWidth); actualHeight = (int) maxHeight; } else if (imgRatio > maxRatio) { imgRatio = maxWidth / actualWidth; actualHeight = (int) (imgRatio * actualHeight); actualWidth = (int) maxWidth; } else { actualHeight = (int) maxHeight; actualWidth = (int) maxWidth; } } //setting inSampleSize value allows to load a scaled down version of the original image options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); //inJustDecodeBounds set to false to load the actual bitmap options.inJustDecodeBounds = false; //this options allow android to claim the bitmap memory if it runs low on memory options.inPurgeable = true; options.inInputShareable = true; options.inTempStorage = new byte[16 * 1024]; try { //load the bitmap from its path bmp = BitmapFactory.decodeFile(filePath, options); if (bmp == null) { InputStream inputStream = null; try { inputStream = new FileInputStream(filePath); BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); } catch (FileNotFoundException exception) { exception.printStackTrace(); } catch (IOException exception) { exception.printStackTrace(); } } } catch (OutOfMemoryError exception) { exception.printStackTrace(); } try { scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, bitmapConfig); } catch (OutOfMemoryError exception) { exception.printStackTrace(); } float ratioX = actualWidth / (float) options.outWidth; float ratioY = actualHeight / (float) options.outHeight; Matrix scaleMatrix = new Matrix(); scaleMatrix.setScale(ratioX, ratioY, 0, 0); Canvas canvas = new Canvas(scaledBitmap); canvas.setMatrix(scaleMatrix); canvas.drawBitmap(bmp, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG)); //check the rotation of the image and display it properly ExifInterface exif; try { exif = new ExifInterface(filePath); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); Matrix matrix = new Matrix(); if (orientation == 6) { matrix.postRotate(90); } else if (orientation == 3) { matrix.postRotate(180); } else if (orientation == 8) { matrix.postRotate(270); } scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); } catch (IOException e) { e.printStackTrace(); } return scaledBitmap; } static File compressImage(Context context, Uri imageUri, float maxWidth, float maxHeight, Bitmap.CompressFormat compressFormat, Bitmap.Config bitmapConfig, int quality, String parentPath, String prefix, String fileName) { FileOutputStream out = null; String filename = generateFilePath(context, parentPath, imageUri, compressFormat.name().toLowerCase(), prefix, fileName); try { out = new FileOutputStream(filename); //write the compressed bitmap at the destination specified by filename. ImageUtil.getScaledBitmap(context, imageUri, maxWidth, maxHeight, bitmapConfig).compress(compressFormat, quality, out); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (IOException ignored) { } } return new File(filename); } private static String generateFilePath(Context context, String parentPath, Uri uri, String extension, String prefix, String fileName) { File file = new File(parentPath); if (!file.exists()) { file.mkdirs(); } /** if prefix is null, set prefix "" */ prefix = TextUtils.isEmpty(prefix) ? "" : prefix; /** reset fileName by prefix and custom file name */ fileName = TextUtils.isEmpty(fileName) ? prefix + FileUtil.splitFileName(FileUtil.getFileName(context, uri))[0] : fileName; return file.getAbsolutePath() + File.separator + fileName + "." + extension; } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } final float totalPixels = width * height; final float totalReqPixelsCap = reqWidth * reqHeight * 2; while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { inSampleSize++; } return inSampleSize; } }