Mar*_*rov 11 objective-c high-resolution uiimage imagenamed ios4
正如许多人抱怨的那样,在用于Retina显示器的Apple SDK中,似乎存在一个错误,而imageWithContentsOfFile实际上并不会自动加载2x图像.
我偶然发现了一个很好的帖子,如何制作一个能够检测UIScreen比例因子并正确加载低或高分辨率图像的功能(http://atastypixel.com/blog/uiimage-resolution-independence-and-the-iphone-4s -retina-display /),但该解决方案加载2x图像并仍然将图像的比例因子设置为1.0,这导致2倍图像缩放2倍(因此,比它看起来大4倍)
imageNamed似乎可以准确地加载低分辨率和高分辨率图像,但对我来说不是一个选择.
有没有人有一个解决方案来加载低/高分辨率图像不使用imageNamed或imageWithContentsOfFile的自动加载?(或者最终解决方法如何使imageWithContentsOfFile工作正确)
Mar*_*rov 13
好的,迈克尔在这里找到的实际解决方案:http: //atastypixel.com/blog/uiimage-resolution-independence-and-the-iphone-4s-retina-display/
他发现UIImage的方法是"initWithCGImage",它也将比例因子作为输入(我想你可以自己设置比例因子的唯一方法)
[UIImage initWithCGImage:scale:orientation:]
Run Code Online (Sandbox Code Playgroud)
这看起来效果很好,您可以自定义加载高分辨率图像,并设置比例因子为2.0
imageWithContentsOfFile的问题在于,由于它目前无法正常工作,即使它已修复,我们也无法信任它(因为某些用户的设备上仍会有旧的iOS)
小智 11
我们刚刚在这里遇到了这个问题.这是我的解决方案似乎有水:
NSString *imgFile = ...path to your file;
NSData *imgData = [[NSData alloc] initWithContentsOfFile:imgFile];
UIImage *img = [[UIImage alloc] initWithData:imgData];
Run Code Online (Sandbox Code Playgroud)
imageWithContentsOfFile
从iOS 4.1及以后开始正常工作(考虑具有正确比例的@ 2x图像).
我已经为这个问题开发了一个简单的解决方法.它使用方法调配来替换UIImage的"imageWithContentsOfFile:"方法的行为.它在视网膜前/后的iPhone/iPod上运行良好.不确定iPad.
希望这有帮助.
#import </usr/include/objc/objc-class.h>
@implementation NSString(LoadHighDef)
/** If self is the path to an image, returns the nominal path to the high-res variant of that image */
-(NSString*) stringByInsertingHighResPathModifier {
NSString *path = [self stringByDeletingPathExtension];
// We determine whether a device modifier is present, and in case it is, where is
// the "split position" at which the "@2x" token is to be added
NSArray *deviceModifiers = [NSArray arrayWithObjects:@"~iphone", @"~ipad", nil];
NSInteger splitIdx = [path length];
for (NSString *modifier in deviceModifiers) {
if ([path hasSuffix:modifier]) {
splitIdx -= [modifier length];
break;
}
}
// We insert the "@2x" token in the string at the proper position; if no
// device modifier is present the token is added at the end of the string
NSString *highDefPath = [NSString stringWithFormat:@"%@@2x%@",[path substringToIndex:splitIdx], [path substringFromIndex:splitIdx]];
// We possibly add the extension, if there is any extension at all
NSString *ext = [self pathExtension];
return [ext length]>0? [highDefPath stringByAppendingPathExtension:ext] : highDefPath;
}
@end
@implementation UIImage (LoadHighDef)
/* Upon loading this category, the implementation of "imageWithContentsOfFile:" is exchanged with the implementation
* of our custom "imageWithContentsOfFile_custom:" method, whereby we replace and fix the behavior of the system selector. */
+(void)load {
Method originalMethod = class_getClassMethod([UIImage class], @selector(imageWithContentsOfFile:));
Method replacementMethod = class_getClassMethod([UIImage class], @selector(imageWithContentsOfFile_custom:));
method_exchangeImplementations(replacementMethod, originalMethod);
}
/** This method works just like the system "imageWithContentsOfFile:", but it loads the high-res version of the image
* instead of the default one in case the device's screen is high-res and the high-res variant of the image is present.
*
* We assume that the original "imageWithContentsOfFile:" implementation properly sets the "scale" factor upon
* loading a "@2x" image . (this is its behavior as of OS 4.0.1).
*
* Note: The "imageWithContentsOfFile_custom:" invocations in this code are not recursive calls by virtue of
* method swizzling. In fact, the original UIImage implementation of "imageWithContentsOfFile:" gets called.
*/
+ (UIImage*) imageWithContentsOfFile_custom:(NSString*)imgName {
// If high-res is supported by the device...
UIScreen *screen = [UIScreen mainScreen];
if ([screen respondsToSelector:@selector(scale)] && [screen scale]>=2.0) {
// then we look for the high-res version of the image first
UIImage *hiDefImg = [UIImage imageWithContentsOfFile_custom:[imgName stringByInsertingHighResPathModifier]];
// If such high-res version exists, we return it
// The scale factor will be correctly set because once you give imageWithContentsOfFile:
// the full hi-res path it properly takes it into account
if (hiDefImg!=nil)
return hiDefImg;
}
// If the device does not support high-res of it does but there is
// no high-res variant of imgName, we return the base version
return [UIImage imageWithContentsOfFile_custom:imgName];
}
@end
Run Code Online (Sandbox Code Playgroud)
增强Lisa Rossellis的答案,将视网膜图像保持在所需的大小(不缩放):
NSString *imagePath = ...Path to your image
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imagePath] scale:[UIScreen mainScreen].scale];
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
26635 次 |
最近记录: |