How do I resize the UIImage to reduce upload image size How do I resize the UIImage to reduce upload image size swift swift

How do I resize the UIImage to reduce upload image size


Xcode 9 • Swift 4 or later

edit/update: For iOS10+ We can use UIGraphicsImageRenderer. For older Swift syntax check edit history.

extension UIImage {    func resized(withPercentage percentage: CGFloat, isOpaque: Bool = true) -> UIImage? {        let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)        let format = imageRendererFormat        format.opaque = isOpaque        return UIGraphicsImageRenderer(size: canvas, format: format).image {            _ in draw(in: CGRect(origin: .zero, size: canvas))        }    }    func resized(toWidth width: CGFloat, isOpaque: Bool = true) -> UIImage? {        let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))        let format = imageRendererFormat        format.opaque = isOpaque        return UIGraphicsImageRenderer(size: canvas, format: format).image {            _ in draw(in: CGRect(origin: .zero, size: canvas))        }    }}

Usage:

let image = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!let thumb1 = image.resized(withPercentage: 0.1)let thumb2 = image.resized(toWidth: 72.0)


This is the way which i followed to resize image.

 -(UIImage *)resizeImage:(UIImage *)image{   float actualHeight = image.size.height;   float actualWidth = image.size.width;   float maxHeight = 300.0;   float maxWidth = 400.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];}

Using this method my image having 6.5 MB reduced to 104 KB.

Swift 4 code:

func resize(_ image: UIImage) -> UIImage {    var actualHeight = Float(image.size.height)    var actualWidth = Float(image.size.width)    let maxHeight: Float = 300.0    let maxWidth: Float = 400.0    var imgRatio: Float = actualWidth / actualHeight    let maxRatio: Float = maxWidth / maxHeight    let compressionQuality: Float = 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        }    }    let rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight))    UIGraphicsBeginImageContext(rect.size)    image.draw(in: rect)    let img = UIGraphicsGetImageFromCurrentImageContext()    let imageData = img?.jpegData(compressionQuality: CGFloat(compressionQuality))     UIGraphicsEndImageContext()    return UIImage(data: imageData!) ?? UIImage()}


In case someone is looking for resizing image to less than 1MB with Swift 3 and 4.

Just copy&paste this extension:

extension UIImage {func resized(withPercentage percentage: CGFloat) -> UIImage? {    let canvasSize = CGSize(width: size.width * percentage, height: size.height * percentage)    UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)    defer { UIGraphicsEndImageContext() }    draw(in: CGRect(origin: .zero, size: canvasSize))    return UIGraphicsGetImageFromCurrentImageContext()}func resizedTo1MB() -> UIImage? {    guard let imageData = UIImagePNGRepresentation(self) else { return nil }    var resizingImage = self    var imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB    while imageSizeKB > 1000 { // ! Or use 1024 if you need KB but not kB        guard let resizedImage = resizingImage.resized(withPercentage: 0.9),            let imageData = UIImagePNGRepresentation(resizedImage)            else { return nil }        resizingImage = resizedImage        imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB    }    return resizingImage}}

And use:

let resizedImage = originalImage.resizedTo1MB()

Edit:Please note it's blocking UI, so move to background thread if you think it's the right way for your case.