Getting right UIImage and CGImage pixel size according to device display (retina or not)

I just fixed an issue related to the wrong display of an UIImageView in my (never ending WIP) app. The problem is that starting with iOS 4 and with the introduction of retina display in iPhone 4, the attribute “size” does not return the real pixel dimensions but points. So on a retina display device an image of 100×100 pixel will return a size of 200×200 (values are doubled). Theoretically there is an helpful attribute “scale” that should return a float value representing the adopted scale (2.0f for retina display, 1.0f for other).
Unfortunately, in my case it returns always 1, both for the iOS simulator than the real device (iPhone 4 with iOS 5), and my images are rendered incorrectly.
After digging on Google (which as usual points me to my beloved Stackoverflow), I gathered several helpful informations that helped me solving the problem and inspired a few helpful precompiler macros :)
The scale value, which is essential to implement retina display-aware software can be retrieved using:

[[UIScreen mainScreen] scale];

So, I realized the following macros:

// return true if the device has a retina display, false otherwise
#define IS_RETINA_DISPLAY() [[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0f

// return the scale value based on device's display (2 retina, 1 other)
#define DISPLAY_SCALE IS_RETINA_DISPLAY() ? 2.0f : 1.0f

// if the device has a retina display return the real scaled pixel size, otherwise the same size will be returned
#define PIXEL_SIZE(size) IS_RETINA_DISPLAY() ? CGSizeMake(size.width/2.0f, size.height/2.0f) : size

Then I used a little trick, to initialize an UIImage with the correct dimensions. Fundamentally I initialize an “helper image” first from which extract a CGImage in order to allocate a new UIImage using the initializer initWithCGImage:scale:orientation: (as scale I use the previous defined macro DISPLAY_SCALE).

UIImage *helperImage = [[UIImage alloc] initWithData:data];
UIImage *pic = [[UIImage alloc] initWithCGImage:helperImage.CGImage scale:DISPLAY_SCALE orientation:UIImageOrientationUp];
  • Bogdan

    Great post. Had same problem (now I don’t thanks to you ;) ), when using CGImageCreateWithImageInRect. BUT, for me the scale property of the UIImage works fine.

  • Bro is it about to get pixel data of any image, like click on specific point and get it pixel values like in format of rgb or hsv etc if i am right please send me some demo where you have implemented this, it will be a great help…