Skip to main content
colinj_blur
Participating Frequently
July 29, 2015
Question

What's the fastest method for getting a count of unique colors in an image?

  • July 29, 2015
  • 2 replies
  • 1009 views

Hi all!

I'm trying to do a bunch of stuff with indexed color tables, saving to gif, loading the colors in from the gif and going from there... the issue is that gif will pad the color table to powers of 2, so if I only had 5 colors in my image, the color table i'm getting from the gif i've saved will be 8...

I'd like to know/determine the number of colors in an image before I do all of the other stuff, but I'm not sure what the fastest way to do this in PS scripting is, and would love any suggestions! The source image will always already be in indexed color if that matters.

Thanks!

This topic has been closed for replies.

2 replies

c.pfaffenbichler
Community Expert
Community Expert
July 30, 2015

Adding posts to one’s one query when no one else has reacted can be a bit off-putting as one might assume the issue has already been dealt with.

With the help of xbytor’s ColorTable.jsx it should be possible to determine the number of color’s in an indexed color image.

colinj_blur
Participating Frequently
July 30, 2015

Agreed, but I didn't realize how to edit posts until i'd already added 2

I tried the xbytor stuff, and got that working, in fact he's been insanely helpful and patient with me... the issue though, and the reason I need the unique color count in the first place is part of his methodology is saving a temporary gif file, and streaming in the color table from there. The problem with that is that gif's being an ancient format, only save the color table length as powers of 2, so if I have 5 colors in my color table, it'll pad it with 8 colors, and the result is inaccurate. If I had the unique color count ahead of time, I could truncate the result from xbytor's tools to the correct length.

c.pfaffenbichler
Community Expert
Community Expert
July 31, 2015

When using

ColorTable.main = function() { 

  var clrTbl = new ColorTable();

  var theFile = selectFile (false);

  clrTbl.readFromFile(theFile);

  return clrTbl

};

to evaluate an exported Color Table I get the correct number of colors.  (readFromFile refers to another function from ColorTable.jsx so this alone would not work.)

colinj_blur
Participating Frequently
July 29, 2015

Couple of things, photoshop does this very quickly when converting from an RGB document to an indexed one, the dialog that pops up lists the number of colors in the image, I just don't know how to access that information via scripting.  

Also I found this plugin: Telegraphics - Free plugins for Photoshop & Illustrator...and other software that does it, but I believe it's written in C and I don't know how to determine what technique its using to get its result as its all greek to me...

colinj_blur
Participating Frequently
July 30, 2015

Ok, so I figured out some code that works, but using the colorSampler across every pixel in an image is INSANELY / PROHIBITIVELY slow... like it can only analyze 18.8 pixels / sec. That's not going to work for a print resolution image. There's got to be a better method right?

#target photoshop

function main() {

    if (app.documents.length == 0) {

        alert("Please open a document before running this script.");

        return;

    }

    // CODE HERE

    var defaultRulerUnits = preferences.rulerUnits; // Note the current  units for the document

    preferences.rulerUnits = Units.PIXELS; // switch units to pixels

    var doc = app.activeDocument

    var docW = app.activeDocument.width.value;

    var docH = app.activeDocument.height.value;

    app.activeDocument.colorSamplers.removeAll();

       //var docW = 5; // for faster testing

       //var docH = 2;  // for faster testing

    var uniqueClrArray = [];

 

    var  lastColor ="xxxxxx";

    var sampler = doc.colorSamplers.add([0, 0]);

    var d = new Date();

    var n = d.getTime();

 

    $.writeln("Starting...  "+n);

 

    for (var y = 0; y < docH; ++y) {

        for (var x = 0; x < docW; ++x) {

            sampler.move([x+0.5, y+0.5]);

            var pxClr = sampler.color.rgb.hexValue;

            if (pxClr != lastColor) {

                var found = false;

                for (var i = 0; i <= uniqueClrArray.length; ++i) {

                    if (pxClr == uniqueClrArray) {

                        lastColor = pxClr;

                        found = true;

                        break;

                    }

                }

                if (!found) {

                 //   $.writeln("Adding pxClr to array");

                    lastColor = pxClr;

                    uniqueClrArray.push(pxClr);

                }

            }

          //  $.writeln("X: " + x + " Y: " + y + "      Hex: " + sampler.color.rgb.hexValue);

        }

    }

   // var uniqueColorTotal = uniqueClrArray.length + 1;

    $.writeln("Unique color count: " + uniqueClrArray.length);

    // END CODE HERE

   d = new Date();

   var x = d.getTime();

   $.writeln( (x-n)/1000 + " sec");

   return null;

}

main();