我有一个应用程序从NSURL
中提取图像。是否可以通知应用程序它们是视网膜('@ 2x')版本(图像是视网膜分辨率)?我目前有以下内容,但图像在更高分辨率的显示屏上显示为像素化:
NSURL *url = [NSURL URLWithString:self.imageURL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
self.pictureImageView.image = image;
答案 0 :(得分: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
的{{1}}方法(除非您的代码在后台线程上运行),因为它使用无法监视或取消的同步网络调用。您可以在this Apple Technical Q&A中阅读有关同步网络的痛苦以及避免它的方法的更多信息。
答案 1 :(得分:11)
尝试使用imageWithData:scale:
(iOS 6及更高版本)
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData scale:[[UIScreen mainScreen] scale]];
答案 2 :(得分: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,否则你可能会遇到奇怪的显示问题,其中显示的是一半大小,双倍大小,半分辨率等等。为避免这一切,请在视网膜分辨率下加载所有UIImages。资源将自动以正确的比例加载。对于根据URL数据构建的UIImages,您需要进行设置。
答案 3 :(得分: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];
}
答案 4 :(得分:0)
@ 2x约定只是从应用程序包加载图像的便捷方式。 如果你不想在视网膜显示器上显示图像,那么你必须使它大2倍:
图片尺寸100x100
查看尺寸:50x50。
编辑:我认为如果您从服务器加载图像,最好的解决方案是添加一些额外的参数(例如缩放)并返回适当大小的图像:
www.myserver.com/get_image.php?image_name=img.png&scale=2
您可以使用[[UIScreen主屏幕]比例]
获取比例答案 5 :(得分: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();
}];
}
答案 6 :(得分:0)
要以编程方式告诉iPhone特定图片 Retina ,您可以执行以下操作:
UIImage *img = [self getImageFromDocumentDirectory];
img = [UIImage imageWithCGImage:img.CGImage scale:2 orientation:img.imageOrientation];
在我的情况下,TabBarItem
图像是动态的,即从服务器下载的图像。然后iOS无法将其识别为视网膜。上面的代码片段对我来说就像一个魅力。