Color Reduction Algorithm

How do you save a GIF? The docs say SaveAsGIF is a cross platform format but every picture I’ve tried (alphaed or masked with 32, 16, 8, 4, 2, 1 bits) raises a UnsupportedFormatException on Cocoa and Carbon.

I see on NSBitmapImageRep there’s NSGIFFileType and NSImageRGBColorTable but I can’t tell how to use them.

Also, in Carbon drawing a 32bit picture to an 8 bit one warps the colors; drawing to 16, 4, 2 and 1 look ok. In Cocoa pictures are always 32bit.

GIF can be saved under OSX by leveraging the SIPS utility program installed on each MAC

below is a chunk of code from my app that uses this…
first is saves as PNG, then uses SIPS to convert it to GIF or TIFF

    //
    // Save Picture in GIF or TIFF format using SIPS command
    //
    // 1. save image as png file in temp directory
    temp_file=SpecialFolder.Temporary.child("temp.png")
    If temp_file.Exists Then temp_file.Delete
    // 2. use sips to convert from PNG to GIF and move to desired directory
    //pic_stack(current_picture).Save temp_file,Format
    work_area.save temp_file,Format
    'temp_file.SaveAsPicture pic_stack(Current_Picture),format
    app.DoEvents
    s="sips -s format "+sips_format+" "+temp_file.shellpath+" --out "+xfile.shellPath
    
    //
    sh.Mode = 0
    sh.Execute s

However I have opted to change my apps requirements…
It will now allow conversion to 216/64 WebSafe Colors which can be done with a Transform Map
for 216 colors it uses 0x00, 0x33,0x66,0x99,0xcc and 0xFF as the transform points
for 64 colors it uses 0x00, 0x55,0xAA and 0xFF
and looks pretty darn good too.

I would suggest starting with either MacOSLib or MBS as there are quite a few elements to be implemented, for using Core Image. However once you get it up and running, there is very little that can compare. Apple do so much work for you behind the scenes, taking advantage of all the hardware it can (multi-core and GPU).

A little note, I’m rather proud of: Our lighting effects app “Shine” uses CoreImage, and it outperforms professional photoshop plugins which cost more. This is customer feedback, not my own tests. He’s just acquired a new Mac Pro.

The other way to color palette reduction, which is what I think you’re after, would be to create an array of colors of best match each pixel to those colors.

i.e.

distance = abs( testPixel.red - table( l ).red ) + abs( testPixel.green - table( l ).green ) + abs( testPixel.blue -table( l ).blue )
The one with the smallest distance is the closest match.

But what function in CoreImage would be used to create an 8bit indexed image from true color? Some posts I’ve found indicate it’s not supported, but I don’t know of their veracity

from http://cocoadev.com/ThresholdingImages
“Turns out that basically Cocoa/Quartz does not support downsampling images to 8-bit colour. It supports drawing them, and it supports upsampling, but not going the other way. I guess this is a deliberate design on Apple’s part to move away from indexed images as a standard graphics data type”

Choosing that array of colors is the hard part. Most of the time in the NeuroQuant algorithm is calculating what those colors should be. SIPS will create a 256 color table but I don’t see how to create lesser counts. It’s not what Dave’s after but if CoreImage can build sized color tables I’d rather use it.