Skip to main content
Known Participant
February 19, 2025
Answered

create averge color inversion layer using script

  • February 19, 2025
  • 1 reply
  • 333 views

Hi everyone,

 

I want to do the following work by script but I don't know how to do it, 

I usually use the key combination to create it:

Step 1: create a visible layer (Ctrl + Alt + Shift + E) 
Step 2: Blur / AVG color that layer (Ctrl + Alt + F)
Step 3: Invert it (Ctrl + I)

 

please guide me, I appreciate your help.

Correct answer Stephen Marsh
quote

@Stephen Marsh  thank you, it's works.

 

but I forgot,
there is one more step, this layer create a clipping mask with the layer below (Alt + Ctrl + G), please

 


By @powerful_Zephyr5EF9

 

Presuming that the layer/s to be clipping masked are selected:

 

var idgroupEvent = stringIDToTypeID( "groupEvent" );
    var desc298 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref64 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        var idordinal = stringIDToTypeID( "ordinal" );
        var idtargetEnum = stringIDToTypeID( "targetEnum" );
        ref64.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc298.putReference( idnull, ref64 );
executeAction( idgroupEvent, desc298, DialogModes.NO );

 

However, this can be simplified to:

app.runMenuItem(stringIDToTypeID('groupEvent'));

 

1 reply

Stephen Marsh
Community Expert
Community Expert
February 19, 2025

@powerful_Zephyr5EF9 

 

Does the ScriptingListener plugin work with your version of Photoshop?

 

You will find things much easier if you have it.

 

Here is a raw SL code recording of the key steps, with some comments:

 

// Merge visible with duplicate
var idmergeVisible = stringIDToTypeID("mergeVisible");
var desc615 = new ActionDescriptor();
var idduplicate = stringIDToTypeID("duplicate");
desc615.putBoolean(idduplicate, true);
executeAction(idmergeVisible, desc615, DialogModes.NO);

// Blur - Average filter
var idAvrg = charIDToTypeID("Avrg");
executeAction(idAvrg, undefined, DialogModes.NO);

// Invert layer
var idinvert = stringIDToTypeID("invert");
executeAction(idinvert, undefined, DialogModes.NO);

// Set blend mode to color
var idset = stringIDToTypeID("set");
var desc619 = new ActionDescriptor();
var idnull = stringIDToTypeID("null");
var ref176 = new ActionReference();
var idlayer = stringIDToTypeID("layer");
var idordinal = stringIDToTypeID("ordinal");
var idtargetEnum = stringIDToTypeID("targetEnum");
ref176.putEnumerated(idlayer, idordinal, idtargetEnum);
desc619.putReference(idnull, ref176);
var idto = stringIDToTypeID("to");
var desc620 = new ActionDescriptor();
var idmode = stringIDToTypeID("mode");
var idblendMode = stringIDToTypeID("blendMode");
var idcolor = stringIDToTypeID("color");
desc620.putEnumerated(idmode, idblendMode, idcolor);
var idlayer = stringIDToTypeID("layer");
desc619.putObject(idto, idlayer, desc620);
executeAction(idset, desc619, DialogModes.NO);

// layer opacity 50%
var idset = stringIDToTypeID("set");
var desc622 = new ActionDescriptor();
var idnull = stringIDToTypeID("null");
var ref177 = new ActionReference();
var idlayer = stringIDToTypeID("layer");
var idordinal = stringIDToTypeID("ordinal");
var idtargetEnum = stringIDToTypeID("targetEnum");
ref177.putEnumerated(idlayer, idordinal, idtargetEnum);
desc622.putReference(idnull, ref177);
var idto = stringIDToTypeID("to");
var desc623 = new ActionDescriptor();
var idopacity = stringIDToTypeID("opacity");
var idpercentUnit = stringIDToTypeID("percentUnit");
desc623.putUnitDouble(idopacity, idpercentUnit, 50.000000);
var idlayer = stringIDToTypeID("layer");
desc622.putObject(idto, idlayer, desc623);
executeAction(idset, desc622, DialogModes.NO);

 

It's a bit verbose... You can reduce the code length and visual/comprehension complexity by using the CleanSL script, manually removing redundant variables or swapping out blocks of recorded AM code for standard DOM code. Makes no difference to the execution speed, it's just easier to work with when it isn't needlessly complicated:

 

// Merge visible with duplicate
var idmergeVisible = stringIDToTypeID("mergeVisible");
var desc615 = new ActionDescriptor();
var idduplicate = stringIDToTypeID("duplicate");
desc615.putBoolean(idduplicate, true);
executeAction(idmergeVisible, desc615, DialogModes.NO);

// Blur - Average filter
executeAction(charIDToTypeID("Avrg"), undefined, DialogModes.NO);
// or DOM code
// app.activeDocument.activeLayer.applyAverage();

// Invert layer
app.activeDocument.activeLayer.invert();

// layer opacity 50%
app.activeDocument.activeLayer.opacity = 50;

// Set blend mode to color
app.activeDocument.activeLayer.blendMode = BlendMode.COLORBLEND;

 

Known Participant
February 19, 2025

@Stephen Marsh  thank you, it's works.

 

but I forgot,
there is one more step, this layer create a clipping mask with the layer below (Alt + Ctrl + G), please

 

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
February 19, 2025
quote

@Stephen Marsh  thank you, it's works.

 

but I forgot,
there is one more step, this layer create a clipping mask with the layer below (Alt + Ctrl + G), please

 


By @powerful_Zephyr5EF9

 

Presuming that the layer/s to be clipping masked are selected:

 

var idgroupEvent = stringIDToTypeID( "groupEvent" );
    var desc298 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref64 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        var idordinal = stringIDToTypeID( "ordinal" );
        var idtargetEnum = stringIDToTypeID( "targetEnum" );
        ref64.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc298.putReference( idnull, ref64 );
executeAction( idgroupEvent, desc298, DialogModes.NO );

 

However, this can be simplified to:

app.runMenuItem(stringIDToTypeID('groupEvent'));