I'm trying to create an ICNS (including a 1024x1024 image) programmatically. Currently I'm creating an NSImage, then I create CGImageRef objects with the appropriate resolution, finally I'm adding them to an icon by using CGImageDestinationAddImage(). Peter Hosey has helped me create '@2x' images already, but the sizes of the images don't wanna be set.
This is the code (still a bit messy, sourcefile represents the path to the image):
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 is the width or height that the current image should be. dpi is 144 if we're making an '@2x' image, otherwise it's 72. These values have been checked with NSLog.
The images in the resulting ICNS file are all the same size as the input image. If the size of the input image is 1024x1024, ImageIO complains:
ImageIO: _CGImagePluginWriteICNS unsupported image size (1024 x 1024) - scaling factor: 1
The above error is displayed every time the dpi is 72 and the size is 1024x1024.
I need to know how to set the size of the CGImage that is to be added to the ICNS file.
EDIT: I logged the images:
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=YESPlanar=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=NOFormat=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=NOFormat=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=NOFormat=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=NOFormat=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=NOFormat=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=2CurrentBacking=|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=2CurrentBacking=|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=2CurrentBacking=|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=2CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"
)|