Skip to main content
Inspiring
February 21, 2025
Question

Script to select foreground color by color name

  • February 21, 2025
  • 3 replies
  • 428 views

Hello, is it possible to select foreground color from the swathes panel by color name , using script?

3 replies

c.pfaffenbichler
Community Expert
Community Expert
February 23, 2025

Maybe this is closer to what you want. 

The »preferences«-file would not be necessary per se, but it would allow for changing, adding, deleting colors »easily«; in this example there are four colors to rotate through. 

And obviously you should decide on where you would prefer to keep the file and its name. 

// set foregroundcolor by circling through array;
// 2025, use it at your own risk;
// read file and get the colors;
var theFile = "~/Desktop/bbb.txt";
if (File(theFile).exists == true) {
var theArray = (readPref (theFile)).split("\r");
for (var a = 0; a < theArray.length; a++) {
theArray[a] = theArray[a].split(",")
};
}
else {
var theArray = [[128,128,128], [0,255,255], [255,255,255], [0,0,0]];
};
// get current color;
var current = [Math.round(app.foregroundColor.rgb.red), Math.round(app.foregroundColor.rgb.green), Math.round(app.foregroundColor.rgb.blue)];
// check color;
var theCheck = false;
var theCounter = 0;
while (theCheck == false && theCounter < theArray.length) {
if (current.join(",") == theArray[theCounter].join(",")) {
if (theCounter == theArray.length-1) {var theNext = 0}
else {var theNext = theCounter+1};
setColor (theArray[theNext]);
theCheck = true
};
theCounter++
};
if (theCheck == false) {setColor (theArray[0])};
// create file;
if (File(theFile).exists == false) {writePref (theArray.join("\r"), theFile)};
alert ("done");
////// read prefs file //////
function readPref (thePath) {
if (File(thePath).exists == true) {
var file = File(thePath);
file.open("r");
file.encoding= 'BINARY';
var theText = new String;
for (var m = 0; m < file.length; m ++) {
theText = theText.concat(file.readch());
};
file.close();
return String(theText)
}
};
////// function to write a preference-file storing a text //////
function writePref (theText, thePath) {
try {
var thePrefFile = new File(thePath);
thePrefFile.open("w");
for (var m = 0; m < theText.length; m ++) {
thePrefFile.write(theText[m])
};
thePrefFile.close()
}
catch (e) {};
};
////// set foreground color //////
function setColor (theArray) {
var desc4 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty( stringIDToTypeID( "color" ), stringIDToTypeID( "foregroundColor" ) );
desc4.putReference( stringIDToTypeID( "null" ), ref1 );
var desc5 = new ActionDescriptor();
desc5.putDouble( stringIDToTypeID( "red" ), theArray[0] );
desc5.putDouble( stringIDToTypeID( "grain" ), theArray[1] );
desc5.putDouble( stringIDToTypeID( "blue" ), theArray[2] );
desc4.putObject( stringIDToTypeID( "to" ), stringIDToTypeID( "RGBColor" ), desc5 );
desc4.putString( stringIDToTypeID( "source" ), "photoshopPicker" );
executeAction( stringIDToTypeID( "set" ), desc4, DialogModes.NO );
};
Zipo4323Author
Inspiring
February 23, 2025

Thank you very much for your help, c.pfaffenbichler!

Sorry I couldn't answer earlier. This isn't exactly what I needed. I guess my explanation wasn't that good.

But I found some scripts on the forum and learned that you can name the swatches with their hex values ​​and then paste those values ​​into the foreground color.

Here is the script . If foreground color is black or white the script will switch only these colors. If it is another color then it will switch between three colors.

 

 

IT WORKS CORRECTLY ONLY WITH AN EMPTY SWATCHES PANEL!

 

#target photoshop

var foreColor = new SolidColor();
foreColorH=app.foregroundColor.hsb.hue; 
foreColorS=app.foregroundColor.hsb.saturation;
foreColorB=app.foregroundColor.hsb.brightness;

