2011-02-12 51 views
15

我有一個應用程序從NSURL中提取圖像。是否有可能通知應用程序他們是視網膜('@ 2x')版本(圖像是視網膜分辨率)?目前,我有以下但圖像會顯得像素化的更高分辨率的顯示器:來自Retina Display的URL的圖片

NSURL *url = [NSURL URLWithString:self.imageURL]; 
NSData *data = [NSData dataWithContentsOfURL:url]; 
UIImage *image = [UIImage imageWithData:data]; 
self.pictureImageView.image = image; 

回答

11

嘗試使用imageWithData:scale:(iOS 6或更高版本)

NSData *imageData = [NSData dataWithContentsOfURL:url]; 
UIImage *image = [UIImage imageWithData:imageData scale:[[UIScreen mainScreen] scale]]; 
0

@ 2倍的慣例是從應用程序包加載圖像只是方便的方式。 如果你wan't顯示視網膜顯示器上的圖像,那麼你必須讓它2倍大:

圖像尺寸100×100

查看尺寸:50×50。

編輯:我認爲,如果你是從加載服務器映像最好的解決辦法是增加一些額外的參數(如規模),並返回相應大小的圖像:

www.myserver.com/get_image.php?image_name=img.png&scale=2 

可以使用獲得規模經濟[ [UIScreen mainScreen]刻度]

17

您需要在將UIImage添加到圖像視圖之前重新縮放UIImage。

NSURL *url = [NSURL URLWithString:self.imageURL]; 
NSData *data = [NSData dataWithContentsOfURL:url]; 
UIImage *image = [UIImage imageWithData:data]; 
CGFloat screenScale = [UIScreen mainScreen].scale; 
if (image.scale != screenScale) 
    image = [UIImage imageWithCGImage:image.CGImage scale:screenScale orientation:image.imageOrientation]; 
self.pictureImageView.image = image; 

最好避免對比例值進行硬編碼,從而調用UIScreen。有關爲什麼這是必要的更多信息,請參閱Apple的UIImage’s scale property文檔。

最好避免使用NSData-dataWithContentsOfURL:方法(除非您的代碼在後臺線程上運行),因爲它使用無法監視或取消的同步網絡調用。您可以在this Apple Technical Q&A中閱讀更多有關同步網絡的難題和避免它的方法。

+0

謝謝!看起來就像我在找什麼! – 2011-02-12 04:50:40

+0

這在iOS7中不再適用。請參閱下面的n13答案。此外,請參閱此處接受的答案:http://stackoverflow.com/questions/5518790/downloading-normal-image-vs-retina-device-image-2x – RajV 2014-01-27 19:34:53

1

只是爲了補充一點,我特別做了以下工作,在相同的情況下,就像魅力一樣。

double scaleFactor = [UIScreen mainScreen].scale; 
     NSLog(@"Scale Factor is %f", scaleFactor); 
     if (scaleFactor==1.0) { 
      [cell.videoImageView setImageWithURL:[NSURL URLWithString:regularThumbnailURLString]; 
     }else if (scaleFactor==2.0){ 
      [cell.videoImageView setImageWithURL:[NSURL URLWithString:retinaThumbnailURLString]; 
     } 
5

您需要在UIImage上設置比例。

UIImage* img = [[UIImage alloc] initWithData:data]; 
CGFloat screenScale = [UIScreen mainScreen].scale; 
if (screenScale != img.scale) { 
    img = [UIImage imageWithCGImage:img.CGImage scale:screenScale orientation:img.imageOrientation]; 
} 

文檔說要小心,構建所有的UIImages相同的比例,否則你可能會奇怪的顯示問題,那裏的東西展示的一半大小,兩倍大小,半分辨率,等等。爲了避免這一切,請在視網膜分辨率下加載所有UIImage。資源將自動以正確的比例加載。對於從URL數據構建的UIImages,您需要設置它。

0
+ (void)deviceScaledImageForView:(UIImageView*)v 
     withParameterizedUrl:(NSString*)url 
       iPadSupport:(BOOL)iPadSupport 
         after:(UITask)after 
{ 

// ...Declare Retina and Retina Plus versions of the the URL string... 
NSString* url2x = @""; 
NSString* url3x = @""; 

// ...And if I'm on an iPad with my caller allowing iPad-specific images... 
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && iPadSupport) { 
    // ...Generate the iPad non-retina and retina versions of the URL... 
    /* Note 3x is not applicable to iPad */ 
    url = [url stringByReplacingOccurrencesOfString:@".png" withString:@"~ipad.png"]; 
    url2x = [url stringByReplacingOccurrencesOfString:@"~ipad.png" withString:@"@2x~ipad.png"]; 
} 
// ...Or, for iPhone... 
else { 
    // ...Generate the iPhone non-Retina, Retina and Retina Plus versions of the URL... 
    url2x = [url stringByReplacingOccurrencesOfString:@".png" withString:@"@2x.png"]; 
    url3x = [url stringByReplacingOccurrencesOfString:@".png" withString:@"@3x.png"]; 
} 

// ...If I'm running on iOS 7.1 or newer... 
CGFloat scale = .0f; 
UIScreen* screen = [UIScreen mainScreen]; 
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) 
    // ...Choose a scale based on the iOS 8 API. 

    //currently the scale for the 6 plus ranges from 2.6 to 2.8 to 3.0 depending on zoomed mode or running on the sim 
    // since our images are at 2x or at 3x we want whole numbers. 
    scale = ceilf(screen.nativeScale); 
else 
    // ...Choose a device scale on the iOS 7 API. 
    scale = screen.scale; 

// ...If I've chosen a Retina Plus scale... 
if (scale > 2.0f){ 
    // ...Select the 3x Retina Plus version of the image. 
    url = url3x; 
} 

// ...Otherwise for retina displays... 
else if (scale == 2.0f) 
    // ...Select the Retina version of the image. 
    url = url2x; 

// ...And finally, request the image data with SDWebImage (for cache support)... 
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:url] 
                 options:SDWebImageDownloaderUseNSURLCache 
                progress:nil 
                completed:^(UIImage* i, 
                   NSData* d, 
                   NSError* e, 
                   BOOL finished) 
{ 
    // ...And after the image is obtained... 
    // ...Apply it to the image view with the correct device scale... 
    v.image = [UIImage imageWithData:d scale:scale]; 

    // ...And if I have an after-action... 
    if (after) 
     // ...Run it. 
     after(); 
}]; 

} 
0

說句iPhone編程特定的圖像是視網膜,你可以做這樣的事情:

UIImage *img = [self getImageFromDocumentDirectory]; 
img = [UIImage imageWithCGImage:img.CGImage scale:2 orientation:img.imageOrientation]; 

在我的情況下,TabBarItem圖像是動態的,即從服務器下載。然後,iOS無法將其識別爲視網膜。上面的代碼片段對我來說就像一個魅力。