50

I need to initialise images from raw data downloaded from a server which delivers the correct size of image based on the type of iPhone client.

I know that I should be setting the scale value to be 2.0 on the 640x960 display, however this is a readonly property and cannot be set during the init when using initWithData.

Any ideas?

Sam
  • 3,659
  • 3
  • 36
  • 49
  • 3
    May I suggest changing the question title to "How to change UIImage's scale property" to make it easier to find? – Rivera Oct 01 '14 at 05:48
  • 1
    Wow, I asked this question over 4 years ago. I think I'll leave it, thanks. – Sam Oct 01 '14 at 10:40

6 Answers6

94

I'm not aware of anything you can embed in the image data itself to tell the phone that it's a @2x image, but something like this should work:

UIImage * img = ...;
img = [UIImage imageWithCGImage:img.CGImage scale:2 orientation:img.imageOrientation];
tc.
  • 33,468
  • 5
  • 78
  • 96
  • This fixed it for me too, thanks! I was drawing text on an image and needed this to keep the scale correct on the resulting image. – Jason Sep 28 '10 at 02:44
  • Perfekt for me too... But why do we have to implement such low level stuff if we store an image with UIImagePNGrepresentation and want it back correctly?? That's not Apple-like. CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFDataRef)); CGImageRef cgHeaderImage= CGImageCreateWithPNGDataProvider(dataProvider,NULL,NO, kCGRenderingIntentDefault); CGDataProviderRelease(dataProvider); headerCell.headerImage.image = [UIImage imageWithCGImage:cgHeaderImage scale:2.0 orientation:UIImageOrientationUp]; CGImageRelease(cgHeaderImage); – Gerd Oct 11 '10 at 10:34
  • Because the PNGRepresentation has no notion of "scale" (similarly, the JPEGRepresentation has no notion of transparency); the image is simply loaded by CGImage. While in theory you could use image DPI, I'm pretty sure that CGImage simply ignores DPI information, so UIImage would have to do additional parsing. Additionally, DPI information is *almost always meaningless*: Macs default to 72, Windows defaults to 96, and most digital cameras default to 300 (and the "DPI" of a photo is completely meaningless; I want angular resolution/FOV and lens distortion curve). – tc. Oct 13 '10 at 20:13
  • I'd also just use `UIImage * img = [UIImage imageWithData:...]; img = [UIImage imageWithCGImage:img.CGImage, scale:2 orientation:img.imageOrientation];`. And finally, `img = [UIImage imageWithData:UIImagePNGRepresentation(img)]` isn't an indentity transform; UIImagePNGRepresentation will often have to convert from premultiplied alpha to "normal" alpha. – tc. Oct 13 '10 at 20:16
  • Do you have any idea how slow that is? Just use `UIImage *image = ,,,;`. Most Apple-created UI elements can handle oversized images, they will scale them down automatically. – Nate Symer Aug 27 '12 at 20:12
  • I just tried it and it works fine for me on the iPhone. On the iPad the images are too small because the original image isn't twice the size of the frame I'm putting them into. – JScarry Sep 26 '12 at 21:04
  • Why this method make my image a half smaller ? scale = 2 means my image double size instead, right ? – Tung Vu Duc Apr 23 '19 at 07:01
19

Since iOS 6.0 UIImage has method + imageWithData:scale:, you can pass 2.0 as scale for retina.

Dennis Krut
  • 423
  • 1
  • 6
  • 11
8

You can pass [[UIScreen mainScreen] scale] as the scale parameter instead of 2.0f.

Phil Loden
  • 1,394
  • 1
  • 15
  • 15
0

Swift3, 4 version

let image = UIImage(data: imageData, scale: UIScreen.main.scale)
allen huang
  • 165
  • 1
  • 4
-1

put this in your .m if you want or on an imported class (the syntax of c is nicer when calling the function IMAO)

BOOL isRetina(){
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        return [[UIScreen mainScreen] scale] == 2.0;
    }
    return NO;
}

Then when creating the image with the server data:

[UIImage imageWithData:dataFromServer scale:isRetina()?2:1];
BenMorel
  • 34,448
  • 50
  • 182
  • 322
user2387149
  • 1,219
  • 16
  • 28
-4

AFAIK you don't need to set the scale value yourself. The OS will handle the points to pixel translation for you.

Rengers
  • 14,911
  • 1
  • 36
  • 54
  • If I just initialise a UIImage from data, it is up-scaled on the iPhone 4. (eg, a 320x480 image will be fullscreen on iPhone 4). I need to prevent this somehow so I can use high resolution images – Sam Jul 20 '10 at 11:20
  • 2
    That's only if an image has the @2x suffix which isn't possible when you `initWithData` – James Webster Feb 28 '12 at 17:39