macoscocoasizensimageicns

Creating Icons (ICNS) programmatically from 1024 * 1024 size NSImage


I'm trying to create an ICNS of size 120 * 120 from a 1024x1024 image programmatically. Currently I'm creating an NSImage, then I create CGImageRef objects with the appropriate resolution, finally I'm saving them to a path using CGImageDestinationAddImage().

I have gone through various links one of them is: Creating an ICNS programmatically: "Unsupported Image Size"

But the problem is, The code generated the same size icon file. (1024 * 1024)

Here's the code:

- (void)generateIconSizeFromImage:(NSString *)path
{
    //destination path

    NSURL *fileURL = [NSURL fileURLWithPath:@"/Users/harjotsingh/Desktop/TestIconGenerated/test1@2x.png"];
    CGImageDestinationRef dr = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypePNG , 1, NULL);

    //image from path
    NSImage *img = [[NSImage alloc] initWithContentsOfFile:path];

    //setting its size to one of icon size
    [img setSize:NSMakeSize(60,60)];

    //setting its rep size to one of icon size
    for (NSImageRep *rep in [img representations])[rep setSize:NSMakeSize(60,60)];

    //setting the dpi, so it create 120 * 120 size icon file
    NSDictionary *imageProps1x = @{
                                   (__bridge NSString *)kCGImagePropertyDPIWidth: @144.0,
                                   (__bridge NSString *)kCGImagePropertyDPIHeight: @144.0,
                                   };

    // Add rect size
    NSRect prect = NSMakeRect(0,0,60,60);

    //get image for desired size
    CGImageRef generatedImage = [img CGImageForProposedRect:&prect context:[NSGraphicsContext currentContext] hints:nil];

    //sadly it shows the same 1024 * 1024 size
    NSLog(@"width:-- %zu && height:-- %zu",CGImageGetWidth(generatedImage),CGImageGetHeight(generatedImage));

    //adding to destination folder
    CGImageDestinationAddImage(dr, generatedImage, (__bridge CFDictionaryRef)(imageProps1x));

    //finalize.
    CGImageDestinationFinalize(dr);

    CFRelease(dr);
}

The image used from input path is of 1024 * 1024 pixels. "the correct specification for a 1024-by-1024-pixel element is as 512 points @ 2x. That's a size (of both image and rep) of (NSSize){ 512.0, 512.0 } (points), with the rep being 1024 pixelsWide and 1024 pixelsHigh." NOTE: This has been taken care of but still no success.


Solution

  • I have gone through this and get it done with few changes. Here's the working code to generate icon form large size image:

    - (void)generateIconSizeFromImage:(NSString *)path
    

    {

    NSImage * smallImage = [[NSImage alloc] initWithContentsOfFile:path];
    [smallImage setSize:NSMakeSize(120,120)];
    
    [smallImage lockFocus];
    
    [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
    
    [smallImage drawInRect:CGRectMake(0, 0, 120,120)];
    
    [smallImage unlockFocus];
    
    
    //destination path
    NSURL *fileURL = [NSURL fileURLWithPath:@"/Volumes/Harjot/Documents/MyProjects/Cobby Mac App/test60@2x.png"];
    
    CGImageDestinationRef dr = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypePNG , 1, NULL);
    
    //setting the dpi, so it create 120 * 120 size icon file
    NSDictionary *imageProps1x = @{
                                   (__bridge NSString *)kCGImagePropertyDPIWidth: @144.0,
                                   (__bridge NSString *)kCGImagePropertyDPIHeight: @144.0,
                                   };
    
    //get image for desired size
    CGImageRef generatedImage = [smallImage CGImageForProposedRect:NULL context:[NSGraphicsContext currentContext] hints:nil];
    
    //now it works and generate the 120 by 120 icon
    NSLog(@"width:-- %zu && height:-- %zu",CGImageGetWidth(generatedImage),CGImageGetHeight(generatedImage));
    
    //adding to destination folder
    CGImageDestinationAddImage(dr, generatedImage, (__bridge CFDictionaryRef)(imageProps1x));
    
    //finalize.
    CGImageDestinationFinalize(dr);
    
    CFRelease(dr);
    

    }

    Enjoy :)