user25093
user25093

Reputation: 287

Optimizing CoreGraphics function/ alternative

I was profiling my app when I noticed a large chunk of time being spent on this function:

    //http://samwize.com/2016/06/01/resize-uiimage-in-swift/
    /// Returns a image that fills in newSize
    func resizedImage(newSize: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0);
        let rect: CGRect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: newSize.width, height: newSize.height))
        self.draw(in: rect)
        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }

enter image description here

What is a good alternative to this function that will resize an image in significantly less time? Or, how should I go about optimizing a function like this that uses CoreGraphics?

Thanks!

Upvotes: 0

Views: 42

Answers (1)

Rob Napier
Rob Napier

Reputation: 299545

This is likely about as fast as you can resize this image. Resizing a large image requires math. Don't imagine there's some magic "make it fast" button. If there were a faster approach with no trade-offs, then that would be the default. That said, there are things you can explore.

Your first step is to decide whether you can avoid resizing entirely. Could you just hand this to a UIImageView and let it take care of things? (Of course UIImageView would also need to resize the image, but it tends to be pretty smart about these things.)

Your next step is to decide whether you can call this resize method less frequently. Are you calling this method repeatedly for the same image?

You should then reconsider your choice for opaque. You selected false, but if you can set this to true, you will improve render performance at the cost of ignoring the alpha channel.

You then should consider whether you can reduce the quality of your resizing. If you can accept a lower quality image, then consider setting UIGraphicsGetCurrentContext.interpolationQuality = .low. Note that this your method has already set the scale to 1, which is non-Retina so already pretty low quality.

Finally, you should consider moving this work to a background queue and dealing with resizing as an asynchronous process. This is much more complex, and requires providing some place-holder image while you resize.

Upvotes: 2

Related Questions