Resize/Scale of an Image – Take 1 – Using an Objective-C Category

Editor’s Note: Part 2 of this post Resize/Scale of an Image – Take 2 – Thread Safe Approach takes this idea to the next level, showing how to dynamically resize images using thread safe code.

Given how common it is to scale an image within an application, it’s surprising (at least to me) that such a method is not included in the UIImage class. Let’s go ahead and take care of this omission by adding a simple method which will provide a means to scale an image.

We’ll use an Objective-C category to add a method to the UIImage class. I covered categories in this post. No question, categories are your friend, as they are very handy in cases such as this, where you would like to add functionality to an existing class.

Defining the UIImage Scale Category

To add a method to the UIImage class, there are two steps we need to take care in the interface defintion. First, create an interface definition for UIImage and add a category name inside a set of parenthesis after the interface declaration. Second, create the method declaration. An example follows:

//  UIImage+Scale.h
 
@interface UIImage (scale)
 
-(UIImage*)scaleToSize:(CGSize)size;
 
@end
Implementation UIImage Scale Category

With the interface in place, let’s write the code for the method that will be added to the UIImage class.

//  UIImage+Scale.h
 
#import "UIImage+Scale.h"
 
@implementation UIImage (scale)
 
-(UIImage*)scaleToSize:(CGSize)size
{
  // Create a bitmap graphics context
  // This will also set it as the current context
  UIGraphicsBeginImageContext(size);
 
  // Draw the scaled image in the current context
  [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
 
  // Create a new image from current context
  UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
 
  // Pop the current context from the stack
  UIGraphicsEndImageContext();
 
  // Return our new scaled image
  return scaledImage;
}
 
@end
Using the UIImage Scale Method

Calling the new scale method we added to UIImage is as simple as this:

#import "UIImage+Scale.h"
 
...
 
// Create an image
UIImage *image = [UIImage imageNamed:@"myImage.png"];
 
// Scale the image
UIImage *scaledImage = [image scaleToSize:CGSizeMake(25.0f, 35.0f)];

13 Comments

  1. That’s awesome, I was in the middle of building an iPhone application that required just that. Thanks so much for the tip!

  2. This is awesome! thanks. I did get a warning that uiimage might not responde to scaleToSize (everything worked despite the warning). I was able to get rid of the warning by importing the uiimage+scale.h file to the .m file where I was using the function.

  3. Just be aware that this code is not thread safe, since it depends on the global current context… If you would like code that is thread safe (and unfortunately a bit more complex ;) I could post that

    Coop

  4. This is works great but I have showing memory leaks in Instruments when I call this code. But maybe it is the way I call it:

    – (UIImage *) getImageForIndex:(NSIndexPath *)indexPath {

    NSInteger row = [indexPath row];
    NSInteger section = [indexPath section];

    CSLewisTriviaAppDelegate *appDelegate = (CSLewisTriviaAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSDictionary *itemAtIndex = (NSDictionary *)[[appDelegate dataController] objectInCategoryArrayAtIndex:section];
    NSString *categoryName = [itemAtIndex objectForKey:@”name”];
    Resources *tempResourcesObject = [[appDelegate dataController] returnResourcesObject];

    NSDictionary *bonusInfoLinksResourceDict = [tempResourcesObject getResourceImageAndTitle:categoryName row:row];

    NSDictionary *resourceDictionary = [self returnResourceDictionary:bonusInfoLinksResourceDict indexPath:indexPath];

    // nothing found
    if (resourceDictionary == nil) {
    return nil;
    }

    UIImage *image = [UIImage imageNamed:[resourceDictionary objectForKey:@”image”]];
    image = [image scaleToSize:CGSizeMake(80.0f, 100.0f)];

    return image;
    }

  5. Of course! I did go back and review memory management to see where my misunderstanding was. I ended up adding the retain and then an autorelease so that the caller doesn’t have to worry about releasing it:

    – (UIImage *) getImageForIndex:(NSIndexPath *)indexPath {

    image = [image scaleToSize:CGSizeMake(80.0f, 100.0f)];
    [image retain];
    return [image autorelease];
    }

    This clears up the problem in Instruments. Thanks!

  6. Really laconic and nice code. Thank you very much.

  7. Does this method will use the same amount of memory if I load a ‘thumbnail’ from the image that I want to resize?

  8. Thanks a lot! I was looking just for this and I’m still a nooby in CoreGraphics.

  9. Wow, that is really cool. Very clever and handy way to scale images! I adopt it :)

Comments are closed.