Resizing UIImage objects

If you need a quick way to resize your UIImage objects project-wide, the best way to do so is to add a new method to the UIImage class by defining a category. Categories are Objective-C’s mechanism for extending a class’ functionality without subclassing it.

So, let’s declare a new category named Resizing on UIImage, and place that category’s definition in a file named UIImage+Resizing.h:

We defined a new method, resizedImageWithSize:, which is now available to all of your UIImage objects – you only need to #import "UIImage+Resizing.h" in every source file where you need this functionality.

On to the implementation:

First, we create a new image context by using UIKit’s UIGraphicsBeginImageContext(CGSize size) function. It creates a new image context with the given size, and sets it as the active context.

Now comes the magical part – [self drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)] draws the receiver (in this case, self) into the currently active context, using the given size. In this case, we want the entire context filled with our original image, so we draw from (0,0) to (size.width,size.height). UIKit does all the hard work of actually resizing the image. Nice!

Next, we need to get an actual UIImage object from our context, so we call UIKit’s UIGraphicsGetImageFromCurrentImageContext() function, which returns an autoreleased UIImage object. Now all we need to do is to end the image context (to prevent memory leaks) by calling UIGraphicsEndImageContext, and return the resulting UIImage object back to the caller.

The actual usage of this code is dead simple:

// Remember to #import "UIImage+Resizing.h"
UIImage* photo = // ... get a photo from somewhere
UIImage* thumbnail = [photo resizedImageWithSize:CGSizeMake(80,60)];

That’s it!

I actually came up with this code after quite a bit of messing around with resizing using Core Graphics, which is a more low-level approach than using UIKit. The memory usage was way too high, since Core graphics relies on the underlying CGImageRef object for drawing, and UIKit seems to do much of it’s job on the GPU, thus minimizing system memory usage.

One more advantage to using UIKit instead of Core Graphics for resizing is when you need to draw a resized image to a PDF context. The UIImage class remembers the source of your image object, so if you draw an object that was loaded from a JPEG file, the image gets embedded into the PDF as a JPEG image. If you resize using Core Graphics, you typically get a CGImageRef object, which you then use to create a new UIImage object, thus losing the information about the source of the image. The image that gets drawn into the PDF context is not compressed, so your PDF file will be bigger.

One response to “Resizing UIImage objects”

  1. Anthony

    Great suggestion! I have been looking for a solution for long time< tried many different approaches. This seems to be working in every iOS fro 4.1 to 5.1 very well
    Thank you!

Leave a Reply