Skip to main content
johnt53984649
Inspiring
October 29, 2016
Answered

Add a Stroke Layer Style / Effect to the Active Layer ExtendScript

  • October 29, 2016
  • 2 replies
  • 8436 views

I'm really, really struggling with this and I can't find any good examples for adding a stroke.  Let's say I have a smart object and I want to add a stroke Layer Style to it that is only 1 pixel in size, is positioned on the inside, has 100% opacity and is solid black in color.  I cannot figure out how to create a script that will add this specific layer style to the currently selected layer.  (Remember, it should work for smart objects as well as regular layers.)  How should I go about doing this?  Can somebody please give me an example of applying a stroke layer style to a smart object layer using ExtendScript and Javascript for Photoshop?

This topic has been closed for replies.
Correct answer JavierAroche

I know this is now an old post, but figured I'd reply with an answer and a somewhat flexible script.

The only parameters I exposed in this function were size, color, opacity and position.

With the ScriptingListener plug-in you will get the ActionDescriptor code generated by Photoshop when you execute almost any action inside of PS. It's pretty easy to install, but it's not easy to read or understand, that will require a lot of testing on your end.

Installing and using the ScriptingListener plug-in  - Adobe Photoshop Scripting | Adobe Developer Connection

// Add Stroke to layer

// Javier Aroche

// Set color as HEX

var strokeColor = new RGBColor();

strokeColor.hexValue = '000000';

addStroke(1, strokeColor, 100, 'inside');

/*

* Add Stroke Effect

* @param {Number} size : 1 - 250

* @param {Object} color : RGBColor object

* @param {Number} opacity : 0 - 100

* @param {Number} position : center / outside / inside

*/

function addStroke(size, color, opacity, position) {

    var strokePosCharID;

   

    switch(position) {

        case 'center':

            strokePosCharID = 'CtrF';

            break;

        case 'outside':

            strokePosCharID = 'OutF';

            break;

        case 'inside':

            strokePosCharID = 'InsF';

            break;

        default: break;

    }

   

    var desc = new ActionDescriptor();

    var ref190 = new ActionReference();

   

    ref190.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "Lefx" ) );

    ref190.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

    desc.putReference( charIDToTypeID( "null" ), ref190 );

    var fxDesc = new ActionDescriptor();

   

    var fxPropDesc = new ActionDescriptor();

    fxPropDesc.putBoolean( charIDToTypeID( "enab" ), true );

    fxPropDesc.putBoolean( stringIDToTypeID( "present" ), true );

    fxPropDesc.putBoolean( stringIDToTypeID( "showInDialog" ), true );

    fxPropDesc.putEnumerated( charIDToTypeID( "Styl" ), charIDToTypeID( "FStl" ), charIDToTypeID( strokePosCharID ) );

    fxPropDesc.putEnumerated(  charIDToTypeID( "PntT" ),  charIDToTypeID( "FrFl" ), charIDToTypeID( "SClr" ) );

    fxPropDesc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Nrml" ) );

    fxPropDesc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), opacity );

    fxPropDesc.putUnitDouble( charIDToTypeID( "Sz  " ), charIDToTypeID( "#Pxl") , size );

    var colorDesc = new ActionDescriptor();

    colorDesc.putDouble( charIDToTypeID( "Rd  " ), color.red);

    colorDesc.putDouble( charIDToTypeID( "Grn " ), color.green );

    colorDesc.putDouble( charIDToTypeID( "Bl  " ), color.blue );

    fxPropDesc.putObject( charIDToTypeID( "Clr " ), charIDToTypeID( "RGBC" ), colorDesc );

    fxPropDesc.putBoolean( stringIDToTypeID( "overprint" ), false );

    fxDesc.putObject( charIDToTypeID( "FrFX" ), charIDToTypeID( "FrFX" ), fxPropDesc );

    desc.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "Lefx" ), fxDesc );

    executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );

}

2 replies

Known Participant
July 9, 2021

In this script I want to add stoke in multiple layer when select the layer ?

 

function addStroke(size, color, opacity, position) {

var strokePosCharID;

 

switch(position) {

case 'center':

strokePosCharID = 'CtrF';

break;

case 'outside':

strokePosCharID = 'OutF';

break;

case 'inside':

strokePosCharID = 'InsF';

break;

default: break;

}

 

var desc = new ActionDescriptor();

var ref190 = new ActionReference();

 

ref190.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "Lefx" ) );

ref190.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

