从子目录加载视网膜图像

时间:2013-05-10 05:14:51

标签: macos cocoa nsbundle

我使用NSDrawNinePartImage()绘制可伸缩控件。由于这当然需要九个单独的图像来绘制部分(加上一些额外的部分),我有一个目录,其中包含top-left.pngtop-left@2x.png等文件。我将此目录作为文件夹参考包含在我的应用包中。

不幸的是,通常的图片加载API(例如-[NSImage imageNamed:]-[NSBundle imageForResource:])似乎不支持子目录,即使您在名称中添加了斜杠也是如此。相反,我用这种方法加载图像:

- (NSImage*)popoverImage:(NSString*)name {
    NSURL * url = [[NSBundle bundleForClass:self.class] URLForResource:name withExtension:@"png" subdirectory:@"popover"];
    return [[NSImage alloc] initWithContentsOfURL:url];
}

这适用于普通显示器,但它忽略了视网膜显示器的2x图像。我怎样才能加载视网膜图像呢?有没有比分别加载两个代表并手工合并更好的方法?我宁愿不使用TIFF作为这些资源的源文件,因为我使用Acorn作为我的图像编辑器,上次我检查时,它并没有真正理解那样的复合图像格式。

3 个答案:

答案 0 :(得分:0)

简单的答案是使用TIFF,您的担忧是错误的。在Xcode中设置项目首选项“Combine High Resolution Artwork”并继续像现在一样使用Acorn生成两个PNG。在构建期间,Xcode会将这两个PNG组合成一个TIFF并将其存储在您的包中。

答案 1 :(得分: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;
}

答案 2 :(得分: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文件)。但它让您无需手动选择图像分辨率(这也需要您监听后备存储更改)。