Improving Image Compression – What We’ve Learned from Whatsapp

Improving Image Compression – What We’ve Learned from Whatsapp

Anyone who has used Whatsapp has observed how quickly images can be shared even if they are large files.

By large files, I mean high resolution images often ranging from 1-4 MB. For example, the iPhone 4S, with an 8MP camera takes fairly large photos: 3264×2448 pixels (8MP means 8 million pixels). But when you share these images through Whatsapp, it compresses the images which allows for incredibly fast sharing.

I was playing around with a wide variety of image sizes to learn how Whatsapp compresses them.

For example, an image with dimensions 3264×2448 (3 MB) is converted to an image with dimensions 800×600 (~70KB).

When compressing images, the aspect ratio is maintained. i.e the resulting compressed image has same aspect ratio as the original image. In the above case, an aspect ratio of 4:3.

I tried images with different dimensions: 3264×2448, 1280×720, 1280×1024, 1024×768, 480×360, and 400×300.

One thing that I noticed was the images with dimensions greater than 800×600 were scaled down to a maximum resolution of 800×600 (smaller images weren’t scaled).

This chart outlines the results:

Original Resolution (size)Compressed Resolution (size)
1280×720 (421 KB)800×450 (45 KB)
1280×1024 (153 KB)800×640 (84 KB)
1024×768 (137 KB)800×600 (64 KB)
3264×2448 (3 MB)800×600 (69 KB)
800×600 (226 KB)800×600 (68 KB)
480×360 (30 KB)480×360 (21 KB)
400×300 (24 KB)400×300 (22 KB)

It is clear from the last three entries that in addition to being scaled down, images are compressed by Whatsapp when they’re saved to JPG.

After playing around a bit with UIImageJPEGRepresentation ( UIImage *image, CGFloat compressionQuality), I found that the compressionQuality was 50% or a factor 0.5.

With some assistance from stackoverflow, I was able to construct a function in Objective-C that compresses the images exactly like Whatsapp does. I even compared the results with Whatsapp compressed images and they were identical.

Here’s the function I created:

(UIImage *)compressImage:(UIImage *)image{
    float actualHeight = image.size.height;
    float actualWidth = image.size.width;
    float maxHeight = 600.0;
    float maxWidth = 800.0;
    float imgRatio = actualWidth/actualHeight;
    float maxRatio = maxWidth/maxHeight;
    float compressionQuality = 0.5;//50 percent compression

    if (actualHeight > maxHeight || actualWidth > maxWidth){
        if(imgRatio < maxRatio){
            //adjust width according to maxHeight
            imgRatio = maxHeight / actualHeight;
            actualWidth = imgRatio * actualWidth;
            actualHeight = maxHeight;
        }
        else if(imgRatio > maxRatio){
            //adjust height according to maxWidth
            imgRatio = maxWidth / actualWidth;
            actualHeight = imgRatio * actualHeight;
            actualWidth = maxWidth;
        }
        else{
            actualHeight = maxHeight;
            actualWidth = maxWidth;
        }
    }

    CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
    UIGraphicsBeginImageContext(rect.size);
    [image drawInRect:rect];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    NSData *imageData = UIImageJPEGRepresentation(img, compressionQuality);
    UIGraphicsEndImageContext();

    return [UIImage imageWithData:imageData];
}

