Reduce the size of a bitmap to a specified size in Android
I found an answer that works perfectly for me:
/** * reduces the size of the image * @param image * @param maxSize * @return */public Bitmap getResizedBitmap(Bitmap image, int maxSize) { int width = image.getWidth(); int height = image.getHeight(); float bitmapRatio = (float)width / (float) height; if (bitmapRatio > 1) { width = maxSize; height = (int) (width / bitmapRatio); } else { height = maxSize; width = (int) (height * bitmapRatio); } return Bitmap.createScaledBitmap(image, width, height, true);}
calling the method:
Bitmap converetdImage = getResizedBitmap(photo, 500);
Where photo
is your bitmap
Here is the solution that limits image quality without changing width
and height
. The main idea of this approach is to compress bitmap inside the loop while output size is bigger than maxSizeBytesCount
. Credits to this question for the answer. This code block shows only the logic of reducing image quality:
ByteArrayOutputStream stream = new ByteArrayOutputStream(); int currSize; int currQuality = 100; do { bitmap.compress(Bitmap.CompressFormat.JPEG, currQuality, stream); currSize = stream.toByteArray().length; // limit quality by 5 percent every time currQuality -= 5; } while (currSize >= maxSizeBytes);
Here is the full method:
public class ImageUtils { public byte[] compressBitmap( String file, int width, int height, int maxSizeBytes ) { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bitmap; int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height); int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width); if (heightRatio > 1 || widthRatio > 1) { if (heightRatio > widthRatio) { bmpFactoryOptions.inSampleSize = heightRatio; } else { bmpFactoryOptions.inSampleSize = widthRatio; } } bmpFactoryOptions.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); ByteArrayOutputStream stream = new ByteArrayOutputStream(); int currSize; int currQuality = 100; do { bitmap.compress(Bitmap.CompressFormat.JPEG, currQuality, stream); currSize = stream.toByteArray().length; // limit quality by 5 percent every time currQuality -= 5; } while (currSize >= maxSizeBytes); return stream.toByteArray(); }}