Daily Archives: November 29, 2010

Drawing Part of a UIImage

Happy Thanksgiving, and sorry for the relative lack of posts here lately. Things are crazier than ever and it’s been a challenge finding time to shower, let alone blog.

I do have something to share, today, though. No, it’s not the next chapter of OpenGL ES 2.0 for iOS. It’s a category that some of you may find useful: a method that allows you to draw only part of a UIImage rather than the entire thing.

On the Mac, NSImage has a handy instance method called drawInRect:fromRect:operation:fraction: that lets you specify exactly which part of an image to draw. On UIImage, we’ve only got the ability to draw the entire image either unless we drop down to Core Graphics calls. We don’t have a nice, easy, convenient way using just UIImage to draw a portion of the image it represents.

I needed this ability in an application I’m working on, so I hacked out the following category. At first glance, this may look to be inefficient, since we’re making a copy of the instance’s backing CGImage in order to create the sub-image, however I believe that CGImageCreateWithImageInRect() references the original image’s bitmap data. I haven’t confirmed that it doesn’t make a copy of the bitmap data, but the documentation certainly seems to imply it. Anyone know?

Anyway, here is the category; I’ve even commented the code more pedantically than is normal for me in case anyone might be confused about what’s going on. Improvements and bug fixes are, as always, welcome.

@implementation UIImage(MCDrawSubImage)
- (void)drawInRect:(CGRect)drawRect fromRect:(CGRect)fromRect blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha
{
CGImageRef drawImage = CGImageCreateWithImageInRect(self.CGImage, fromRect);
if (drawImage != NULL)
{
CGContextRef context = UIGraphicsGetCurrentContext();

// Push current graphics state so we can restore later
CGContextSaveGState(context);

// Set the alpha and blend based on passed in settings
CGContextSetBlendMode(context, blendMode);
CGContextSetAlpha(context, alpha);

// Take care of Y-axis inversion problem by translating the context on the y axis
CGContextTranslateCTM(context, 0, drawRect.origin.y + fromRect.size.height);

// Scaling -1.0 on y-axis to flip
CGContextScaleCTM(context, 1.0, -1.0);

// Then accommodate the translate by adjusting the draw rect
drawRect.origin.y = 0.0f;

// Draw the image
CGContextDrawImage(context, drawRect, drawImage);

// Clean up memory and restore previous state
CGImageRelease(drawImage);

// Restore previous graphics state to what it was before we tweaked it
CGContextRestoreGState(context);
}

}

@end

©2008-2010 Jeff LaMarche.
iphonedevelopment.blogspot.com

How to Take Better Vacation Photos [Photography]

It can be very tempting to snap a photo of everything that happens on your vacation, but you might be better served by thinking of your trip as a story and carefully selecting the most interesting moments to capture. More »







Change Two Settings to Speed Up Photoshop [Photoshop Tip]

Just because a setting is tucked away doesn’t mean it can’t make a big difference. Many Photoshop veterans, for instance, are discovering that cutting out Cache Levels and Image Previews can make the photo editing beast a bit more agile. More »







Switch is a Smart Multi-User Browser for iPads [Downloads]

iPad only: The iPad is a device destined to be handed over to friends and passed among family members, but there are no user accounts or variable browser settings. Enter Switch, a clever browser that allows user accounts and anonymous guest browsing. More »







WP Like Button Plugin by Free WordPress Templates