从子目录加载视网膜图像
Posted
技术标签:
【中文标题】从子目录加载视网膜图像【英文标题】:Loading retina images from a subdirectory 【发布时间】:2013-05-10 05:14:50 【问题描述】:我正在使用NSDrawNinePartImage()
来绘制可拉伸控件。因为这当然需要九个单独的图像来绘制零件(加上一些在上面绘制的额外内容),所以我有一个充满文件的目录,例如top-left.png
和top-left@2x.png
。我将此目录作为文件夹引用包含在我的应用程序包中。
不幸的是,-[NSImage imageNamed:]
和 -[NSBundle imageForResource:]
等常用的图像加载 API 似乎不支持子目录,即使您在名称中添加了斜线也是如此。相反,我使用这种方法加载图像:
- (NSImage*)popoverImage:(NSString*)name
NSURL * url = [[NSBundle bundleForClass:self.class] URLForResource:name withExtension:@"png" subdirectory:@"popover"];
return [[NSImage alloc] initWithContentsOfURL:url];
这适用于普通显示器,但它忽略了视网膜显示器的 2x 图像。我怎样才能让它也加载视网膜图像?有没有比分别加载两个代表并手动组合它们更好的方法?我宁愿不使用 TIFF 作为这些资源的源文件,因为我使用 Acorn 作为我的图像编辑器,而上次我检查时,它并不能很好地理解这样的复合图像格式。
【问题讨论】:
【参考方案1】:简单的答案是使用 TIFF,您的担心是错误的。在 Xcode 中,设置项目首选项“Combine High Resolution Artwork”,并像现在一样继续使用 Acorn 生成两个 PNG。在构建期间,Xcode 会将这两个 PNG 组合成一个 TIFF,并将其存储在您的包中。
【讨论】:
“合并高分辨率图稿”似乎不会影响文件夹引用。知道如何解决这个问题吗? @BrentRoyal-Gordon - 对不起,我不知道你的最佳答案。要查看的内容包括:包括文件而不是文件夹(您仍然可以使用 Acorn 编辑它们);使用构建阶段脚本来组合和复制文件;并使用嵌套包(添加一个包子项目,将图像放入其中,让 Xcode 构建并复制包 - 听起来可能有点过分,但包只是一个文件夹,它只是让 Xcode 生成文件夹的一种方式)。 HTH【参考方案2】:我最终硬着头皮在运行时手动组合图像。我通过在 NSImage 上的一个类别中添加这个方法,然后用它代替 -initWithContentsOfURL:
来做到这一点:
- (id)initRetinaImageWithContentsOfURL:(NSURL *)url
if((self = [self initWithContentsOfURL:url]))
NSURL * baseURL = url.URLByDeletingLastPathComponent;
NSString * baseName = url.lastPathComponent.stringByDeletingPathExtension;
NSString * extension = url.lastPathComponent.pathExtension;
NSString * retinaBaseName = [NSString stringWithFormat:@"%@@2x", baseName];
NSURL * retinaURL = [baseURL URLByAppendingPathComponent:[retinaBaseName stringByAppendingPathExtension:extension]];
if([retinaURL checkResourceIsReachableAndReturnError:NULL])
NSData * data = [[NSData alloc] initWithContentsOfURL:retinaURL];
NSBitmapImageRep * rep = [[NSBitmapImageRep alloc] initWithData:data];
rep.size = self.size;
[self addRepresentation:rep];
return self;
【讨论】:
【参考方案3】:这就是我的工作:
NSArray *paths = [NSBundle.mainBundle pathsForResourcesOfType: @"icns" inDirectory: @"Collections/1"];
for (NSString *path in paths)
NSString *fileName = [[path lastPathComponent] stringByDeletingPathExtension];
NSImage *image = [[NSImage alloc] initWithContentsOfFile: path];
image.name = fileName;
[iconCollectionController addObject: @@"icon": image];
但是正如 CRD 已经指出的那样,您需要合并您的作品(作为 tiff 或 icns 文件)。但它使您无需手动选择图像分辨率(这也需要您聆听后备存储的更改)。
【讨论】:
以上是关于从子目录加载视网膜图像的主要内容,如果未能解决你的问题,请参考以下文章
如何在资产目录新图像集中删除所有 iPhone/iPad 视网膜/非视网膜图像