Strokes around layer-mask outline

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

Gewuerz

Strokes around layer-mask outline

Post by Gewuerz »

I have any (smart object or not smart object) layers with layer mask. The image content is not equal in size to the layer masks.

I wish to make Strokes (4px inside, possible adjustable) around the masks, only for selected layers!
In the moment i activate the masks-selection, layer for layer, make new layers above on the selected layers.
Fill the selection on the new layers with black , set Fill to 0% ,make a layer effect stroke 4px inside. I get then borders around outline the mask.
I had tested to build a action, no success.

Is this possible with a script? Any help welcome.

Thanks Wolfgang

This the result that i wish:

Professional AI Audio Generation within Adobe Premiere Pro - Download Free Plugin here

pfaffenbichler

Strokes around layer-mask outline

Post by pfaffenbichler »

Well, it’s not what you asked for, but this would create one Layer with Stroke based on the selected Layers’s Layer Masks.
Code: Select all// create a layer with stroke from selected layers’ layer masks;
// thanks to mike hale and paul mr;
// 2013, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
myDocument.suspendHistory("operation", "main(myDocument)");
};
////////////////////////////////////
function main () {
var theLayers = getSelectedLayersIdx();
myDocument.selection.deselect();
for (var n = 0; n < theLayers.length; n++) {
selectLayerByIndex(theLayers[n], false);
   if (hasLayerMask(myDocument, myDocument.activeLayer) == true) {
      alert (myDocument.activeLayer);
      try {addLayerMaskToSelection()}
      catch (e) {loadLayerMask()}
      };
   };
createSolidColorLayer ();
applyLayerStyleStroke ()
};
// by mike hale, via paul riggott;
// http://forums.adobe.com/message/1944754#1944754
function selectLayerByIndex(index,add){
add = undefined ? add = false: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){
alert(e.message);
}
};
////// by paul mr;
function getSelectedLayersIdx(){
      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;
};

////// the fill-layer-function //////
function makeFillLayer (theName, theHue, theSat, theBright) {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc4 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref2 = new ActionReference();
        var idClr = charIDToTypeID( "Clr " );
        var idFrgC = charIDToTypeID( "FrgC" );
        ref2.putProperty( idClr, idFrgC );
    desc4.putReference( idnull, ref2 );
    var idT = charIDToTypeID( "T   " ); 
        var desc5 = new ActionDescriptor();
        var idH = charIDToTypeID( "H   " );
        var idAng = charIDToTypeID( "#Ang" );
        desc5.putUnitDouble( idH, idAng, theHue );
        var idStrt = charIDToTypeID( "Strt" );
        desc5.putDouble( idStrt, theSat );
        var idBrgh = charIDToTypeID( "Brgh" );
        desc5.putDouble( idBrgh, theBright );
    var idHSBC = charIDToTypeID( "HSBC" );
    desc4.putObject( idT, idHSBC, desc5 );
executeAction( idsetd, desc4, DialogModes.NO );
// =======================================================
var id212 = charIDToTypeID( "Mk  " );
var desc39 = new ActionDescriptor();
var id213 = charIDToTypeID( "null" );
var ref27 = new ActionReference();
var id214 = stringIDToTypeID( "contentLayer" );
ref27.putClass( id214 ); desc39.putReference( id213, ref27 );
var id215 = charIDToTypeID( "Usng" );
var desc40 = new ActionDescriptor();
var id216 = charIDToTypeID( "Type" );
var id217 = stringIDToTypeID( "solidColorLayer" );
desc40.putClass( id216, id217 );
var id218 = stringIDToTypeID( "contentLayer" );
desc39.putObject( id215, id218, desc40 );
executeAction( id212, desc39, DialogModes.NO );
app.activeDocument.activeLayer.name = theName;
return app.activeDocument.activeLayer
};

////// make solid color layer //////
function createSolidColorLayer () {
// create solid color layer;
// =======================================================
var idMk = charIDToTypeID( "Mk  " );
    var desc8 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref6 = new ActionReference();
        var idcontentLayer = stringIDToTypeID( "contentLayer" );
        ref6.putClass( idcontentLayer );
    desc8.putReference( idnull, ref6 );
    var idUsng = charIDToTypeID( "Usng" );
        var desc9 = new ActionDescriptor();
        var idType = charIDToTypeID( "Type" );
            var desc10 = new ActionDescriptor();
            var idClr = charIDToTypeID( "Clr " );
                var desc11 = new ActionDescriptor();
                var idRd = charIDToTypeID( "Rd  " );
                desc11.putDouble( idRd, 0.000000 );
                var idGrn = charIDToTypeID( "Grn " );
                desc11.putDouble( idGrn, 0.000000 );
                var idBl = charIDToTypeID( "Bl  " );
                desc11.putDouble( idBl, 0.000000 );
            var idRGBC = charIDToTypeID( "RGBC" );
            desc10.putObject( idClr, idRGBC, desc11 );
        var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );
        desc9.putObject( idType, idsolidColorLayer, desc10 );
    var idcontentLayer = stringIDToTypeID( "contentLayer" );
    desc8.putObject( idUsng, idcontentLayer, desc9 );
