views:

385

answers:

1

I have a custom view which is composed of a number of UIImageViews. These UIImageViews can vary in size (from 200x200 down to 50x50). The images that they display (loaded from png files) are stored in resources at the highest possible resolution (200x200), but frequently are displayed at lower resolutions.

Currently I just load the UIImageViews with the images at full resolution, thus:

UIImage* anImage = [UIImage imageWithContentsOfFile:imagePathAndName]; // anImage is 200x200
aView = [[UIImageView alloc] initWithImage:anImage];
aView.frame = myFrame; // myFrame is 50x50

First question, is there any performance penalty (memory or CPU time) to just letting UIImageView scale down the images from say 200x200 to 50x50? It doesn't appear that my app is using a ton of memory or slowing down as a result of this, but if I could speed it up or reduce memory consumption, that would be a win.

I played around with scaling the images programmatically. Like this:

UIImage* anImage = [UIImage imageWithContentsOfFile:imagePathAndName]; // Image is UIGraphicsBeginImageContext( scaledSize ); // scaledSize is 50x50
CGRect scaledRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[anImage drawInRect:scaledRect];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); // Scaled image is now 50x50
UIGraphicsEndImageContext();
aView = [[UIImageView alloc] initWithImage:scaledImage];
aView.frame = myFrame; // myFrame is 50x50

Programmatically scaling the images first seemed to have no ill affect... until I loaded it on my iPhone 4. See, the size of the UIImageView is based on the size if it's parent view, which (layed out in IB), is the size of an iPhone 3G screen. Sadly, the size of this view when running on an iPhone 4 is the same, despite the fact that the iPhone 4 has twice the resolution as a 3G. So by scaling the images based on the size of the view, I end up making them lower resolution than they should be on an iPhone 4, and they look kinda crappy.

So the second question is, if there is some benefit to programmatically scaling the images down. how can I take advantage of the extra pixels on an iPhone 4? Clearly I can't go by the size of my view.

+1  A: 

Avoid premature optimization.

If your app runs well, it runs well. If it doesn't, try to optimize it.

From my experience using a 200px image where a 50px image would do is just fine. The image could easily be loaded to the graphics hardware and scaling is most likely done in hardware.

I would only prescale images if performance profiling tells me to.

For the second part of your question, the actual scaling code, you have to note, that CoreGraphics knows nothing about retina displays. So in a CGBitmapContext a point is a pixel, unless you tell it otherwise. In you code snippet you left out the line, which creates the bitmap context, but it's most likely UIGraphicsBeginImageContext(CGSize size). Take a look at and use UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale); instead. Passing 0.0 as scale should normally do.

UIKit Functions: UIGraphicsBeginImageContextWithOptions

tonklon
UIGraphicsBeginImageContextWithOptions did the trick perfectly, thanks! And your point on premature optimization is well taken, I will have to give it some thought.
zpasternack