desc.putReference( charIDToTypeID( "null" ), ref190 );

var fxDesc = new ActionDescriptor();

 

var fxPropDesc = new ActionDescriptor();

fxPropDesc.putBoolean( charIDToTypeID( "enab" ), true );

fxPropDesc.putBoolean( stringIDToTypeID( "present" ), true );

fxPropDesc.putBoolean( stringIDToTypeID( "showInDialog" ), true );

fxPropDesc.putEnumerated( charIDToTypeID( "Styl" ), charIDToTypeID( "FStl" ), charIDToTypeID( strokePosCharID ) );

fxPropDesc.putEnumerated( charIDToTypeID( "PntT" ), charIDToTypeID( "FrFl" ), charIDToTypeID( "SClr" ) );

fxPropDesc.putEnumerated( charIDToTypeID( "Md " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Nrml" ) );

fxPropDesc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), opacity );

fxPropDesc.putUnitDouble( charIDToTypeID( "Sz " ), charIDToTypeID( "#Pxl") , size );

var colorDesc = new ActionDescriptor();

colorDesc.putDouble( charIDToTypeID( "Rd " ), color.red);

colorDesc.putDouble( charIDToTypeID( "Grn " ), color.green );

colorDesc.putDouble( charIDToTypeID( "Bl " ), color.blue );

fxPropDesc.putObject( charIDToTypeID( "Clr " ), charIDToTypeID( "RGBC" ), colorDesc );

fxPropDesc.putBoolean( stringIDToTypeID( "overprint" ), false );

fxDesc.putObject( charIDToTypeID( "FrFX" ), charIDToTypeID( "FrFX" ), fxPropDesc );

desc.putObject( charIDToTypeID( "T " ), charIDToTypeID( "Lefx" ), fxDesc );

executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );

}

 

Chuck Uebele
Community Expert
Community Expert
July 9, 2021

What is the issue that you're having?

Known Participant
July 9, 2021

Not a issue I want add stoke in Selected Layer in Script,

How to add Stoke Selected Layer

Jarda Bereza
Inspiring
October 29, 2016

I would use JAM framework: JsDoc Reference - jamStyles

JSON Action Manager | Tonton Pixel

In a certain sense it is a framework like jQuery is framework for the web.

Otherwise you can use this:

var idsetd = charIDToTypeID( "setd" );

    var desc55 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref19 = new ActionReference();

        var idPrpr = charIDToTypeID( "Prpr" );

        var idLefx = charIDToTypeID( "Lefx" );

        ref19.putProperty( idPrpr, idLefx );

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref19.putEnumerated( idLyr, idOrdn, idTrgt );

    desc55.putReference( idnull, ref19 );

    var idT = charIDToTypeID( "T   " );

        var desc56 = new ActionDescriptor();

        var idScl = charIDToTypeID( "Scl " );

        var idPrc = charIDToTypeID( "#Prc" );

        desc56.putUnitDouble( idScl, idPrc, 100.000000 );

        var idFrFX = charIDToTypeID( "FrFX" );

            var desc57 = new ActionDescriptor();

            var idenab = charIDToTypeID( "enab" );

            desc57.putBoolean( idenab, true );

            var idpresent = stringIDToTypeID( "present" );

            desc57.putBoolean( idpresent, true );

            var idshowInDialog = stringIDToTypeID( "showInDialog" );

            desc57.putBoolean( idshowInDialog, true );

            var idStyl = charIDToTypeID( "Styl" );

            var idFStl = charIDToTypeID( "FStl" );

            var idInsF = charIDToTypeID( "InsF" );

            desc57.putEnumerated( idStyl, idFStl, idInsF );

            var idPntT = charIDToTypeID( "PntT" );

            var idFrFl = charIDToTypeID( "FrFl" );

            var idSClr = charIDToTypeID( "SClr" );

            desc57.putEnumerated( idPntT, idFrFl, idSClr );

            var idMd = charIDToTypeID( "Md  " );

            var idBlnM = charIDToTypeID( "BlnM" );

            var idNrml = charIDToTypeID( "Nrml" );

            desc57.putEnumerated( idMd, idBlnM, idNrml );

            var idOpct = charIDToTypeID( "Opct" );

            var idPrc = charIDToTypeID( "#Prc" );

            desc57.putUnitDouble( idOpct, idPrc, 100.000000 );

            var idSz = charIDToTypeID( "Sz  " );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc57.putUnitDouble( idSz, idPxl, 10.000000 );

            var idClr = charIDToTypeID( "Clr " );

                var desc58 = new ActionDescriptor();

                var idRd = charIDToTypeID( "Rd  " );

                desc58.putDouble( idRd, 0.000000 );

                var idGrn = charIDToTypeID( "Grn " );

                desc58.putDouble( idGrn, 180.015568 );

                var idBl = charIDToTypeID( "Bl  " );

                desc58.putDouble( idBl, 255.000000 );

            var idRGBC = charIDToTypeID( "RGBC" );

            desc57.putObject( idClr, idRGBC, desc58 );

            var idoverprint = stringIDToTypeID( "overprint" );

            desc57.putBoolean( idoverprint, false );

        var idFrFX = charIDToTypeID( "FrFX" );

        desc56.putObject( idFrFX, idFrFX, desc57 );

    var idLefx = charIDToTypeID( "Lefx" );

    desc55.putObject( idT, idLefx, desc56 );

