我正在尝试以编程方式创建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}代表=(
"NSBitmapImageRep 0x10380b900 Size={512, 512} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=1024x1024 Alpha=YES
Planar = NO Format =(尚未加载)CurrentBacking = nil(故障)CGImageSource = 0x10380ae70“
)|
2012-12-31 12:48:52.058 Eicon [912:680f] | NSImage 0x101b4caf0大小= {512,512}代表=(
"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}代表=(
"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}代表=(
"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 Size = {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 Size = {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 Size = {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 Size = {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“
)|
错误消息是正确的。您要放入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 =(尚未加载)BPS = 8 BPP =(尚未加载)像素= 1024x1024 Alpha =否平面=否格式=(尚未加载)CurrentBacking =无(故障)CGImageSource = 0x104221170“
11.52分不是IconFamily的任何元素的有效大小。您需要找出为什么此图像和代表具有该大小。
另外两件事:
size
(点大小)(最好是有效值)。-[NSImage initWithSize:]
文档说:
可以通过传递大小(0.0,0.0)来初始化接收器;但是,在使用NSImage对象之前,必须将接收器的大小设置为非零值,否则将引发异常。
您没有设置任何对象的大小,这是您需要做的。 (我很惊讶您没有像文档承诺那样对此有例外。)
正如我在另一个问题上提到的那样,不再有1024点元素; 1024 x 1024像素元素的正确规格为512点@ 2x。这是size
(包括图像和表示),等于(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
。