## IconFamily class and MakeThumbnail example
for Mac OS X

by Troy Stephens, Thomas Schnitzer, David Remahl, Nathan Day, and Ben Haller

(See the IconFamily project page for the latest release and info!)

Congratulations to David Remahl on winning an Apple Design Award at WWDC 2002 for Can Combine Icons 2.1 (Runner Up, Best Mac OS X Student Product)! CCI builds on the IconFamily class and provides a nice, intuitive interface for compositing icons to make new ones. Way to go, David! :-)

August 6, 2002 - Version 0.5 released!

### Overview

"IconFamily" is a Cocoa/Objective-C wrapper for the Mac OS X Carbon API's "icon family" data type. Its main purpose is to enable Cocoa applications to easily create custom file icons from NSImage instances, and thus take advantage of Mac OS X's new 128x128 RGBA "thumbnail" icon format to provide richly detailed thumbnail previews of the files' contents. Using the IconFamily class you can also:

- read and write .icns files
- copy icon data to and from the scrap (pasteboard)
- assign an icon family as a file's kCustomIconResource, so it will appear in Finder views
- get and set the elements of an icon family in convenient, Cocoa-compatible NSBitmapImageRep form

The IconFamily code has spawned several useful image and icon processing tools for Mac OS X (see "Related Projects" below). It's also extensively commented, so extending it further and fixing problems should be pretty easy. I intend to put more work into it as I find the time, and welcome feedback and suggestions.

### Downloading

The complete package for the current version is available here: IconFamily-0.5.tgz

For those who might just want to try the MakeThumbnail example program without having to compile it first, there is also a "Deployment" build of the application: MakeThumbnail-0.5.dmg.gz

This package includes the source for a simple Cocoa testbed app called "MakeThumbnail" that demonstrates the use of the IconFamily class. MakeThumbnail lets you open any NSImage-supported image file and re-save it as a JPEG with an icon family consisting of various-sized thumbnail versions of the image assigned as the file's custom icon. It also enables you to save the same icon family to an .icns file.

You can also browse the core source code online:

- IconFamily.h
- IconFamily.m
- NSString+CarbonFSSpecCreation.h
- NSString+CarbonFSSpecCreation.m

(The complete source code for the MakeThumbnail example is included in the .tgz archive.)

### Usage Notes

One caveat: The data for an icon family that contains a "thumbnail" (128x128 32-bit RGBA) version isn't particularly small. Apple does some compression on the bitmap data assigned via SetIconFamilyData() (though apparently not on the 8-bit masks), but nonetheless a custom icon resource can take up in the neighborhood of 35,000 to 60,000 bytes in a file's resource fork (in my experience, using Mac OS X Public Beta). Storage is of course getting cheaper per gigabyte all the time, and users who work with a lot of image files may consider the extra use of disk space to be worth it. But while 50k of icon data adds comparatively little to a 5+ MB uncompressed image file, it can, at the other extreme, be larger than the actual image data for, say, a small JPEG file. It is also about 10x the size of the thumbnail data generated by image browsers I have used (albeit for lower, though I think adequate, resolution and quality). In short, my humble suggestion is to use this feature judiciously, and offer users the option of whether to save custom thumbnail icons with their image files.

### Credits / Contributors

Troy Stephens wrote the initial releases of the IconFamily code and MakeThumbnail demo. Thomas Schnitzer provided valuable help in understanding the related Carbon APIs, as well as contributions to the icon family element extraction code, that made these releases possible.

David Remahl, author of Can Combine Icons, generously donated his own extensions to the IconFamily class for the 0.3 and 0.4.x releases. Nathan Day has likewise helped fix bugs and has contributed useful extensions, in the course of using the IconFamily code to build Popup Dock. Ben Haller, author of Stick Software's Constrictor, pitched in his own contributions and dedication to get the 0.4 release out the door.

Mike Margolis, author of Sugar Cube Software's Pic2Icon tool, has contributed support for creating shadowed, dog-eared document-like thumbnail icons that I hope to have folded in for the next (0.5) release.

### Related Projects

David Remahl built on the IconFamily class to create Can Combine Icons, an elegant Cocoa-based Mac OS X application that makes short work of compositing icons to create new ones.

The bitmap manipulation code in Trollin's iconCompo, another versatile icon compositing tool, was influenced by the IconFamily source.