You can find the above code on GitHub.

  1. Richi on May 29, 2013 at 7:28 am said:

    good analysis !! :) thx !

  2. your effort answer to a question i had. so this is why pix shared by whatsapp are just shit when you view them as shared media on ipad…
    they could make a function that let choose the receiver how the pic must look, like original or resized..
    if in good resolution like 3Mg pixel just hold them for 24h before to delete them.

  3. Dude, i fucking love you! Your code just solved a problem i had in my app, to send a pic to the server.

  4. can you tel what is the advantage of maintaining the same aspect ratio while compressing??

    • Seriously?? Isn’t that obvious?? If aspect ratio is not kept same the whole pic would look either compressed from sides or elongated..

  5. Pierluca on March 6, 2014 at 3:15 am said:

    Hi man!! Nice work!! But just a question, do you know where can a try to find something to modify the whatsapp compression on iOS app. Thanks a lot

  6. Matthew on April 1, 2014 at 10:41 am said:

    Thank you so much for this one! Saved me a lot of time reproducing WhatsApp compressing method!

  7. stefano on April 26, 2014 at 11:16 am said:

    I heard that telegram sends images without scaling them.

  8. btkh95 on June 12, 2014 at 8:26 am said:

    So that means I can get into whatsapp scripting to alter the compression to have no compression at all? If so, pls tell me how to find the pathway thanks

  9. prathamesh on October 7, 2014 at 4:23 am said:

    How to get selected image from gallery in android app??
    Please reply..

  10. Demo Please

  11. What namespace can be used?

  12. peter on May 14, 2015 at 9:53 pm said:

    This code is awesome thank you: below is the code in swift:

    @IBAction func signUp(sender: AnyObject) {

    let imageData = UIImagePNGRepresentation(self.profilePic.image)

    let image = UIImage(data: imageData)

    func compressImage(image:UIImage) -> NSData {
    // Reducing file size to a 10th

    var actualHeight : CGFloat = image.size.height
    var actualWidth : CGFloat = image.size.width
    var maxHeight : CGFloat = 1136.0
    var maxWidth : CGFloat = 640.0
    var imgRatio : CGFloat = actualWidth/actualHeight
    var maxRatio : CGFloat = maxWidth/maxHeight
    var compressionQuality : CGFloat = 0.5

    if (actualHeight > maxHeight || actualWidth > maxWidth){
    if(imgRatio maxRatio){
    //adjust height according to maxWidth
    imgRatio = maxWidth / actualWidth;
    actualHeight = imgRatio * actualHeight;
    actualWidth = maxWidth;
    }
    else{
    actualHeight = maxHeight;
    actualWidth = maxWidth;
    compressionQuality = 1;
    }
    }

    var rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
    UIGraphicsBeginImageContext(rect.size);
    image.drawInRect(rect)
    var img = UIGraphicsGetImageFromCurrentImageContext();
    let imageData = UIImageJPEGRepresentation(img, compressionQuality);
    UIGraphicsEndImageContext();

    return imageData;
    }

    let compressedImage = compressImage(image!)

    let picture = PFFile(name: “image.png”, data: compressedImage)

    PFUser.currentUser()!.setObject(picture, forKey: “profilePic”)
    PFUser.currentUser()!.saveInBackgroundWithBlock {
    (success: Bool, error: NSError?) -> Void in
    if (success) {
    println(“image has been saved”)
    } else {
    println(“image failed”)
    }
    }
    }

  13. Hank 72 on June 1, 2015 at 2:49 pm said:

    Does Whatsapp compress all video files as well?

  14. rendl42 on June 2, 2015 at 9:48 am said:

    Any idea if this is still true after the introduction of retina and other HD devices?

  15. Compress.Photo on July 28, 2015 at 11:33 pm said:

    There are many online tools like compress.photos where you can compress the images without loosing the quality of image.

  16. Pingback: How to compress - Resize image on iOS - BlogoSfera

  17. carmelito on August 16, 2015 at 6:23 pm said:

    Great tutorial! Solved my problem with my app! Continue Helping!
    I converted it to swift:

    func compressImage(image: UIImage) -> UIImage {
    var actualHeight : CGFloat = image.size.height
    var actualWidth : CGFloat = image.size.width
    var maxHeight : CGFloat = 600.0
    var maxWidth : CGFloat = 800.0
    var imgRatio : CGFloat = actualWidth/actualHeight
    var maxRatio : CGFloat = maxWidth/maxHeight
    var compressionQuality : CGFloat = 0.5 //50 percent compression

    if ((actualHeight > maxHeight) || (actualWidth > maxWidth)){
    if(imgRatio maxRatio){
    //adjust height according to maxWidth
    imgRatio = maxWidth / actualWidth;
    actualHeight = imgRatio * actualHeight;
    actualWidth = maxWidth;
    }
    else{
    actualHeight = maxHeight;
    actualWidth = maxWidth;
    }
    }

    var rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight)
    UIGraphicsBeginImageContext(rect.size)
    image.drawInRect(rect)
    var img : UIImage = UIGraphicsGetImageFromCurrentImageContext()
    var imageData = UIImageJPEGRepresentation(img, compressionQuality)
    UIGraphicsEndImageContext()

    return UIImage(data: imageData)!
    }

  18. natahorchata on August 20, 2015 at 9:47 am said:

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值