6 Replies Latest reply on Jul 31, 2015 2:47 PM by colinj_blur

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

    colinj_blur

      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!

        • 1. Re: What's the fastest method for getting a count of unique colors in an image?
          colinj_blur Level 1

          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...

          • 2. Re: What's the fastest method for getting a count of unique colors in an image?
            colinj_blur Level 1

            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[i]) {

                                    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();

            • 3. Re: What's the fastest method for getting a count of unique colors in an image?
              c.pfaffenbichler Level 9

              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.

              • 4. Re: What's the fastest method for getting a count of unique colors in an image?
                colinj_blur Level 1

                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.

                • 5. Re: What's the fastest method for getting a count of unique colors in an image?
                  c.pfaffenbichler Level 9

                  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.)

                  • 6. Re: What's the fastest method for getting a count of unique colors in an image?
                    colinj_blur Level 1

                    Yes, it works when evaluating a .act file/colortable exported manually through the Photoshop UI. I needed a way to do this entirely through script. I ended up writing a script that executes an external python script that determines the unique color count insanely fast even on enormous images. I also have code that will, utilize xbytor's colortable.jsx in conjunction with my unique color counter code to write a color table out that ends up with the proper number of colors without and gif padding.

                     

                    I just need to clean it up, and have xbytor give it a once over to make sure i didn't do anything stupid, or unnecessary inefficient and I'll post it all here in a day or so.