如何确定 -[UIImage imageNamed:] 将加载的文件的路径?
Posted
技术标签:
【中文标题】如何确定 -[UIImage imageNamed:] 将加载的文件的路径?【英文标题】:How do I determine the path of the file that -[UIImage imageNamed:] will load? 【发布时间】:2012-07-11 21:14:50 【问题描述】:我有一个继承项目,其中包含一堆使用-[UIImage imageWithContentsOfFile:]
和完整路径的代码。我正在将其转换为使用 -[UIImage imageNamed:]
和仅使用文件名(无扩展名),因此我可以将其传递给 @"icon"
之类的内容,并酌情获取 icon.png
或 icon@2x.png
或 icon~ipad.png
。
问题是,程序中有一部分我想检查图像的大小,如果它太大,我想显示TooBigImage.png
。
所以我需要知道,如果我调用[UIImage imageNamed: someName]
,它将使用哪个扩展/修改名称。基本上,我想要那个文件的路径,所以我可以在加载图像之前检查它的大小。
或者,如果有办法检查imageSizeForImageNamed:
或类似的东西,我可以使用它,我只是不知道。
我宁愿不重新实现整个“如果视网膜,附加@2x,等等......”的事情,因为这是(a)麻烦和(b)脆弱(如果苹果改变/增强行为?)
提示?
谢谢!
【问题讨论】:
当你说尺寸时,你是指像素尺寸还是字节尺寸? 我不想踩到你的脚趾,但[UIImage imageNamed]
应该只用于 UI 图标图像,因为它将检索到的图像缓存在 RAM 中,这可能会导致内存问题(如果使用不当) .另一方面,[UIImage imageWithContentsOfFile]
不进行缓存,这对于较大的图像是可取的。
@ids:要么。 @Torsten:我相信你不使用imageNamed
是错误的。系统缓存没问题,早期 ios 的漏洞早就修复了。
不过,您不希望将图像在 Ram 中保留更长的时间。如果它适合你的情况,那就这样吧。恕我直言,最简单且一点也不脆弱的方法是查询界面习语和比例因子,并据此计算图像大小。如果新设备问世,您必须重新访问此代码,但无论如何您可能都必须调整应用的其他方面。
是否有原因 if (image.size.width > 1000) blah blah;不会在这里工作?设置适当的图像后,UIImage 将包含加载图像的 size 属性。
【参考方案1】:
对于像素,请使用 size
和 scale
属性:
UIImage *getMySize = [UIImage imageNamed:@"blah"];
float width = getMySize.scale * getMySize.size.width;
float height = getMySize.scale * getMySize.size.height;
这里是UIImage Documentation。
【讨论】:
对。我想知道是否有一个解决方案可以为我提供imageNamed:
将使用的文件的名称,这样我就可以在不加载它的情况下检查文件统计信息。
好吧,一旦你有了像素大小,你应该能够确定它返回的是哪个文件,除非你的主包中有多个文件名为“blah*.png”,它们的大小相同。当您对主包拥有如此多的控制权时,使用大小信息和回溯来确定它正在使用您的哪些文件应该不会太难。【参考方案2】:
[UIImage imageNamed: @"icon"]
总是在应用程序主包中查找。所以icon.png
必须位于要找到的捆绑包中。那里不允许有子路径。
但是,您可以使用[NSBundle bundleWithPath: @"subfolder"]
定义自己的捆绑包,这样做的好处是您可以使用捆绑包方法来检索优化的资产。
NSBundle *bundle = [[NSBundle bundleWithPath: @"folder"] autorelease];
然后,[bundle pathForResource:ofType:]
将从您的文件夹(即 icon~ipad)返回正确的图像资源路径,[UIImage imageWithContentsOfFile:]
将负责大小修饰符。
虽然这个问题没有答案,但它很好地总结了我的经验。 How do NSBundle pathForResource:ofType: and UIImage imageWithContentsOfFile: handle scale and device modifiers?
【讨论】:
是的,imageNamed
总是在主包中查找,但并不总是加载“icon.png”——这就是这个问题的意义所在:我可以确定要加载什么文件吗?
它将加载最合适的资源。根据定义,该函数从包的根文件夹加载具有给定名称的 png 图像。没有办法(我知道)告诉这个函数加载另一个图像。该功能虽然足够智能,可以加载 iPhone/ipad 和/或 @2x 图像(如果存在)。【参考方案3】:
据我所知,您应该实现自己的功能来手动检查文件的大小。
您可以自己生成名称,例如:
-(bool)fileOk:(NSString*)filename
bool retina = [UIScreen mainScreen].scale == 2.0;
static bool iPad = UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad;
//Generate the filename
NSString *fullFilename = [NSString stringWithFormat:@"%@%@%@",filename,(retina)?@"@2x":@"",(iPad)?@"~ipad":@"~iphone"];
//Get the size:
NSError *error;
NSString *fullPath=[[NSBundle mainBundle] pathForResource:fullFilename ofType:@"png"];
NSDictionary *fileDictionary = [[NSFileManager defaultManager] attributesOfItemAtPath: fullPath error:&error];
return (fileDictionary && [fileDictionary fileSize]<SOME_TO_BIG_SIZE_CONSTANT);
然后您可以选择是否要显示图像。我还没有尝试过代码,所以可能有一些错字... 我希望这就是你要找的……
【讨论】:
这有我在脆弱性问题中提到的问题。 (正如发布的那样,它也有问题,但我会把它留作练习。;) 好吧,我进行了编辑,所以它可以检测文件是否存在。如果文件不存在,则 fileDictionary 将为 nil。我认为你的问题是一个非常容易解决的问题......以上是关于如何确定 -[UIImage imageNamed:] 将加载的文件的路径?的主要内容,如果未能解决你的问题,请参考以下文章