Search code examples
iosswiftxcodememory-leaksuiimage

Memory leak when resizing UIImage


I've read through multiple threads concerning the topic but my problem still persists. When I'm resizing an Image with following code:

extension UIImage {
  func thumbnailWithMaxSize(image:UIImage, maxSize: CGFloat) -> UIImage {
    let width = image.size.width
    let height = image.size.height
    var sizeX: CGFloat = 0
    var sizeY: CGFloat = 0
    if width > height {
        sizeX = maxSize
        sizeY = maxSize * height/width
    }
    else {
        sizeY = maxSize
        sizeX = maxSize * width/height
    }

    UIGraphicsBeginImageContext(CGSize(width: sizeX, height: sizeY))
    let rect = CGRect(x: 0.0, y: 0.0, width: sizeX, height: sizeY)
    UIGraphicsBeginImageContext(rect.size)
    draw(in: rect)
    let thumbnail = UIGraphicsGetImageFromCurrentImageContext()!;

    UIGraphicsEndImageContext()

    return thumbnail

}


override func viewDidLoad() {
    super.viewDidLoad()

    let lionImage = UIImage(named: "lion.jpg")!

    var thumb = UIImage()

    autoreleasepool {
        thumb = lionImage.thumbnailWithMaxSize(image: lionImage, maxSize: 2000)
    }
    myImageView.image = thumb
}

...the memory is not released. So when I navigate through multiple ViewControllers (e.g. with a PageViewController) I end up getting memory warnings and the app eventually crashes. I also tried to load the image via UIImage(contentsOfFile: path) without success. Any suggestions?


Solution

  • I noticed your code beginning two contexts but only ending one.

    Here's my extension, which is basically the same as your's. Since I'm not having memory issues, it looks like that may be the issue.

    extension UIImage {
        public func resizeToRect(_ size : CGSize) -> UIImage {
            UIGraphicsBeginImageContext(size)
            self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext();
            return resizedImage!
        }
    }