以编程方式创建ICNS:“不支持的图像大小”

时间:2012-12-29 20:54:57

标签: 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不支持的图片大小(1024 x 1024) - 缩放系数:1

每次dpi为72且尺寸为1024x1024时,都会显示以上错误。

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


编辑:我记录了图片:

  

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

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

平面=无格式=(尚未加载)CurrentBacking = nil(断层)   CGImageSource = 0x10380ae70"

     

)|

     

2012-12-31 12:48:52.058 Eicon [912:680f] | NSImage 0x101b4caf0   大小= {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   大小= {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   大小= {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   大小= {128,128}代表=(

"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   大小= {128,128}代表=(

"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尺寸= {32,   32}代表=(

"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尺寸= {32,   32}代表=(

"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尺寸= {16,   16}代表=(

"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尺寸= {16,   16}代表=(

"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"

     

)|

1 个答案:

答案 0 :(得分:1)

错误消息是正确的。您正在放入IconFamily格式不支持的图像。具体来说,从您的输出:

  

2012-12-26 13:48:57.682 Eicon [1131:1b0f] | NSImage 0x1025233b0 尺寸= {11.52,11.52} Reps =(“NSBitmapImageRep 0x10421fc30 尺寸= {11.52, 11.52} ColorSpace =(尚未加载)BPS = 8 BPP =(尚未加载)Pixels = 1024x1024 Alpha = NO Planar = NO Format =(尚未加载)CurrentBacking = nil(错误)CGImageSource = 0x104221170“< / p>

对于IconFamily的任何元素,11.52点不是有效大小。你需要找出这个图像和代表有这么大的原因。

其他一些事情:

  1. 正如我在其他答案中告诉你的那样,你不需要改变表示的像素大小。保留像素大小。设置代表和图像的size(磅值)(最好是有效的东西)。
  2. -[NSImage initWithSize:]文档说:

      

    允许通过传递(0.0,0.0)的大小来初始化接收器;但是,在使用NSImage对象之前,必须将接收者的大小设置为非零值,否则将引发异常。

    您没有设置任何对象的大小,这是您需要做的。 (我很惊讶你没有像文件承诺那样得到例外。)

  3. 正如我在你提到的另一个问题上提到的,不再有1024点元素了; 1024×1024像素单元的正确规格为512点@ 2x。这是({1}}(点数)的size(图像和代表),其代表为1024 (NSSize){ 512.0, 512.0 }和1024 pixelsWide


    看起来我之前缺少一个关键成分。在这里。

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

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

    pixelsHigh

    将正确的字典作为NSDictionary *imageProps1x = @{ (__bridge NSString *)kCGImagePropertyDPIWidth: @72.0, (__bridge NSString *)kCGImagePropertyDPIHeight: @72.0, }; NSDictionary *imageProps2x = @{ (__bridge NSString *)kCGImagePropertyDPIWidth: @144.0, (__bridge NSString *)kCGImagePropertyDPIHeight: @144.0, }; 的最后一个参数传递。