The imageWithData:
method will always create an image with a scale of 1.0 (non-retina). Creating a retina-aware UIImage from a custom location outside the bundle, you need to use the initWithCGImage:scale:orientation:
method:
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.test.com/img2@2x.png"]]];
UIImage *retinaImage = [UIImage initWithCGImage:[image CGImage] scale:2.0 orientation:UIImageOrientationUp];
(and, obviously, you shouldn't download the image synchronously...).
I needed to do the same thing (loading scale-dependent images from the documents directory) in my last project, so I've written a small convenience method in a UIImage category:
- (id)initWithContentsOfResolutionIndependentFile:(NSString *)path
{
if([[UIScreen mainScreen] scale] == 2.0) {
NSString *path2x = [[path stringByDeletingLastPathComponent]
stringByAppendingPathComponent:[NSString stringWithFormat:@"%@@2x.%@",
[[path lastPathComponent] stringByDeletingPathExtension],
[path pathExtension]]];
if([[NSFileManager defaultManager] fileExistsAtPath:path2x]) {
return [self initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:path2x]] CGImage] scale:2.0 orientation:UIImageOrientationUp];
}
}
return [self initWithContentsOfFile:path];
}
Usage:
UIImage *myImage = [[UIImage alloc] initWithContentsOfResolutionIndependentFile:@"/path/to/image.png"];
This will try to load the image from /path/to/image@2x.png
when on retina, and use /path/to/image.png
otherwise.