executeAction( idMk, desc8, DialogModes.NO );
// set fill opacity to 0;
// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc5 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref4 = new ActionReference();
        var idLyr = charIDToTypeID( "Lyr " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref4.putEnumerated( idLyr, idOrdn, idTrgt );
    desc5.putReference( idnull, ref4 );
    var idT = charIDToTypeID( "T   " );
        var desc6 = new ActionDescriptor();
        var idfillOpacity = stringIDToTypeID( "fillOpacity" );
        var idPrc = charIDToTypeID( "#Prc" );
        desc6.putUnitDouble( idfillOpacity, idPrc, 0.000000 );
    var idLyr = charIDToTypeID( "Lyr " );
    desc5.putObject( idT, idLyr, desc6 );
executeAction( idsetd, desc5, DialogModes.NO );
};
////// make stroke //////
function applyLayerStyleStroke () {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc12 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref7 = new ActionReference();
        var idPrpr = charIDToTypeID( "Prpr" );
        var idLefx = charIDToTypeID( "Lefx" );
        ref7.putProperty( idPrpr, idLefx );
        var idLyr = charIDToTypeID( "Lyr " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref7.putEnumerated( idLyr, idOrdn, idTrgt );
    desc12.putReference( idnull, ref7 );
    var idT = charIDToTypeID( "T   " );
        var desc13 = new ActionDescriptor();
        var idScl = charIDToTypeID( "Scl " );
        var idPrc = charIDToTypeID( "#Prc" );
        desc13.putUnitDouble( idScl, idPrc, 100.000000 );
        var idFrFX = charIDToTypeID( "FrFX" );
            var desc14 = new ActionDescriptor();
            var idenab = charIDToTypeID( "enab" );
            desc14.putBoolean( idenab, true );
            var idStyl = charIDToTypeID( "Styl" );
            var idFStl = charIDToTypeID( "FStl" );
            var idInsF = charIDToTypeID( "InsF" );
            desc14.putEnumerated( idStyl, idFStl, idInsF );
            var idPntT = charIDToTypeID( "PntT" );
            var idFrFl = charIDToTypeID( "FrFl" );
            var idSClr = charIDToTypeID( "SClr" );
            desc14.putEnumerated( idPntT, idFrFl, idSClr );
            var idMd = charIDToTypeID( "Md  " );
            var idBlnM = charIDToTypeID( "BlnM" );
            var idNrml = charIDToTypeID( "Nrml" );
            desc14.putEnumerated( idMd, idBlnM, idNrml );
            var idOpct = charIDToTypeID( "Opct" );
            var idPrc = charIDToTypeID( "#Prc" );
            desc14.putUnitDouble( idOpct, idPrc, 100.000000 );
            var idSz = charIDToTypeID( "Sz  " );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc14.putUnitDouble( idSz, idPxl, 4.000000 );
            var idClr = charIDToTypeID( "Clr " );
                var desc15 = new ActionDescriptor();
                var idRd = charIDToTypeID( "Rd  " );
                desc15.putDouble( idRd, 0.000000 );
                var idGrn = charIDToTypeID( "Grn " );
                desc15.putDouble( idGrn, 0.000000 );
                var idBl = charIDToTypeID( "Bl  " );
                desc15.putDouble( idBl, 0.000000 );
            var idRGBC = charIDToTypeID( "RGBC" );
            desc14.putObject( idClr, idRGBC, desc15 );
        var idFrFX = charIDToTypeID( "FrFX" );
        desc13.putObject( idFrFX, idFrFX, desc14 );
    var idLefx = charIDToTypeID( "Lefx" );
    desc12.putObject( idT, idLefx, desc13 );
executeAction( idsetd, desc12, DialogModes.NO );
};
////// from xbytor’s stdlib //////
// from discussions with Mike Hale
function hasLayerMask (doc, layer) {
   cTID = function(s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
   function _ftn() {
      var ref = new ActionReference();
      ref.putEnumerated(cTID("Lyr "), cTID("Ordn"), cTID("Trgt"));
      var desc = executeActionGet(ref);
      return desc.hasKey(cTID("UsrM"));
      };
   return _ftn(doc, layer);
   };
////// load layer mask additionally //////
function addLayerMaskToSelection () {
// =======================================================
var idAdd = charIDToTypeID( "Add " );
    var desc4 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref4 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idChnl = charIDToTypeID( "Chnl" );
        var idMsk = charIDToTypeID( "Msk " );
        ref4.putEnumerated( idChnl, idChnl, idMsk );
    desc4.putReference( idnull, ref4 );
    var idT = charIDToTypeID( "T   " );
        var ref5 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idfsel = charIDToTypeID( "fsel" );
        ref5.putProperty( idChnl, idfsel );
    desc4.putReference( idT, ref5 );
executeAction( idAdd, desc4, DialogModes.NO );
};
////// load layer mask as selection //////
function loadLayerMask () {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
    var desc2 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref1 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idfsel = charIDToTypeID( "fsel" );
        ref1.putProperty( idChnl, idfsel );
    desc2.putReference( idnull, ref1 );
    var idT = charIDToTypeID( "T   " );
        var ref2 = new ActionReference();
        var idChnl = charIDToTypeID( "Chnl" );
        var idChnl = charIDToTypeID( "Chnl" );
        var idMsk = charIDToTypeID( "Msk " );
        ref2.putEnumerated( idChnl, idChnl, idMsk );
    desc2.putReference( idT, ref2 );
executeAction( idsetd, desc2, DialogModes.NO );
};
Gewuerz

Strokes around layer-mask outline

Post by Gewuerz »

Great Thanks.
It works.
Better would be single layers with strokes above on the selected layers.

I think your solution helps me very much. THANK YOU.

Wolfgang
pfaffenbichler

Strokes around layer-mask outline

Post by pfaffenbichler »

When I used the for-clause (based on theLayers.length) to create new Layers with the Layer Style instead of just loading the selection the indices got messed up in my test.
But one could (but this is probably a pretty clumsy work-around) use it to collect the Layers into another Array (as Layers and not by indices) and then set up another for-clause to process them individually.