executeAction( idsetd, desc55, DialogModes.NO );

But this in not much readable code and it destroy other styles.

johnt53984649
Inspiring
October 30, 2016

I cannot get the code that you provided to work for some reason.  May I ask how you were able to generate it?  I haven't been able to try the JAM framework yet.

JavierAroche
JavierArocheCorrect answer
Inspiring
November 5, 2016

I know this is now an old post, but figured I'd reply with an answer and a somewhat flexible script.

The only parameters I exposed in this function were size, color, opacity and position.

With the ScriptingListener plug-in you will get the ActionDescriptor code generated by Photoshop when you execute almost any action inside of PS. It's pretty easy to install, but it's not easy to read or understand, that will require a lot of testing on your end.

Installing and using the ScriptingListener plug-in  - Adobe Photoshop Scripting | Adobe Developer Connection

// Add Stroke to layer

// Javier Aroche

// Set color as HEX

var strokeColor = new RGBColor();

strokeColor.hexValue = '000000';

addStroke(1, strokeColor, 100, 'inside');

/*

* Add Stroke Effect

* @param {Number} size : 1 - 250

* @param {Object} color : RGBColor object

* @param {Number} opacity : 0 - 100

* @param {Number} position : center / outside / inside

*/

function addStroke(size, color, opacity, position) {

    var strokePosCharID;

   

    switch(position) {

        case 'center':

            strokePosCharID = 'CtrF';

            break;

        case 'outside':

            strokePosCharID = 'OutF';

            break;

        case 'inside':

            strokePosCharID = 'InsF';

            break;

        default: break;

    }

   

    var desc = new ActionDescriptor();

    var ref190 = new ActionReference();

   

    ref190.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "Lefx" ) );

    ref190.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

    desc.putReference( charIDToTypeID( "null" ), ref190 );

    var fxDesc = new ActionDescriptor();

   

    var fxPropDesc = new ActionDescriptor();

    fxPropDesc.putBoolean( charIDToTypeID( "enab" ), true );

    fxPropDesc.putBoolean( stringIDToTypeID( "present" ), true );

    fxPropDesc.putBoolean( stringIDToTypeID( "showInDialog" ), true );

    fxPropDesc.putEnumerated( charIDToTypeID( "Styl" ), charIDToTypeID( "FStl" ), charIDToTypeID( strokePosCharID ) );

    fxPropDesc.putEnumerated(  charIDToTypeID( "PntT" ),  charIDToTypeID( "FrFl" ), charIDToTypeID( "SClr" ) );

    fxPropDesc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Nrml" ) );

    fxPropDesc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), opacity );

    fxPropDesc.putUnitDouble( charIDToTypeID( "Sz  " ), charIDToTypeID( "#Pxl") , size );

    var colorDesc = new ActionDescriptor();

    colorDesc.putDouble( charIDToTypeID( "Rd  " ), color.red);

    colorDesc.putDouble( charIDToTypeID( "Grn " ), color.green );

    colorDesc.putDouble( charIDToTypeID( "Bl  " ), color.blue );

    fxPropDesc.putObject( charIDToTypeID( "Clr " ), charIDToTypeID( "RGBC" ), colorDesc );

    fxPropDesc.putBoolean( stringIDToTypeID( "overprint" ), false );

    fxDesc.putObject( charIDToTypeID( "FrFX" ), charIDToTypeID( "FrFX" ), fxPropDesc );

    desc.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "Lefx" ), fxDesc );

    executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );

}