• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to get list of all colors in an image?

Guest
Aug 12, 2015 Aug 12, 2015

Copy link to clipboard

Copied

How to get list of all colors in an image?

can we get 2-3 most frequently used colors in an image?

TOPICS
Actions and scripting

Views

7.9K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Aug 12, 2015 Aug 12, 2015

Copy link to clipboard

Copied

Personally I find your question extremely vague.

What exactly are you trying to achieve?

What kind of images are you trying to evaluate and to what end?

I think attempts to quantify colors in images have come up repeatedly on Photoshop Scripting Fora and you should do a Forum/web search.

Unfortunately ps-scripts.com is not operational anymore …

ps-scripts.com • Index page

One example that employs a very crude distinction:

// determine the mainly apparent color/s in an image;

// 2012, use at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

if (myDocument.mode == DocumentMode.RGB) {

// collect means of color ranges;

var theArray = new Array;

//get Red;

theArray.push(["red", getColorRangeHistogram ("Grn ", true, "Bl  ", true, "Rd  ", false)[0]]);

//get Yellow;

theArray.push(["yellow", getColorRangeHistogram ("Grn ", false, "Rd  ", false, "Bl  ", true)[0]]);

//get Green;

theArray.push(["green", getColorRangeHistogram ("Bl  ", true, "Rd  ", true, "Grn ", false)[0]]);

//get Cyan;

theArray.push(["cyan", getColorRangeHistogram ("Bl  ", false, "Grn ", false, "Rd  ", true)[0]]);

//get Blue;

theArray.push(["blue", getColorRangeHistogram ("Grn ", true, "Rd  ", true, "Bl  ", false)[0]]);

//get Magenta;

theArray.push(["magenta", getColorRangeHistogram ("Bl  ", false, "Rd  ", false, "Grn ", true)[0]]);

theArray.sort(sortByDate);

// compare values;

var sortedArray =  [[theArray[0][0]]];

for (var m = 1; m < theArray.length; m++) {

  var thePrevious = theArray[m - 1];

  var thisOne = theArray;

  if (thisOne[1] > thePrevious[1] - 2) {

  sortedArray[sortedArray.length - 1].push(thisOne[0])

  }

  else {

  sortedArray.push([thisOne[0]])

  }

  };

// get results;

var theString = new String;

for (var n = 0; n < sortedArray.length; n++) {

  var theseOnes = sortedArray;

  if (theseOnes.length > 1) {theString = theString + "Number " + (n + 1) + " colors are " + theseOnes.join(", ") + "\n"}

  else {theString = theString + "Number " + (n + 1) + " color is " + theseOnes[0] + "\n"};

  };

// get the overall mean;

var theMean = histogramMean(myDocument.histogram);

switch (Math.round(theMean[0] / 256 * 4)) {

  case 0: theBright = "very dark";

  break;

  case 1: theBright = "dark";

  break;

  case 2: theBright = "of medium brightness";

  break;

  case 3: theBright = "light";

  break;

  case 4: theBright = "very light";

  break;

  };

theString = theString + "\n\n the image appears to be " + theBright + ". ";

alert (theString);

};

};

////// get histogram  of channel operations //////

function getColorRangeHistogram (channel1, inverse1, channel2, inverse1, channel3, inverse3) {

var theChannel1 = channelOperation (channel1, inverse1, channel2, inverse1, "Drkn");

var theChannel = channelOperation (theChannel1, false, channel3, inverse3, "linearBurn");

theChannel1.remove();

var theHisto = theChannel.histogram;

app.activeDocument.selection.deselect();

theChannel.remove();

return histogramMean (theHisto)

};

////// channel operation //////

function channelOperation (channel1, inverse1, channel2, inverse2, theBlend) {

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc1 = new ActionDescriptor();

    var idNw = charIDToTypeID( "Nw  " );

    var idChnl = charIDToTypeID( "Chnl" );

    desc1.putClass( idNw, idChnl );

    var idUsng = charIDToTypeID( "Usng" );

        var desc2 = new ActionDescriptor();

        var idT = charIDToTypeID( "T  " );

if (channel1.constructor == String) {

            var ref1 = new ActionReference();

            var idChnl = charIDToTypeID( "Chnl" );

            var idChnl = charIDToTypeID( "Chnl" );

            var idGrn = charIDToTypeID( channel1 );

            ref1.putEnumerated( idChnl, idChnl, idGrn );

            var idLyr = charIDToTypeID( "Lyr " );

            var idOrdn = charIDToTypeID( "Ordn" );

            var idMrgd = charIDToTypeID( "Mrgd" );

            ref1.putEnumerated( idLyr, idOrdn, idMrgd );

        desc2.putReference( idT, ref1 );

  }

else {

  var ref2 = new ActionReference();

  var idChnl = charIDToTypeID( "Chnl" );

  ref2.putName( idChnl, channel1.name );

  desc2.putReference( idT, ref2 );

  };

        var idInvr = charIDToTypeID( "Invr" );

        desc2.putBoolean( idInvr, inverse1 );

        var idClcl = charIDToTypeID( "Clcl" );

        var idClcn = charIDToTypeID( "Clcn" );

if (theBlend.length > 4) {

        var idDrkn = stringIDToTypeID( theBlend );

  }

else {

        var idDrkn = charIDToTypeID( theBlend );

  };

        desc2.putEnumerated( idClcl, idClcn, idDrkn );

        var idSrctwo = charIDToTypeID( "Src2" );

            var ref2 = new ActionReference();

            var idChnl = charIDToTypeID( "Chnl" );

            var idChnl = charIDToTypeID( "Chnl" );

            var idBl = charIDToTypeID( channel2 );

            ref2.putEnumerated( idChnl, idChnl, idBl );

            var idLyr = charIDToTypeID( "Lyr " );

            var idOrdn = charIDToTypeID( "Ordn" );

            var idMrgd = charIDToTypeID( "Mrgd" );

            ref2.putEnumerated( idLyr, idOrdn, idMrgd );

        desc2.putReference( idSrctwo, ref2 );

        var idInvS = charIDToTypeID( "InvS" );

        desc2.putBoolean( idInvS, inverse2 );

    var idClcl = charIDToTypeID( "Clcl" );

    desc1.putObject( idUsng, idClcl, desc2 );

executeAction( idMk, desc1, DialogModes.NO );

return app.activeDocument.channels[app.activeDocument.channels.length - 1];

};

