从子目录加载视网膜图像
问题描述:
我正在使用NSDrawNinePartImage()
绘制可拉伸控件。由于这当然需要九个单独的图像来绘制这些部分(加上一些额外的东西),我有一个目录充满了像top-left.png
和[email protected]
这样的文件。我将这个目录包含在我的应用程序包中作为文件夹引用。从子目录加载视网膜图像
不幸的是,像-[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];
}
也能正常工作正常显示,但它忽略了2倍的图像的Retina显示屏。我怎样才能让它加载视网膜图像呢?有没有比分别加载两个代表并手工合并更好的方法?我宁愿不使用TIFF作为这些资源的源文件,因为我使用Acorn作为图像编辑器,而且最后一次检查时,它并不真正了解像这样的复合图像格式。
答
我最终咬住了子弹,并在运行时手动合并图像。我这样做是在上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;
}
答
简单的答案是使用TIFF,你的担心是错位的。在Xcode中设置项目首选项“合并高分辨率图稿”,并继续像现在一样使用Acorn生成您的两个PNG。在构建过程中,Xcode会将这两个PNG合并为一个TIFF并将其存储在您的包中。
答
这是我做的:
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文件)。但它可以让您免去手动选择图像分辨率的烦恼(这也需要您听取后备存储更改)。
“合并高分辨率图稿”似乎不影响文件夹引用。任何想法如何解决这个问题? – 2013-05-10 21:20:55
@ BrentRoyal-Gordon - 对不起,我不知道你最好的答案。要看的东西包括:包括文件而不是文件夹(你仍然可以用Acorn编辑它们);使用构建阶段脚本来合并和复制文件;并使用嵌套捆绑(添加一个捆绑子项目,把图像放在那里,让Xcode构建并复制捆绑包 - 可能听起来过分夸张,但捆绑只是一个文件夹,它只是让Xcode生成文件夹的一种方式)。 HTH – CRD 2013-05-11 07:13:56