How to programmatically make Mac OS X ICNS with 10 different images using sips or other

My problem is what I need. I need to achieve this programmatically.

So, for mac os x, the application icon should have the following dimensions:

I have 10 images. Each of them I placed an icon in the right corner, the location and position of this icon do not scale. So there are 10 different images.

How to make ICNS out of this?

I thought of using sips, however sips only accepts one file, and it does all the scaling: http://cc.bingj.com/cache.aspx?q=mac+icns+sips+argument+list&d=5035141870911884&mkt=en-US&setlang= en-US & w = n3PZcWn6bEPxt4O96PPLd6nugtVq5jDz

Is there any way to make /usr/bin/sips take my 10 images and make icns from it? If bows can't do it the other way?

0
source share
1 answer

If you want to use iconutil , you can do it. At least on my system, 10.9.5 is part of the base OS. This is not a special installation like developer tools. You can verify that with:

 pkgutil --file-info /usr/bin/iconutil 

Here are the outputs:

 volume: / path: /usr/bin/iconutil pkgid: com.apple.pkg.BSD pkg-version: 10.9.0.1.1.1306847324 install-time: 1402788942 uid: 0 gid: 0 mode: 755 

The important part is pkgid. This is part of the BSD package, which is part of the base OS.

However, it is not difficult to write some code to do this.

You can use the CGDestination API. Create a destination using CGImageDestinationCreateWithURL() . For type , go kUTTypeAppleICNS .

Given that you want to add images from separate files, the easiest way is to create a CGImageSource for each of them using CGImageSourceCreateWithURL() . Then you can directly add the image from the source to the destination using CGImageDestinationAddImageFromSource() . Remember CFRelease() each source after adding the image to the destination.

Then call CGImageDestinationFinalize() so that the destination writes the image at the URL. Then CFRelease() the destination.

If each of the source images has the correct DPI set, it will be copied unchanged to the destination. If the source images do not have the proper DPI set, you can override it by passing the CGImageDestinationAddImageFromSource() property dictionary. Include the kCGImagePropertyDPIHeight and kCGImagePropertyDPIWidth , each of which has a corresponding CFNumber with the desired DPI. For a normal resolution icon, use 72 DPI. For the high resolution icon (@ 2x), use 144 DPI.


Creating ICNS files can also be done using the old IconFamily API, but it's a little hairy. In addition, it does not support high-resolution icons.

First, you create a handle (pointer-to-pointer-to-resizable-buffer) for the icon family:

 IconFamilyHandle iconFamily = (IconFamilyHandle)NewHandle(0); 

Then, for each image size (16, 32, 128, 256, and 512), you create a handle for the raw bitmap of the image data. The bitmap should be 32 bits per pixel, 8 bits per component, ARGB - non-spanned data without laying.

 int size = /* 16, 32, 128, 256, or 512 */; Handle handle = NewHandle(size * size * 4); // fill handle with image data; buffer pointer is *handle 

Then you add this handle to the icon family with a call like:

 SetIconFamilyData(iconFamily, kIconServices16PixelDataARGB, handle); 

For other sizes, replace "16" in kIconServices16PixelDataARGB with the appropriate value.

Then you write the descriptor data for the icon family to a file. A pointer to the data is obtained by dereferencing the handle (i.e. *iconFamily ). Its size is obtained by calling GetHandleSize((Handle)iconFamily) .

Dispose of all the handles you created by calling DisposeHandle() .

+2
source

All Articles