if (foreColorS !== 0 && foreColorB !== 100 || foreColorS !== 0 && foreColorB !== 0) {
    var hexColor = foregroundColor.rgb.hexValue;
    if (countSwatches()<1||swatchName()!==hexColor){
        addToSwatches();
        }
    if (countSwatches()>1){
        deleteSwatch();
        }
    foreColor.hsb.hue=foreColorH+0;
    foreColor.hsb.saturation = 0;
    foreColor.hsb.brightness = 0;
    app.foregroundColor = foreColor;
}else if (foreColorS == 0 && foreColorB == 0) {
    foreColor.hsb.hue=foreColorH+0;
    foreColor.hsb.saturation = 0;
    foreColor.hsb.brightness = 100;
    app.foregroundColor = foreColor;
}else if (countSwatches()<1 && foreColorS == 0 && foreColorB == 100){
    foreColor.hsb.hue=foreColorH+0;
    foreColor.hsb.saturation = 0;
    foreColor.hsb.brightness = 0;
    app.foregroundColor = foreColor;
}else{
    foregroundColor.rgb.hexValue = swatchName();
}

function countSwatches() {
    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("presetManager"));
    r.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    var list = executeActionGet(r).getList(stringIDToTypeID("presetManager")).getObjectValue(1).getList(stringIDToTypeID("name"));
    return list.count
}

function addToSwatches() {
var idMk = charIDToTypeID( "Mk  " );
    var desc37422 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref347 = new ActionReference();
        var idClrs = charIDToTypeID( "Clrs" );
        ref347.putClass( idClrs );
    desc37422.putReference( idnull, ref347 );
    var idUsng = charIDToTypeID( "Usng" );
        var desc37423 = new ActionDescriptor();
        var idNm = charIDToTypeID( "Nm  " );
        desc37423.putString( idNm, hexColor );
        var idIdnt = charIDToTypeID( "Idnt" );
        desc37423.putString( idIdnt, """1bcf8def-21de-6044-8176-b8a092b5dfcb""" );
        var idCCid = charIDToTypeID( "CCid" );
        desc37423.putString( idCCid, """""" );
        var idClr = charIDToTypeID( "Clr " );
            var desc37424 = new ActionDescriptor();
            var idH = charIDToTypeID( "H   " );
            var idAng = charIDToTypeID( "#Ang" );
            desc37424.putUnitDouble( idH, idAng, foreColorH );
            var idStrt = charIDToTypeID( "Strt" );
            desc37424.putDouble( idStrt, foreColorS );
            var idBrgh = charIDToTypeID( "Brgh" );
            desc37424.putDouble( idBrgh, foreColorB );
        var idHSBC = charIDToTypeID( "HSBC" );
        desc37423.putObject( idClr, idHSBC, desc37424 );
    var idClrs = charIDToTypeID( "Clrs" );
    desc37422.putObject( idUsng, idClrs, desc37423 );
    var idpushToDesignLibraries = stringIDToTypeID( "pushToDesignLibraries" );
    desc37422.putBoolean( idpushToDesignLibraries, false );
executeAction( idMk, desc37422, DialogModes.NO );
}

function swatchName() {
    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("presetManager"));
    r.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    var list = executeActionGet(r).getList(stringIDToTypeID("presetManager")).getObjectValue(1).getList(stringIDToTypeID("name"));
    var sName = list.getString(0);
    return sName;
}

function deleteSwatch() {
    var r = new ActionReference();
        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("presetManager"));
        r.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        var list = executeActionGet(r).getList(stringIDToTypeID("presetManager")).getObjectValue(1).getList(stringIDToTypeID("name"));        
        if (list.count > 0) {
            var idDlt = charIDToTypeID( "Dlt " );
            var ad1 = new ActionDescriptor();
            var idnull = charIDToTypeID( "null" );
            var ref5 = new ActionReference();
            var idClrs = charIDToTypeID( "Clrs" );
            ref5.putIndex( idClrs, 1 );
            ad1.putReference( idnull, ref5 );
            executeAction( idDlt, ad1, DialogModes.NO );
            }
}

 

c.pfaffenbichler
Community Expert
Community Expert
February 24, 2025

I guess I misunderstood the issue. 

c.pfaffenbichler
Community Expert
Community Expert
February 21, 2025

Sorry I encouraged your hopes – I hadn’t considered that Swatches are a bit of a clunk in EXTK-Scripting. 

Maybe someone with UXP-Scripting-chops can offer a solution … 

 

In ESTK-Scripting one can certainly check if a Swatch of a certain name exists, but using its color values would, as far as I can tell, necessitate reading the aco-data.  

Hopefully someone else has a better idea. 

 

What role does this play in your workflow? 

Could you store the color-values in another form? 

 

edited 

 

// 2025, use it at your own risk;
var theCheck = true;
var theSwatches = collectSwatches ();
var theCheck = false;
var theCount = 0;
while  (theCheck == false && theCount < theSwatches.length) {
if (theSwatches[theCount] == "Main") {
alert ("swatch »Main« exists at "+theCount)
theCheck = true
};
theCount++
};
////////////////////////////////////
////// based on mike hale’s code //////
function collectSwatches () {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var desc = executeActionGet(ref);// get the app descriptor
var presetsList = desc.getList(stringIDToTypeID('presetManager'));// the presets list
var swatchDesc = presetsList.getObjectValue(1);// swatches is the second key
var nameList = swatchDesc.getList(charIDToTypeID("Nm  "));// there is only one key in the swatch descriptor so get the list
var theNames = new Array;
for (var m = 0; m < nameList.count; m++) {
theNames.push(nameList.getString(m))
};
return theNames;
};

 

 

Zipo4323Author
Inspiring
February 21, 2025

The main script I was trying to make was switching between three foreground colors (some color, then white and then black). For example if the current foreground color is green, I need the script to somehow remember that color, then when I rerun the script it should switch to white, then black and then back to green etc. If the current color is black or white then the script should not remember them. The solution I came up with was to make a script that puts that color in the swatches panel, gives it the name "Main" for example, and then take it from there. If I changed the foreground color, for example from green to red, and ran the script, it should remove the green and add the red to the swatches panel. the background color should not be used. Hope I explained it clearly) Maybe there is a simpler solution?

c.pfaffenbichler
Community Expert
Community Expert
February 22, 2025

I would recommend writing a preferences-file that stores the index of the current color in an array of colors, something like this (though I may not have fully understood your intended workflow): 

// 2025, use it at your own risk;
// the colors;
var theArray = [[128,128,128], [255,255,255], [0,0,0]];
// read file;
var theFile = "~/Desktop/aaa.txt";
if (File(theFile).exists == true) {var theNumber = Number(readPref (theFile))}
else {var theNumber = 0};
if (theNumber == theArray.length-1) {var theNext = 0}
else {var theNext = theNumber + 1};
// get color;
var current = [Math.round(app.foregroundColor.rgb.red), Math.round(app.foregroundColor.rgb.green), Math.round(app.foregroundColor.rgb.blue)];
// check colors;
if (current.join(",") == theArray[theNumber].join(",")) {
setColor (theArray[theNext]);
writePref (String(theNext), theFile)
} else {
setColor (theArray[0])
writePref (String(0), theFile);
};
alert ("done");
////// read prefs file //////
function readPref (thePath) {
if (File(thePath).exists == true) {
var file = File(thePath);
file.open("r");
file.encoding= 'BINARY';
var theText = new String;
for (var m = 0; m < file.length; m ++) {
theText = theText.concat(file.readch());
};
file.close();
return String(theText)
}
};
////// function to write a preference-file storing a text //////
function writePref (theText, thePath) {
try {
var thePrefFile = new File(thePath);
thePrefFile.open("w");
for (var m = 0; m < theText.length; m ++) {
thePrefFile.write(theText[m])
};
thePrefFile.close()
}
catch (e) {};
};
////// set foreground color //////
function setColor (theArray) {
var idset = stringIDToTypeID( "set" );
    var desc4 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref1 = new ActionReference();
        var idcolor = stringIDToTypeID( "color" );
        var idforegroundColor = stringIDToTypeID( "foregroundColor" );
        ref1.putProperty( idcolor, idforegroundColor );
    desc4.putReference( idnull, ref1 );
    var idto = stringIDToTypeID( "to" );
        var desc5 = new ActionDescriptor();
        var idred = stringIDToTypeID( "red" );
        desc5.putDouble( idred, theArray[0] );
        var idgrain = stringIDToTypeID( "grain" );
        desc5.putDouble( idgrain, theArray[1] );
        var idblue = stringIDToTypeID( "blue" );
        desc5.putDouble( idblue, theArray[2] );
    var idRGBColor = stringIDToTypeID( "RGBColor" );
    desc4.putObject( idto, idRGBColor, desc5 );
    var idsource = stringIDToTypeID( "source" );
    desc4.putString( idsource, "photoshopPicker" );
executeAction( idset, desc4, DialogModes.NO );
};

 

c.pfaffenbichler
Community Expert
Community Expert
February 21, 2025

What do you have in mind? 

A dialog with a text-entry-field, a dropdown list, …? 

Or is the name to be evaluated from a layer’s name or …? 

Zipo4323Author
Inspiring
February 21, 2025

Thanks for the quick reply! If there is a color with some name ("Main" for example) in the swatch panel,  I need the script to select it as the foreground color. Without dialog boxes, drop-down lists, etc. Sorry for my English if I made a mistake.