I've implemented the below code to scale an image down, with respect to the aspect ratio (by proportionally decreasing height/width with respect to one another).. This will definitely help to reduce the size of the images uploaded to my backend, but this does not take into account the resolution of the images. I want to set a hard image limit, say 800Kb, and if the image is greater than 800Kb after resizing, then compress to a point at which it is less than 800Kb.
Anyone have any experience doing something like this? I'm curious what relationship lies between the quality argument passed into the Bitmap.Compress method and how much file size is shaven off per percentage quality - If i could obtain this information, I believe I can reach my goal.
Thanks for any help ahead of time, my current code is below, maybe it will help others heading in this direction in the future.
public static void uploadImage(String url, File file, Callback callback, Context context,
IMAGE_PURPOSE purpose) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
int maxWidth = 0;
int maxHeight = 0;
int maxSize = 0;
switch(purpose){
case PROFILE:
maxWidth = Constants.MAX_PROFILE_IMAGE_WIDTH;
maxHeight = Constants.MAX_PROFILE_IMAGE_HEIGHT;
maxSize = Constants.MAX_PROFILE_IMAGE_SIZE;
break;
case UPLOAD:
maxWidth = Constants.MAX_UPLOAD_IMAGE_WIDTH;
maxHeight = Constants.MAX_UPLOAD_IMAGE_HEIGHT;
maxSize = Constants.MAX_UPLOAD_IMAGE_SIZE;
break;
}
int newWidth = bitmap.getWidth();
int newHeight = bitmap.getHeight();
// Make sure the width is OK
if(bitmap.getWidth() > maxWidth){
// Find out how much the picture had to shrink to get to our max defined width
float shrinkCoeff = ((float)(bitmap.getWidth() - maxWidth) / (float)bitmap.getWidth());
newWidth = maxWidth;
// Shrink the height by the same amount to maintain aspect ratio
newHeight = bitmap.getHeight() - (int)((float)bitmap.getHeight() * shrinkCoeff);
}
// Make sure the height is OK
if(newHeight > maxHeight){
// Find out how much the picture had to shrink to get to our max defined width
float shrinkCoeff = ((newHeight - maxHeight) / newHeight);
newHeight = maxHeight;
// Shrink the width by the same amount to maintain aspect ratio
newWidth = newWidth - (int)((float)newWidth * shrinkCoeff);
}
Bitmap resized = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
// Get the image in bytes
ByteArrayOutputStream bos = new ByteArrayOutputStream();
resized.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte[] imageBytes = bos.toByteArray();
// If the size on disk is too big, reduce the quality
if(imageBytes.length > maxSize){
// Compress image here to get to maxSize
}