Skip to main content
August 13, 2015
Question

How to get list of all colors in an image?

  • August 13, 2015
  • 7 replies
  • 10542 views

How to get list of all colors in an image?

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

This topic has been closed for replies.

7 replies

Participant
January 6, 2017

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.

Inspiring
December 9, 2016

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.

Participant
December 8, 2016

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.

c.pfaffenbichler
Community Expert
Community Expert
August 21, 2015

And …?

c.pfaffenbichler
Community Expert
Community Expert
August 15, 2015

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

August 15, 2015

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

c.pfaffenbichler
Community Expert
Community Expert
August 16, 2015

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

  };

c.pfaffenbichler
Community Expert
Community Expert
August 13, 2015

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.

c.pfaffenbichler
Community Expert
Community Expert
August 13, 2015

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;

};

August 13, 2015

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

c.pfaffenbichler
Community Expert
Community Expert
August 13, 2015

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.