如何确定 -[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.pngicon@2x.pngicon~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】:

对于像素,请使用 sizescale 属性:

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:] 将加载的文件的路径?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定样本量

如何确定滚动视图中当前可见的区域并确定中心?

Flink on YARN时,如何确定TaskManager数

如何确定 div 是不是滚动到底部?

七步法计算测量不确定度:第四步

如何确定控件何时对用户可见?