Thomas Schnitzer's Iconizer lets you zoom and drag-select to choose specific regions of your images from which to create thumbnail icons.

Sugar Cube Software's free Pic2Icon leverages the IconFamily class, enabling you to create thumbnails for image files with drag-and-drop simplicity.

Stick Software's Constrictor uses the IconFamily class to provide thumbnail icons for saved screen snapshots.

Gideon Softworks' FileXaminer (a Finder "Get Info" enhancement) uses IconFamily to support custom icon assignments.

Extraneous Software's LameSecure, a lightweight security tool, reportedly uses IconFamily somewhere, for something or other. :-)

### Version History

Version 0.5 - August 6, 2002

Updated for compatibility with Mac OS X 10.2:

- Fixed `-init` method so it works on both 10.1.x and 10.2
- Added calls to `FNNotify()` to improve Finder synchronization

Applications that rely on the `-init` method that was added in Version 0.4 should be recompiled with this new version of the IconFamily class for compatibility with Mac OS X 10.2.

Version 0.4.1 - May 2, 2002

Released within hours of 0.4, this version fixed the omission of two new methods submitted by David Remahl:

- `-setAsCustomIconForDirectory:`
- `-setAsCustomIconForDirectory:withCompatibility:`

There is also a new method in the "CarbonFSSpecCreation" category on NSString, which permits getting an `FSRef` for a given path. The prior method to get an `FSSpec` is now implemented in terms of this method.

Version 0.4 - May 2, 2002

Nathan Day, Ben Haller, and David Remahl contributed new features and bug fixes for the 0.4 release, including:

- fixes for the `-init` and `-setAsCustomIconOfFile:` methods
- a new `+removeCustomIconFromFile:` class method
- support for creating 8-bit indexed-color icon family elements
- respect for exiting type/creator codes in `-setAsCustomIconForFile:...` A new "compatibility" parameter to this method causes "large" and "small" 8-bit images and their 1-bit masks to be stored as independent resources in addition to being stored as members of the icon family resource
- a fix for `-writeToFile:` (previously there was a problem with certain kinds of paths)
- a probably more efficient alternative to going through `-tiffData` to get bitmap image representations in `-initWithThumbnailsOfImage:usingImageInterpolation:`

Special thanks to Ben for folding his and David's changes into a ready-to-go 0.4 release!

I've also fixed a potential divide-by-zero error in `+get32BitdataFromBitmapImageRep:`.

Version 0.3 - January 26, 2002

David Remahl contributed a number of useful extensions and fixes for this release, including:

- new init methods for creating an IconFamily from a standard system icon, from the Finder icon of a specified file, or from the Carbon Scrap Manager (Cocoa Pasteboard)
- a `-putOnScrap` method for placing a copy of an IconFamily on the Scrap (Pasteboard)
- code to undo the effects of premultiplied alpha in `get32BitDataFromBitmapImageRep:`
- a fix for 1-bit mask generation

Mike Margolis and David Remahl jointly suggested the use of NSGraphicsContext's `-setImageInterpolation:` method to specify the resampling algorithm to use. By default, the IconFamily class now uses `NSImageInterpolationHigh`, which produces higher-quality thumbnails than previous versions of the code, but you can easily choose from among `Default/None/Low/High`.

I added an accessory view to MakeThumbnail's "Save" panel to facilitate experimenting with the various `NSImageInterpolation...` settings that are now available. I've also added generation of "small" (16x16) icons, fixed memory leaks, and fixed a bug that affected the display size of the loaded image in the MakeThumbnail example under Mac OS X 10.0 and later versions.

IconFamily 0.3 has been tested on Mac OS X 10.1.2, using the December 2001 Developer Tools.

Version 0.2 - April 25, 2001

This release fixed a bug in the -bitmapImageRepWithAlphaForIconFamilyElement: method, where the NSBitmapImageRep's data was being referenced instead of copied and retained (sometimes resulting in a damaged bitmap or one containing random garbage).

I also added an init method for creating an IconFamily from an existing IconFamilyHandle, and removed the warnings about post-Public Beta Mac OS X compatibility, since the code appeared to work just fine on Mac OS X 10.0.

Version 0.1 alpha - February 28, 2001

First public release.

Troy Stephens (troy_stephens@mac.com)
Last Updated Monday, August 05, 2002