2013-05-10 53 views
2

我正在使用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作为图像编辑器,而且最后一次检查时,它并不真正了解像这样的复合图像格式。

回答

0

我最终咬住了子弹,并在运行时手动合并图像。我这样做是在上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; 
} 
0

简单的答案是使用TIFF,你的担心是错位的。在Xcode中设置项目首选项“合并高分辨率图稿”,并继续像现在一样使用Acorn生成您的两个PNG。在构建过程中,Xcode会将这两个PNG合并为一个TIFF并将其存储在您的包中。

+0

“合并高分辨率图稿”似乎不影响文件夹引用。任何想法如何解决这个问题? – 2013-05-10 21:20:55

+0

@ BrentRoyal-Gordon - 对不起,我不知道你最好的答案。要看的东西包括:包括文件而不是文件夹(你仍然可以用Acorn编辑它们);使用构建阶段脚本来合并和复制文件;并使用嵌套捆绑(添加一个捆绑子项目,把图像放在那里,让Xcode构建并复制捆绑包 - 可能听起来过分夸张,但捆绑只是一个文件夹,它只是让Xcode生成文件夹的一种方式)。 HTH – CRD 2013-05-11 07:13:56

0

这是我做的:

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文件)。但它可以让您免去手动选择图像分辨率的烦恼(这也需要您听取后备存储更改)。