////// get mean of histogram //////

function histogramMean (theHist) {

// get total number;

var thePixels = 0;

for (var m = 0; m < theHist.length; m++) {

  thePixels = thePixels + theHist

  };

// get mean and median;

var theMean = 0;

var aTotal = 0;

var check = false;

for (var n = 0; n < theHist.length; n++) {

  theMean = theMean + (n * theHist / thePixels);

  aTotal = aTotal + theHist;

  if (aTotal >= thePixels / 2 && check == false) {

  theMedian = n;

  check = true;

  }

  };

// get standard deviation;

var theStandDev = 0;

for (var o = 0; o < theHist.length; o++) {

  theStandDev = theStandDev + (Math.pow ((o - theMean), 2) * theHist)

  };

theStandDev = Math.sqrt (theStandDev / thePixels);

//

return ([theMean, theMedian, theStandDev]);

//alert (thePixels + " pixels\n" + theMean + " mean\n" + theMedian + " median\n" + theStandDev + " standard deviation")

};

////// to sort a double array based on script by sam, http://www.rhinocerus.net/forum/lang-javascript/ //////

function sortByDate(a,b) {

if (a[1]<b[1]) return 1;

if (a[1]>b[1]) return -1;

return 0;

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

I am not able to search anything in the link you suggested.

and also this script is giving illegal argument error at line number 79

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

and also this script is giving illegal argument error at line number 79

Recurring problem I have with this Forum, "T  " should have three spaces.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

But this is not what I asked.  Like in this image red and white is appearing mostly. I wanted RGB value which appeared most frequently in  images

images.jpg.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

But this is not what I asked.

And I already stated that your question seemed unclear and asked for you to clarify.

But you originally did not react to that.

And even now your intended task seems unclear to me.

In this example 255/255/255 would probably the RGB color that the largest number of pixels share – would this be the result you want?

What result would you expect for this image exactly (and for a couple of further examples maybe)?

Maybe you should look into indexed colors.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

I was asking for most dominant color? you want me to clear more?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

Yellow is the most dominant color in this pic,, input will be image and output will be most frequent RGB.

10080front-0.jpg

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 14, 2015 Aug 14, 2015

Copy link to clipboard

Copied

Photoshop Scripting can largely be considered as automating Photoshop tasks with the possibility of automated input and evaluation – if a task can not be broken down to specific Photoshop (or File-specific or mathematic …) operations it may not be possible to (efficiently) Script it.

If you want to only evaluate regions in an image that are above a certain Saturation threshold you need to figure out how to filter out that information.

Why RGB values anyway? Would Lab work, too, maybe?

Maybe you should explain what you are ultimately trying to achieve with this.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

you want me to clear more?

Yes.

Maybe you do not appreciate that "color" can carry more than one meaning.

I was asking for most dominant color?

In that example that would be 255/255/255 – is that really the result you wanted?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 13, 2015 Aug 13, 2015

Copy link to clipboard

Copied

Sorry, sloppy reading on my part.

What exactly do you mean by "color" really?

The most frequent RGB color in the example with the yellow shirt would again probably be 255/255/255, so if you want to automate the process you may have to define your terms more precisely.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 15, 2015 Aug 15, 2015

Copy link to clipboard

Copied

So I did a pixel by pixel evaluation of the RGB image with the apple (and it was as expected pretty time-consuming) and determined the most used RGB colors in the image.

The top six are

255,255,255 with 26847 pixels

255,254,255 with 408 pixels

254,255,255 with 354 pixels

254,254,254 with 299 pixels

255,253,255 with 241 pixels

252,255,255 with 201 pixels

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Aug 15, 2015 Aug 15, 2015

Copy link to clipboard

Copied

Yes this is exactly what I want to achieve. Please share your script. I will try to optimize it for better efficiency.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 16, 2015 Aug 16, 2015

Copy link to clipboard

Copied

Once again:

Why RGB values? Would Lab work?

Paul Riggott has posted a Script a while back that uses the Raw format to get the Lab values for all pixels pretty fast, so that might improve the efficiency considerably.


Here is some code, but consider that the Color Sampler Tool needs to be set to Point Sample and that the color sampler approach is not fast.

Even when downsampling the image (the "apple" one in this case) to 59px by 54px the operation takes roughly 2 minutes here.

// 2015, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

// get start time;

var time1 = Number(timeString());

var theString = new String;

app.activeDocument.colorSamplers.removeAll();

var theSampler = app.activeDocument.colorSamplers.add([0.5,0.5]);

// move color sampler;

for (var y = 0; y < app.activeDocument.height; ++y) {

for (var x = 0; x < app.activeDocument.width; ++x) {

// =======================================================

var idmove = charIDToTypeID( "move" );

    var desc4 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref2 = new ActionReference();

        var idClSm = charIDToTypeID( "ClSm" );

        ref2.putIndex( idClSm, 1 );

    desc4.putReference( idnull, ref2 );

    var idT = charIDToTypeID( "T  " );

        var desc5 = new ActionDescriptor();

        var idHrzn = charIDToTypeID( "Hrzn" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc5.putUnitDouble( idHrzn, idPxl, x+0.5 );

        var idVrtc = charIDToTypeID( "Vrtc" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc5.putUnitDouble( idVrtc, idPxl, y+0.5 );

    var idPnt = charIDToTypeID( "Pnt " );

    desc4.putObject( idT, idPnt, desc5 );

executeAction( idmove, desc4, DialogModes.NO );

// add the value to the string;

theString = theString + String(Math.round(theSampler.color.rgb.red))+","+String(Math.round(theSampler.color.rgb.green))+","+String(Math.round(theSampler.color.rgb.blue))+";";

}

};

////////////////////////////////////

//var theString = readPref ("~/Desktop/test.txt");

// collect values; from string

var theResult = new Array;

while (theString.length > 1) {

var theNumber = 0;

var theValue = theString.slice(0, theString.indexOf(";")+1);

while (theString.indexOf(theValue) != -1) {

theString = theString.replace(theValue, "");

theNumber++

$.writeln("___"+theValue+"___"+theNumber);

};

theResult.push([theValue.slice(0,-1), theNumber])

};

////////////////////////////////////

theResult.sort(sortArrayByIndexedItem);

var time2 = Number(timeString());

alert ("the operation took "+((time2-time1)/1000)+" seconds\nthe colors and their numbers are\n"+theResult.join("\n"));

};

////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////

function sortArrayByIndexedItem(a,b) {

var theIndex = 1;

if (a[theIndex]>b[theIndex]) return -1;

if (a[theIndex]<b[theIndex]) return 1;

return 0;

};////// read prefs file //////

////// function to get the date //////

function timeString () {

  var now = new Date();

  return now.getTime()

  };

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 09, 2016 Dec 09, 2016

Copy link to clipboard

Copied

I was asking for most dominant color? you want me to clear more?

Yes this is exactly what I want to achieve. Please share your script. I will try to optimize it for better efficiency.

A bit rude in my opinion man. c.pfaffenbichler​ is helping you, using his free time. If you had shown an example in the original post of the source and output needed, you would have gotten a faster and more accurate response. And you wouldn't have wasted his time helping you.

Now, about the question. I've been looking for an alternative for getLayerPixmap directly in ExtendScript, but there might not be one, unfortunately.

The way I see it, there are 2 methods. One through a CEP panel. You can load an image on your local setup and obtain its pixels through Canvas and analyze them. You will have an array of pixels like this, if I'm not mistaken [ [r,g,b,a], [r,g,b,a], .... ]. This is probably the method used in the link that raunaqsingh​ posted.

Another way is to use Generator​ and create a small plugin to obtain the pixmap. You can use Generator's getLayerPixmap function.

I also made a similar approach with the color sampler, and indeed, was very slow.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 21, 2015 Aug 21, 2015

Copy link to clipboard

Copied

And …?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 07, 2016 Dec 07, 2016

Copy link to clipboard

Copied

has anyone found a solution to this?

Basically, i am looking for something similar to this in photoshop script,

Color Thief

I want a script that extracts the color pixel value that repeats most in an image and fill a new canvas with that color and save it as a JPG.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 09, 2016 Dec 09, 2016

Copy link to clipboard

Copied

I have a PS solution that will give you a ranked percentage of colours within an image which runs in 5.3 seconds. It does reduce the stored dimensions of the image to 125px on the long-side though so there will be some slight inaccuracy regarding the true pixel count of the original image which is why it expresses the counts as percentages.

Let me know if you're interested in that.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 05, 2017 Jan 05, 2017

Copy link to clipboard

Copied

LATEST

Duplicate the background layer, go to, Filter--->Blur--->Average.

This will be the median of your image and also the most abundant color.

you can also use this color to white balance the image with the center eyedropper of a levels adjustment layer.

Hope this help.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines