macos - 以编程方式创建 ICNS : "Unsupported Image Size"

标签 macos cocoa size nsimage icns

我正在尝试以编程方式创建 ICNS(包括 1024x1024 图像)。目前我正在创建一个 NSImage,然后创建具有适当分辨率的 CGImageRef 对象,最后我使用 CGImageDestinationAddImage()< 将它们添加到图标中。 Peter Hosey 已经帮助我创建了“@2x”图像,但不想设置图像的大小。

这是代码(还是有点乱,sourcefile代表图像的路径):

NSSize sizes[10];
sizes[0] = NSMakeSize(1024,1024);
sizes[1] = NSMakeSize(512,512);
sizes[2] = NSMakeSize(512,512);
sizes[3] = NSMakeSize(256,256);
sizes[4] = NSMakeSize(256,256);
sizes[5] = NSMakeSize(128,128);
sizes[6] = NSMakeSize(64,64);
sizes[7] = NSMakeSize(32,32);
sizes[8] = NSMakeSize(32,32);
sizes[9] = NSMakeSize(16,16);
int count = 0;
for (int i=0 ; i<10 ; i++) {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"Size%i",i+1]]) count++;
}
NSURL *fileURL = [NSURL fileURLWithPath:aPath];

// Create icns
CGImageDestinationRef dr = CGImageDestinationCreateWithURL((CFURLRef)fileURL, kUTTypeAppleICNS , count, NULL);
NSImage *img = [[NSImage alloc] initWithContentsOfFile:sourcefile];
for (int i=0 ; i<10 ; i++) {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"Size%i",i+1]]) {

        // Create dictionary
        BOOL is2X = true;
        if (i == 1 || i == 3 || i == 5 || i == 7 || i == 9) is2X = false;
        int dpi = 144, size = (int)(sizes[i].width/2);
        if (!is2X) {dpi = 72;size = sizes[i].width;}
        [img setSize:NSMakeSize(size,size)];
        for (NSImageRep *rep in [img representations])[rep setSize:NSMakeSize(size,size)];
        const void *keys[2] = {kCGImagePropertyDPIWidth, kCGImagePropertyDPIHeight};
        const void *values[2] = {CFNumberCreate(0, kCFNumberSInt32Type, &dpi), CFNumberCreate(0, kCFNumberSInt32Type, &dpi)};
        CFDictionaryRef imgprops = CFDictionaryCreate(NULL, keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

        // Add image
        NSRect prect = NSMakeRect(0,0,size,size);
        CGImageRef i1 = [img CGImageForProposedRect:&prect context:nil hints:nil];
        CGImageDestinationAddImage(dr, i1, imgprops);
    }
}
CGImageDestinationFinalize(dr);
CFRelease(dr);

size 是当前图像应有的宽度或高度。如果我们制作“@2x”图像,dpi 为 144,否则为 72。这些值已使用 NSLog 检查。

生成的 ICNS 文件中的图像与输入图像的大小相同。如果输入图像的大小是 1024x1024,ImageIO 会提示:

ImageIO: _CGImagePluginWriteICNS unsupported image size (1024 x 1024) - scaling factor: 1

每次dpi为72、尺寸为1024x1024时,都会出现上述错误。

我需要知道如何设置要添加到 ICNS 文件中的 CGImage 的大小。

<小时/>

编辑:我记录了图像:

2012-12-31 12:48:51.281 Eicon[912:680f] |NSImage 0x101b4caf0 Size={512, 512} Reps=(

"NSBitmapImageRep 0x10380b900 Size={512, 512} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=1024x1024 Alpha=YES

Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.058 Eicon[912:680f] |NSImage 0x101b4caf0 Size={512, 512} Reps=(

"NSBitmapImageRep 0x10380b900 Size={512, 512} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.111 Eicon[912:680f] |NSImage 0x101b4caf0 Size={256, 256} Reps=(

"NSBitmapImageRep 0x10380b900 Size={256, 256} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.238 Eicon[912:680f] |NSImage 0x101b4caf0 Size={256, 256} Reps=(

"NSBitmapImageRep 0x10380b900 Size={256, 256} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.309 Eicon[912:680f] |NSImage 0x101b4caf0 Size={128, 128} Reps=(

"NSBitmapImageRep 0x10380b900 Size={128, 128} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.409 Eicon[912:680f] |NSImage 0x101b4caf0 Size={128, 128} Reps=(

"NSBitmapImageRep 0x10380b900 Size={128, 128} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.534 Eicon[912:680f] |NSImage 0x101b4caf0 Size={32, 32} Reps=(

"NSBitmapImageRep 0x10380b900 Size={32, 32} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.616 Eicon[912:680f] |NSImage 0x101b4caf0 Size={32, 32} Reps=(

"NSBitmapImageRep 0x10380b900 Size={32, 32} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.729 Eicon[912:680f] |NSImage 0x101b4caf0 Size={16, 16} Reps=(

"NSBitmapImageRep 0x10380b900 Size={16, 16} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.864 Eicon[912:680f] |NSImage 0x101b4caf0 Size={16, 16} Reps=(

"NSBitmapImageRep 0x10380b900 Size={16, 16} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

最佳答案

错误信息是正确的。您所放入的图像尺寸不受 IconFamily 格式的支持。具体来说,从您的输出来看:

2012-12-26 13:48:57.682 Eicon[1131:1b0f] |NSImage 0x1025233b0 Size={11.52, 11.52} Reps=( "NSBitmapImageRep 0x10421fc30 Size={11.52, 11.52} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=1024x1024 Alpha=NO Planar=NO Format=(not yet loaded) CurrentBacking=nil (faulting) CGImageSource=0x104221170"

11.52 磅对于 IconFamily 的任何元素都不是有效的大小。您需要找出为什么此图像和代表具有该尺寸。

其他一些事情:

  1. 正如我在其他答案中告诉您的,您不需要更改表示的像素大小。不考虑像素大小。设置代表和图像的大小(点大小)(最好是有效的值)。
  2. -[NSImage initWithSize:] 文档说:

    It is permissible to initialize the receiver by passing a size of (0.0, 0.0); however, the receiver’s size must be set to a non-zero value before the NSImage object is used or an exception will be raised.

    您没有设置任何一个对象的大小,而这是您需要做的。 (我很惊讶你没有像文档 promise 的那样得到异常(exception)。)

正如我在您的另一个问题中提到的,不再有 1024 点元素了; 1024 x 1024 像素元素的正确规范是 512 点 @ 2x。这是 (NSSize){ 512.0, 512.0 }(点)的大小(图像和代表),代表为 1024 pixelsWide和 1024 pixelsHigh

<小时/>

看来我之前错过了一个关键成分。在这里。

您提供给 CGImageDestination 的 CGImage 没有与之关联的点大小 - 只有 NSImages 和 NSImageReps 有该点大小。 CGImage 只有像素大小;没有任何内容表明图像的物理尺寸或分辨率。

要告诉 CGImageDestination 给定的 CGImage 是 @ 1x 还是 @ 2x,您需要创建一个给出图像 DPI 的字典:

NSDictionary *imageProps1x = @{
    (__bridge NSString *)kCGImagePropertyDPIWidth: @72.0,
    (__bridge NSString *)kCGImagePropertyDPIHeight: @72.0,
};
NSDictionary *imageProps2x = @{
    (__bridge NSString *)kCGImagePropertyDPIWidth: @144.0,
    (__bridge NSString *)kCGImagePropertyDPIHeight: @144.0,
};

将正确的字典作为最后一个参数传递给CGImageDestinationAddImage

关于macos - 以编程方式创建 ICNS : "Unsupported Image Size",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14085843/

相关文章:

objective-c - 在自动布局中,我设置了不应水平增长的标签和应水平增长的控件。为什么我会反其道而行之?

swift - 在 Xcode 中创建自定义 View 列表

macos - UTI来自哪里?

objective-c - 如何编码 NSInitation?

xcode - WebView 从本地目录加载包含所有资源的 HTML 页面

objective-c - 如何复制CGLayer

c++ - 为位图设置 unsigned int 时出现问题

python - 无法安装 csv 模块

wpf - Canvas 背景的装订尺寸

c++ - 为什么使用 boost 会大大增加文件大小?