Search code examples
androidandroid-imageviewandroid-imageandroid-bitmap

How to subsample/resize an image like in whatsapp


When sending an image through whatsapp, you can see the image you are sending in an imageview scaled very very well

for example, i sent two images to my friend

  • size of first image : 1296 pixels X 2304 pixels

  • size of second image : 1920 pixels X 1080 pixels

this images are too big therefore whatsapp has to scale them before showing them to me in an imageview

  • size of first image after being scaled by whatapp 333 pixels X 339 pixels

  • size of second image after being scaled by whatsapp 333 pixels X 187 pixels

As you can see the width is the same only height differs. i have tried to figure out how whatapp scales this images, but my methods gives me an image with a different dimensions far from whatsapp's ones

Method 1

private void resizeImage(){

Uri selectedImage = imageReturnedIntent.getData();
                      d("image url is " + selectedImage);
                      InputStream imageStream = getContentResolver().openInputStream(selectedImage);
                       BitmapFactory.decodeStream(imageStream,null, options);
                      imageHeight = options.outHeight;
                      imageWidth = options.outWidth;

                      options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);
                      options.inJustDecodeBounds = false;
                      bitmap = BitmapFactory.decodeStream(imageStream,null, options);

}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth , int reqHeght){

    int height = options.outHeight;
    int width = options . outWidth;
    d("width is "+ width + " height is "+ height);
    d("required width is "+ reqWidth + " required height "+ reqHeght);
    int inSampleSize = 1;

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

        int heightRatio = Math.round((float)height/(float)reqHeght);
        d("height ratio is "+ heightRatio);

        int widthRatio = Math.round((float)width / (float) reqWidth);
        d("width ratio is "+widthRatio);

        inSampleSize = (heightRatio > widthRatio)? heightRatio :widthRatio;
    }
    d(" insample size is "+ inSampleSize);
    return inSampleSize;
}

Output for first image using the above method : Smaller(< 333) width, very big height(>339. it's 579!!)

Second method

private Bitmap scaleToFitWidth(Bitmap b, int width){
  float factor = width/b.getWidth(); // width is 333

  return Bitmap.createScaledBitmap(b, width,(int)(b.getHeight() * factor),true)
}

Output of first image in second method: image height is very very big!

Question Does anyone knows how to scale images very well like whatapp Across all devices?(i would like to be the same as whatsapp if possible)

EDIT: whatsapp Images

My huawel phone

 image is huawel

samsung tablet

image in samsung talet


Solution

  • You can checkout this code it works same as you wanted WhatsApp Like Image Compression. This code has been modified according to my usage. Using this code will provide you :

    • Low Size Images around 100kb without playing with image quality.
    • High pixel images will be scaled down to maxWidth and maxHeight without loosing its original quality.

    Original Article : Loading images Super-Fast like WhatsApp

    Demo :

    Original Image : Size - 3.84Mb Dimensions - 3120*4160

    Compressed Image : Size - 157Kb Dimensions - 960*1280

    Edit 1: You can also make a custom Square ImageView which extends ImageView Class. SquareImageView