Copy link to clipboard
Copied
Hey fam,
I want an script when selected (Vector shapes, solid color layers) I can set a color a from the psd itself as picking one of the squares below
bottom left are the color codes suggested,
I already have the script to sort/filter the layers I want but I would like someway it picks the color from the bottom color chart and fill all selected layers.
Thanks Fam
There's not much for me to go by.
So here are some general links that may or may not help depending on the file setup:
// Script to change color on all selected layers supports solid, shape, text and artlayers
var doc;
if (app.documents.length <= 0) {
alert("No active document!");
} else {
doc = app.activeDocument;
doc.s
Give this script a go:
/*
Recolour Colour Label Layers from Palette Swatches.jsx
v1.0 - 7th August 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-change-fill-color-layer/td-p/14778076
*/
#target photoshop
/***** Stage 1 - Get the colour palette swatches *****/
// Hide the Photoshop panels
app.togglePalettes();
// Select the colour palette layer
app.activeDocument.activeLayer = app.activeDocument.layers.getByName('COLORPALETTE');
// E
...
Copy link to clipboard
Copied
A layered PSD file and example images of the final output colour combinations would be helpful.
Are the reference colour swatches always in the same pixel location? There are 3 colours, however the base yellow colour isn't shown.
Copy link to clipboard
Copied
Yes, swatches will always in the same pixel location
(Sorry about the Yellow It was a test)
Here's the final result
Most of the time I used two colors, however, I would like to set in the script manager to colors based on layer colored.
For now all of them are red (you helped me with that script "Redlabeled")
Copy link to clipboard
Copied
There's not much for me to go by.
So here are some general links that may or may not help depending on the file setup:
// Script to change color on all selected layers supports solid, shape, text and artlayers
var doc;
if (app.documents.length <= 0) {
alert("No active document!");
} else {
doc = app.activeDocument;
doc.suspendHistory("Set Color On Selected", "ChangeLayerColors();");
}
function ChangeLayerColors() {
if (app.showColorPicker()) {
var color = app.foregroundColor.rgb;
var selectedLayers = getSelectedLayersIndices();
var normalLayers = [];
var invisibleLayers = [];
for (var i = 0; i < selectedLayers.length; i++) {
selectLayerByIndex( selectedLayers[i], false)
if (!doc.activeLayer.visible) {
invisibleLayers.push(doc.activeLayer);
}
if (doc.activeLayer.kind == LayerKind.SOLIDFILL) {
setSolidFillColor(color);
} else if (doc.activeLayer.kind == LayerKind.TEXT) {
var textColor = new SolidColor();
textColor.rgb.red = color.red;
textColor.rgb.green = color.green;
textColor.rgb.blue = color.blue;
doc.activeLayer.textItem.color = textColor;
} else if (doc.activeLayer.kind == LayerKind.NORMAL) {
normalLayers.push(doc.activeLayer);
}
}
for (var i = 0; i < normalLayers.length; i++) {
doc.activeLayer = normalLayers[i];
fillWithColor(color);
}
for (var i = 0; i < invisibleLayers.length; i++) {
doc.activeLayer = invisibleLayers[i];
doc.activeLayer.visible = false;
}
}
for (var i = 0; i < selectedLayers.length; i++) {
selectLayerByIndex(selectedLayers[i], true);
}
}
function fillWithColor(color) {
doc.selection.selectAll();
if (doc.activeLayer.visible === false) {
doc.activeLayer.visible = true;
doc.selection.fill(color, ColorBlendMode.NORMAL, 100, true);
doc.selection.deselect();
doc.activeLayer.visible = false;
} else {
doc.selection.fill(color, ColorBlendMode.NORMAL, 100, true);
doc.selection.deselect();
}
}
function setSolidFillColor(color) {
var color = app.foregroundColor.rgb;
var idsetd = charIDToTypeID("setd");
var desc1 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
var ref = new ActionReference();
var idcontentLayer = stringIDToTypeID("contentLayer");
var idOrdn = charIDToTypeID("Ordn");
var idTrgt = charIDToTypeID("Trgt");
ref.putEnumerated(idcontentLayer, idOrdn, idTrgt);
desc1.putReference(idnull, ref);
var idT = charIDToTypeID("T ");
var desc2 = new ActionDescriptor();
var idClr = charIDToTypeID("Clr ");
var desc3 = new ActionDescriptor();
var idRd = charIDToTypeID("Rd ");
desc3.putDouble(idRd, color.red);
var idGrn = charIDToTypeID("Grn ");
desc3.putDouble(idGrn, color.green);
var idBl = charIDToTypeID("Bl ");
desc3.putDouble(idBl, color.blue);
var idRGBC = charIDToTypeID("RGBC");
desc2.putObject(idClr, idRGBC, desc3);
var idsolidColorLayer = stringIDToTypeID("solidColorLayer");
desc1.putObject(idT, idsolidColorLayer, desc2);
executeAction(idsetd, desc1, DialogModes.NO);
}
function getSelectedLayersIndices(){
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
var c = desc.count
var selectedLayers = new Array();
for(var i=0;i<c;i++){
try{
activeDocument.backgroundLayer;
selectedLayers.push( desc.getReference( i ).getIndex() );
}catch(e){
selectedLayers.push( desc.getReference( i ).getIndex()+1 );
}
}
}else{
var ref = new ActionReference();
ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
try{
activeDocument.backgroundLayer;
selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))-1);
}catch(e){
selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));
}
}
return selectedLayers;
}
function selectLayerByIndex(index,add){
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) {
desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) )
}
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){}
}
And:
Copy link to clipboard
Copied
This is fair enough @Stephen_A_Marsh Thanks. Maybe I'm asking for too much on this one since when I was recording and action it couldn't save the position of the color picker "Set is not available" or something like that displayed. I'm reviewing the static script from the link above. It's a pretty reduction of steps tho.
Copy link to clipboard
Copied
It's not that you're asking too much, it's that (at least for me) your screenshots and text descriptions are not enough for me to offer better advice or help. This is why I asked for a sample layered file and examples of the final output.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
On the colour palette in the lower left, it's currently a linked layer, however, I have no idea how the linked file is structured as I don't have access to that linked file.
To get the colours out of the linked file, if it's a Photoshop-compatible file, then the SO could be opened and edited to get the colours for each swatch. Possibly cycling through the layers depending on how they are constructed, or by X:Y pixel coordinates and colour samplers if these were consistent. It would all depend on the structure.
Otherwise, if the swatches were always in a consistent size and position, then a script could use X:Y pixel coordinates and colour samplers to get the colours.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
How will the 3 colour swatches be matched to the layers?
By layer name?
By layer colour label?
The clothing is created from a mixture of pixel layers, solid fill/shape layers and embedded smart object layers.
The smart objects also contain solid fill/shape layers as well. Do these also require re-colouring based on the swatches?
Copy link to clipboard
Copied
Should be easier by label so I can label up to 4 colors.
And yes, Smart objects (solid fill/shape layers) should be able re-colouring based on the swatches.
There's a bunch of layers on the PSD file so I would say it's better match layers base on layer colour label, so when edit the file I can remove label from layer.
Let me know your thoutghs
Notes: as you can see in the image below there's a sample set of clothing so if there's a note for X:Y pixel coordinates that I can change manually for each file, I don't know how would be better.
Best Regards
Copy link to clipboard
Copied
As the linked smart object for the colour labels uses separate LayerKind.SOLIDFILL layers, it's possible to retrieve the colour values directly from the layer without using colour samplers. I don't have code at hand to so though and I'm guessing that CMYK is less common than RGB or Hex. Another option would be use use the text content from the details group and use those values to retrieve the colour information.
So there are multiple ways to get the target colour from each colour label swatch. This shouldn't be a roadblock.
So the next thing would be to have the script match up the primary, secondary and tertiary colour label value with each layer, edit the corresponding layers and recolour based on the known colour label values.
Copy link to clipboard
Copied
We can use Hex, CMYK is more for production. I updated the linked file and sample clothing PSD, the linked file position might change in other clothing files but I can fix a position for the others if necessary.
Every fill/colorshape layer was re-coloured:
Best regards.
Copy link to clipboard
Copied
@Stephen_A_Marsh Will be any luck on this?
Copy link to clipboard
Copied
Possibly, but it's not a 5-minute exercise.
I can't get the fill colour of the colour label directly, so I'll need to use colour samplers instead.
I'll look at the new PSD files. Can you post a JPEG of the design with new colour labels and colours so that I can look at reproducing the result?
Copy link to clipboard
Copied
I know this is a bit challenging, If I was a scripter I'd be kinda curious
For sure, let me know if this helps.
Copy link to clipboard
Copied
Yes, that was my next question!
Layer label colours:
Orange = 1/Primary colour palette
Red = 2/Secondary colour palette
Yellow = 3/Tertiary colour palette
Copy link to clipboard
Copied
Yeah, That's right.
Copy link to clipboard
Copied
The first part of the script is about getting the primary, secondary and tertiary colour swatch values. So now that I look at the two swatch files:
COLORPALETTE_TEMP.psd (original)
Sample-2.psd (latest)
They both have very different layer group and layer structures.
Which is the correct final one?
Will you change any layer group or layer names or stacking order (i.e. to tidy them up). I can't hit a moving target so I need to know that this isn't going to change.
I have created code to get the CMYK values from each of the 3 swatches based on the COLORPALETTE_TEMP.psd structure, however, if this is going to be based on Sample-2.psd then I will need to change the code to support the new layer structure. I don't wish to do this yet another time if you decide to tidy things up or make further changes. This needs to be set in place before the rest of the script is coded to change the layer colours.
I also need you to decide on the filename of the swatch file as the script will be selecting this smart object layer by name. Otherwise, the script can select the layer based on its position in the layer stack, in your latest example this is the very top layer.
Copy link to clipboard
Copied
I see, you can go ahead and proceed with COLORPALETTE_TEMP.psd (original), however, I uploaded the
Sample-2.psd (latest) in case you need the Hex Code, whatever it's easier for you would be fine. If you want me to change the last clothing file with the original one, I can go ahead and update it. Let me know what's the best for you. and the filename of the color swatch can be "COLORPALETTE".
Copy link to clipboard
Copied
Thanks, here is the first step, getting the primary/secondary/tertiary swatch colour values from the COLORPALETTE smart object document which will be common to all your separate mockup files.
// Save and set the dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// Select the colour palette layer
//app.activeDocument.activeLayer = app.activeDocument.layers[0];
app.activeDocument.activeLayer = app.activeDocument.layers['COLORPALETTE'];
// Edit the smart object
if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
// Delete color samplers
app.activeDocument.colorSamplers.removeAll();
// Add a colour sampler to the primary swatch
app.activeDocument.activeLayer = app.activeDocument.layerSets['DETAILS'].layerSets['COLOR'].layers[2];
addSamplerToLayerCentre();
// Add a colour sampler to the secondary swatch
app.activeDocument.activeLayer = app.activeDocument.layerSets['DETAILS'].layerSets['COLOR'].layers[0];
addSamplerToLayerCentre();
// Add a colour sampler to the tertiary swatch
app.activeDocument.activeLayer = app.activeDocument.layerSets['DETAILS'].layerSets['COLOR'].layers[1];
addSamplerToLayerCentre();
// Get the primary swatch values
// Math.round || Math.floor || Math.ceil
// var primarySamplerC = Math.round(app.activeDocument.colorSamplers[0].color.cmyk.cyan);
var primarySamplerC = app.activeDocument.colorSamplers[0].color.cmyk.cyan;
var primarySamplerM = app.activeDocument.colorSamplers[0].color.cmyk.magenta;
var primarySamplerY = app.activeDocument.colorSamplers[0].color.cmyk.yellow;
var primarySamplerK = app.activeDocument.colorSamplers[0].color.cmyk.black;
alert("Primary (CMYK): " + primarySamplerC + ", " + primarySamplerM + ", " + primarySamplerY + ", " + primarySamplerK);
// Get the secondary swatch values
var secondarySamplerC = app.activeDocument.colorSamplers[1].color.cmyk.cyan;
var secondarySamplerM = app.activeDocument.colorSamplers[1].color.cmyk.magenta;
var secondarySamplerY = app.activeDocument.colorSamplers[1].color.cmyk.yellow;
var secondarySamplerK = app.activeDocument.colorSamplers[1].color.cmyk.black;
alert("Secondary (CMYK): " + secondarySamplerC + ", " + secondarySamplerM + ", " + secondarySamplerY + ", " + secondarySamplerK);
// Get the tertiary swatch values
var tertiarySamplerC = app.activeDocument.colorSamplers[2].color.cmyk.cyan;
var tertiarySamplerM = app.activeDocument.colorSamplers[2].color.cmyk.magenta;
var tertiarySamplerY = app.activeDocument.colorSamplers[2].color.cmyk.yellow;
var tertiarySamplerK = app.activeDocument.colorSamplers[2].color.cmyk.black;
alert("Tertiary (CMYK): " + tertiarySamplerC + ", " + tertiarySamplerM + ", " + tertiarySamplerY + ", " + tertiarySamplerK);
// Close the smart object doc without saving
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
} else {
alert("The layer isn't a smart object layer!");
}
app.displayDialogs = savedDisplayDialogs;
function addSamplerToLayerCentre() {
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var layerBounds = app.activeDocument.activeLayer.bounds;
var hor = layerBounds[2] - layerBounds[0];
var ver = layerBounds[3] - layerBounds[1];
var hCentre = hor / 2 + layerBounds[0];
var vCentre = ver / 2 + layerBounds[1];
app.activeDocument.colorSamplers.add([hCentre, vCentre]);
app.preferences.rulerUnits = savedRuler;
}
The next step will be to edit the primary/secondary/tertiary coloured layers and replace the existing colour values with the updated COLORPALLETE values.
Copy link to clipboard
Copied
Oh I test it, it's amazing the way it was selecting each color. Oh man you're a really Scripting Expert.
Copy link to clipboard
Copied
Thanks, not an expert by any means!
Now that I know that you're getting correct and expected results, I can look at editing the various layers with the colour values returned by the previous test code.
Copy link to clipboard
Copied
Lol, I've been playing with all the scripts you just have shared with me. Now I have my custom buttons on my action panel. I'll stayed tuned, Bud.
Copy link to clipboard
Copied
Give this script a go:
/*
Recolour Colour Label Layers from Palette Swatches.jsx
v1.0 - 7th August 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-change-fill-color-layer/td-p/14778076
*/
#target photoshop
/***** Stage 1 - Get the colour palette swatches *****/
// Hide the Photoshop panels
app.togglePalettes();
// Select the colour palette layer
app.activeDocument.activeLayer = app.activeDocument.layers.getByName('COLORPALETTE');
// Edit the smart object
if (app.activeDocument.activeLayer.kind == LayerKind.SMARTOBJECT) {
app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
// Delete color samplers
app.activeDocument.colorSamplers.removeAll();
// Add a colour sampler to the primary swatch
app.activeDocument.activeLayer = app.activeDocument.layerSets.getByName('DETAILS').layerSets.getByName('COLOR').layers[2];
addSamplerToLayerCentre();
// Add a colour sampler to the secondary swatch
app.activeDocument.activeLayer = app.activeDocument.layerSets.getByName('DETAILS').layerSets.getByName('COLOR').layers[0];
addSamplerToLayerCentre();
// Add a colour sampler to the tertiary swatch
app.activeDocument.activeLayer = app.activeDocument.layerSets.getByName('DETAILS').layerSets.getByName('COLOR').layers[1];
addSamplerToLayerCentre();
// Get the primary swatch values
// Math.round || Math.floor || Math.ceil
var primarySamplerR = Math.round(app.activeDocument.colorSamplers[0].color.rgb.red);
var primarySamplerG = Math.round(app.activeDocument.colorSamplers[0].color.rgb.green);
var primarySamplerB = Math.round(app.activeDocument.colorSamplers[0].color.rgb.blue);
// Get the secondary swatch values
var secondarySamplerR = Math.round(app.activeDocument.colorSamplers[1].color.rgb.red);
var secondarySamplerG = Math.round(app.activeDocument.colorSamplers[1].color.rgb.green);
var secondarySamplerB = Math.round(app.activeDocument.colorSamplers[1].color.rgb.blue);
// Get the tertiary swatch values
var tertiarySamplerR = Math.round(app.activeDocument.colorSamplers[2].color.rgb.red);
var tertiarySamplerG = Math.round(app.activeDocument.colorSamplers[2].color.rgb.green);
var tertiarySamplerB = Math.round(app.activeDocument.colorSamplers[2].color.rgb.blue);
// Close the smart object doc without saving
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
} else {
alert("The layer isn't a smart object layer!");
}
function addSamplerToLayerCentre() {
var savedRuler = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var layerBounds = app.activeDocument.activeLayer.bounds;
var hor = layerBounds[2] - layerBounds[0];
var ver = layerBounds[3] - layerBounds[1];
var hCentre = hor / 2 + layerBounds[0];
var vCentre = ver / 2 + layerBounds[1];
app.activeDocument.colorSamplers.add([hCentre, vCentre]);
app.preferences.rulerUnits = savedRuler;
}
/***** Stage 2 - Recolour the layers *****/
// Set the active document
var doc = app.activeDocument;
if (!documents.length) {
alert('There are no documents open!');
} else {
activeDocument.suspendHistory('Recolour Colour Label Layers from Palette Swatches.jsx', 'main()');
}
///// Main Function /////
function main() {
// Script running notification window - courtesy of William Campbell
/* https://www.marspremedia.com/download?asset=adobe-script-tutorial-11.zip
https://youtu.be/JXPeLi6uPv4?si=Qx0OVNLAOzDrYPB4 */
var working;
working = new Window("palette");
working.preferredSize = [300, 80];
working.add("statictext");
working.t = working.add("statictext");
working.add("statictext");
working.display = function (message) {
this.t.text = message || "Script running, please wait...";
this.show();
app.refresh();
};
working.display();
// Call the file processing function
processAllLayersAndSets(doc.layers);
// Ensure Photoshop has focus before closing the running script notification window
app.bringToFront();
working.close();
// End of script notification
app.beep();
alert("Script completed!");
// Restore the Photoshop panels
app.togglePalettes();
///// Sub-Functions /////
function processAllLayersAndSets(layers) {
// Loop over the layers
for (var i = 0; i < layers.length; i++) {
var layer = layers[i];
// Store the current visibility state
var originalVisibility = layer.visible;
// Temporarily make the layer invisible
layer.visible = false;
// Select the layer
doc.activeLayer = layer;
// Layer label colours: "none", "red", "orange", "yellowColor", "grain", "blue", "violet", "gray" - New in 2024: "magenta", "seafoam", "indigo", "fuchsia"
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
var theLabelColID = desc.getEnumerationValue(stringIDToTypeID('color'));
if (theLabelColID === stringIDToTypeID("orange")) {
// Primary recolouring
if (app.activeDocument.activeLayer.kind == LayerKind.SOLIDFILL) {
setSolidFill(primarySamplerR, primarySamplerG, primarySamplerB);
}
} else if (theLabelColID === stringIDToTypeID("red")) {
// Secondary recolouring
if (app.activeDocument.activeLayer.kind == LayerKind.SOLIDFILL) {
setSolidFill(secondarySamplerR, secondarySamplerG, secondarySamplerB);
}
} else if (theLabelColID === stringIDToTypeID("yellowColor")) {
// Tertiary recolouring
if (app.activeDocument.activeLayer.kind == LayerKind.SOLIDFILL) {
setSolidFill(tertiarySamplerR, tertiarySamplerG, tertiarySamplerB);
}
}
// Restore the original layer visibility
layer.visible = originalVisibility;
// If it's a layer group, process the nested layers
if (layer.typename == "LayerSet") {
processAllLayersAndSets(layer.layers);
}
}
}
function setSolidFill(theRvalue, theGvalue, theBvalue) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var descriptor3 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
descriptor.putReference(s2t("null"), reference);
descriptor3.putDouble(s2t("red"), theRvalue);
descriptor3.putDouble(s2t("grain"), theGvalue);
descriptor3.putDouble(s2t("blue"), theBvalue);
descriptor2.putObject(s2t("color"), s2t("RGBColor"), descriptor3);
descriptor.putObject(s2t("to"), s2t("solidColorLayer"), descriptor2);
executeAction(s2t("set"), descriptor, DialogModes.NO);
}
}