Skip to content

Instantly share code, notes, and snippets.

@akshay1188
Last active June 10, 2023 16:42
Show Gist options
  • Save akshay1188/4749253 to your computer and use it in GitHub Desktop.
Save akshay1188/4749253 to your computer and use it in GitHub Desktop.
Whatsapp like image compression
- (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];
}
@GSerjo
Copy link

GSerjo commented Mar 19, 2020

swift 5

    func resize() -> Data? {
        
        let maxHeight: CGFloat = 1136
        let maxWidth: CGFloat = 640
        
        var actualHeight = self.size.height
        var actualWidth = self.size.width

        var imgRatio = actualWidth / actualHeight
        let maxRatio = maxWidth / maxHeight
        var compressionQuality : CGFloat = 0.6
        
        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
                compressionQuality = 1
            }
        }
        
        let canvas = CGSize(width: actualWidth, height: actualHeight)
        let format = imageRendererFormat
        format.opaque = true
        let result = UIGraphicsImageRenderer(size: canvas, format: format).image {
            _ in draw(in: CGRect(origin: .zero, size: canvas))
        }
        return result.jpegData(compressionQuality: compressionQuality)
    }

@diegogarciar
Copy link

Hello,
One question, from where does maxHeight and maxWidth come from? was it also taken from WhatsApp?

@GSerjo
Copy link

GSerjo commented Oct 4, 2020

Hi Diego,

maybe, a bit difficult to check (the initial version has been created 5 years ago).. in the current WhatsApp version I see 768*1024. here how you can see maxHeight and maxWidth

  • open WhatsApp on a computer
  • download an image
  • check dimensions

@diegogarciar
Copy link

Thanks, so I did that and it currently is 1280x960. But I disagree with compressionQuality = 1 in the else statement as that's the scenario where the ratios are the same, but the original image is obviously bigger, not smaller, so I do want it compressed.

@knox
Copy link

knox commented Jan 24, 2021

Resizing with UIGraphicsImageRenderer is dead simple but consumes a lot of memory. So i suggest to use CGContext instead:

extension UIImage {
    func compressedData() -> Data? {
        let maxHeight: CGFloat = 1136
        let maxWidth: CGFloat = 640

        var actualHeight = size.height
        var actualWidth = size.width

        var imgRatio = actualWidth / actualHeight
        let maxRatio = maxWidth / maxHeight
        var compressionQuality : CGFloat = 0.6

        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
                compressionQuality = 1
            }
        }

        guard let cgImage = cgImage else { return nil }

        let mutableData = NSMutableData()
        guard let imageDestinationRef = CGImageDestinationCreateWithData(mutableData as CFMutableData, kUTTypeJPEG, 1, nil) else { return nil }
        let options: NSDictionary = [
            kCGImageDestinationLossyCompressionQuality: compressionQuality
        ]
        CGImageDestinationAddImage(imageDestinationRef, cgImage, options)
        guard CGImageDestinationFinalize(imageDestinationRef) else { return nil }

        return mutableData as Data
    }
}

@YogeshPateliOS
Copy link

@knox kUTTypeJPEG deprecated

@MounikaMadishetti
Copy link

@YogeshPateliOS We can use UTType. jpeg.identifier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment