Skip to main content
Participant
May 13, 2023
Question

How to change via script a SolidFill layer color on a masked layer

  • May 13, 2023
  • 3 replies
  • 2942 views
  1. I have a simple file where I cuse the Elliptical Marquee tool to mark a Circle.
  2. I then add a New Fill Layer - Solid Color (purple).
  3. I save this file as a project.
  4. I would then want to change this mask color via a script (JDX, PY, whatever) to a different one (example red).

 

I tried via JSX with the following code:

 

 

// Get the active document
var doc = app.activeDocument;

// Get the "Circle" layer
var circleLayer = doc.layers.getByName("Circle");

// Get the Circle mask
var circleMask = circleLayer.mask;

// Create a new solid color fill layer
var colorLayer = doc.artLayers.add();
colorLayer.kind = LayerKind.SOLIDFILL;
colorLayer.name = "Color Fill";
colorLayer.fillOpacity = 100;
colorLayer.blendMode = BlendMode.NORMAL;
colorLayer.solidColor.rgb.red = 255;
colorLayer.solidColor.rgb.green = 0;
colorLayer.solidColor.rgb.blue = 0;

// Apply the color fill layer as a clipping mask to the Circle mask
circleMask.applyAdd();
colorLayer.move(circleLayer, ElementPlacement.PLACEAFTER);
colorLayer.clipped = true;

 

However that throws a message:
"Error 8193: You can only change the layer's kind to text or normal" line 12: color

colorLayer.kind = LayerKind.SOLIDFILL;

 

I've tried modifying the code countless times to no effect. Any help to achieve this would be appreciated or a different approach to take.

This topic has been closed for replies.

3 replies

c.pfaffenbichler
Community Expert
Community Expert
May 13, 2023

@Stephen Marsh ’s post should have covered the Scripting aspect plenty, but I wonder why you used the Elliptical Marquee Tool and not the Ellipse Tool? 

Using a Vector Mask (path) instead of a Layer Mask (pixel) can offer benefits but naturally there can be reasons for using pixels. 

Participant
May 15, 2023

Hi,


The example I provided with a Circle is not the file I need it for but a preview of a principle.

My actual file contains a Solid Fill mask over a mask selecting a part of a tshirt (like sleeves only).

 

To answer your questions however as far as I understand the Ellipse Tool creates a static object in a layer. I cannot color just that created "circle" via a script - only the marquee tool would allow me the "mask". Or perhaps I dont understand the concept.

c.pfaffenbichler
Community Expert
Community Expert
May 15, 2023

Paths are not »static«, one can edit them further after all. 

Used as a Vector Mask they need not even »be sharp«, one can Feather them via the Properties Panel. 

 

None of which means that you need to use the, obviously. 

Stephen Marsh
Community Expert
Community Expert
May 13, 2023

To add a new solid fill layer, you can use the following function:

 

addSolidFill(128, 128, 128);

function addSolidFill(rValue, gValue, bValue) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var descriptor3 = new ActionDescriptor();
	var descriptor4 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putClass( s2t( "contentLayer" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor4.putDouble( s2t( "red" ), rValue );
	descriptor4.putDouble( s2t( "grain" ), gValue );
	descriptor4.putDouble( s2t( "blue" ), bValue );
	descriptor3.putObject( s2t( "color" ), s2t( "RGBColor" ), descriptor4 );
	descriptor2.putObject( s2t( "type" ), s2t( "solidColorLayer" ), descriptor3 );
	descriptor.putObject( s2t( "using" ), s2t( "contentLayer" ), descriptor2 );
	executeAction( s2t( "make" ), descriptor, DialogModes.NO );
}

 

You can optionally change the following line from:

 

executeAction( s2t( "make" ), descriptor, DialogModes.NO );

 

To an interactive script if required:

 

executeAction( s2t( "make" ), descriptor, DialogModes.ALL );

 

P.S. The Photoshop DOM only covers so much, one must use Action Manager (AM) code to do what isn't possible via the DOM. Perhaps the most accessible way to get into AM coding is to use the ScriptingListener plug-in (some advanced users know how to do this without the plug-in):

 

https://helpx.adobe.com/au/photoshop/kb/downloadable-plugins-and-content.html

 

Stephen Marsh
Community Expert
Community Expert
May 13, 2023

With an existing solid fill layer that you need to edit...

 

STATIC:

 

#target photoshop

/*
Static Edit Color Fill.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-change-via-script-a-solidfill-layer-color-on-a-masked-layer/td-p/13789443
v1.0 - 13th May 2023, Stephen Marsh
*/

if (app.documents.length > 0) {

    if (activeDocument.activeLayer.kind == LayerKind.SOLIDFILL) {

        setColorFill(128, 128, 128);

    } else {
        alert("The active layer isn't a Color Fill layer!");
    }

} else {
    alert('You must have a document open!');
}


function setColorFill(rValue, gValue, bValue) {
    function s2t(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"), rValue);
    descriptor3.putDouble(s2t("grain"), gValue);
    descriptor3.putDouble(s2t("blue"), bValue);
    descriptor2.putObject(s2t("color"), s2t("RGBColor"), descriptor3);
    descriptor.putObject(s2t("to"), s2t("solidColorLayer"), descriptor2);
    executeAction(s2t("set"), descriptor, DialogModes.NO);
}

 

 

INTERACTIVE:

 

#target photoshop

/*
Interactive Edit Color Fill.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-update-solid-color-adjustment-layer-color-using-photoshop-scripting/td-p/13702428
v1.0 - 4th April 2023, Stephen Marsh
*/

if (app.documents.length > 0) {

    if (activeDocument.activeLayer.kind == LayerKind.SOLIDFILL) {

        interactiveSetColorFill();

    } else {
        alert("The active layer isn't a Color Fill layer!");
    }

} else {
    alert('You must have a document open!');
}


function interactiveSetColorFill() {
    /*
    Get the colour fill RGB values
    https://community.adobe.com/t5/photoshop-ecosystem-discussions/get-current-solid-layer-color-hex-code-in-alert/td-p/10830649
    */
    var r = new ActionReference();
    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("adjustment"));
    r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
    var objAdjustment = executeActionGet(r).getList(stringIDToTypeID("adjustment"));
    var objsolidColorLayer = objAdjustment.getObjectValue(0);
    var objRGBColor = objsolidColorLayer.getObjectValue(stringIDToTypeID("color"));
    var rValue = Math.round(objRGBColor.getDouble(stringIDToTypeID("red")));
    var gValue = Math.round(objRGBColor.getDouble(stringIDToTypeID("grain")));
    var bValue = Math.round(objRGBColor.getDouble(stringIDToTypeID("blue")));
    /*
    Set the colour fill RGB values
    */
    function s2t(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"), rValue);
    descriptor3.putDouble(s2t("grain"), gValue);
    descriptor3.putDouble(s2t("blue"), bValue);
    descriptor2.putObject(s2t("color"), s2t("RGBColor"), descriptor3);
    descriptor.putObject(s2t("to"), s2t("solidColorLayer"), descriptor2);
    executeAction(s2t("set"), descriptor, DialogModes.ALL);
}

 

 

Participant
May 15, 2023

Hi @Stephen Marsh thank you. This does exactly what I wanted (Static version). However as soon as I try to upgrade this type of script (to add change to more than 1 layer, change from active layer to layer based on name) photoshop returns with the following error:
Error 8800: General Photoshop error occured. This functionality may not be available in this version of Photoshop.
- The command "Set" is not currently avaialble/
Line 49
-> executeAction(s2t("set"), descriptor, DialogModes.NO);

 

My end goal is to automaticaly by script change the fill color of 2-3 different layers (based on layer name) to a specific color (where it would loop through a CSV file to read the color data) and save those as PNGs.

Stephen Marsh
Community Expert
Community Expert
May 15, 2023

Have you tried to just copy the function and then just put the function call in your script? Just simplify it, taking only the bare minimum. What Photoshop version are you using?