Skip to main content
Known Participant
May 31, 2024
Answered

How can I configure a script to run on all selected layers?

  • May 31, 2024
  • 3 replies
  • 798 views

I have a script. Those Scripts only affect the layer I selected. 

How can I modify these scripts if I want the selected layer to affect two or more layers? 

 

Sample scripts 

// Blurmore.jsx
//

//
// Generated Fri May 31 2024 14:44:55 GMT+0630
//

cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

//
//==================== Blur more ==============
//
function Blurmore() {
  // Gaussian Blur
  function step1(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    desc1.putUnitDouble(cTID('Rds '), cTID('#Pxl'), 6.4);
    executeAction(sTID('gaussianBlur'), desc1, dialogMode);
  };

  step1();      // Gaussian Blur
};



//=========================================
//                    Blurmore.main
//=========================================
//

Blurmore.main = function () {
  Blurmore();
};

Blurmore.main();

// EOF

"Blurmore.jsx"
// EOF

 

This topic has been closed for replies.
Correct answer Stephen Marsh

For completeness, I originally mentioned that there are multiple code options to perform the task of processing multiple selected layers individually.

 

Here is another example using different code:

 

/*
Process Selected Layers
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/do-action-for-selected-layer/td-p/12604989
*/

#target photoshop

var selectedLayers = getSelectedLayersIdx();
for (var a in selectedLayers) {
   
   makeActiveByIndex(Number(selectedLayers[a]));

   // Your code here
   alert(app.activeDocument.activeLayer.name);
}

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;
      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 {
      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 makeActiveByIndex(idx, visible, add) {
   if (visible === undefined) visible = false; // Boolean to make the selected layer visible
   if (add === undefined) add = false;
   var desc = new ActionDescriptor();
   var ref = new ActionReference();
   ref.putIndex(charIDToTypeID("Lyr "), idx);
   desc.putReference(charIDToTypeID("null"), ref);
   if (add) desc.putEnumerated(stringIDToTypeID('selectionModifier'), stringIDToTypeID('selectionModifierType'), stringIDToTypeID('addToSelection'));
   desc.putBoolean(charIDToTypeID("MkVs"), visible);
   executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
}

3 replies

Stephen Marsh
Community Expert
Community Expert
June 4, 2024

@Thiha31203570tbl0 

 

I can see that you have used xtools to convert an action for Gaussian Blur to Action Manager (AM) based ExtendScript, which has created a rather verbose 44 lines of code.

 

Using Document Object Model (DOM) based ExtendScript code, this can be performed with 1 line:

 

app.activeDocument.activeLayer.applyGaussianBlur(6.4);

 

https://theiviaxx.github.io/photoshop-docs/Photoshop/ArtLayer/applyGaussianBlur.html

 

With the help of the Scripting Listener plugin, you can also capture the AM code in just 6 lines, which could be simplified further:

 

var idgaussianBlur = stringIDToTypeID( "gaussianBlur" );
    var desc238 = new ActionDescriptor();
    var idradius = stringIDToTypeID( "radius" );
    var idpixelsUnit = stringIDToTypeID( "pixelsUnit" );
    desc238.putUnitDouble( idradius, idpixelsUnit, 6.400000 );
executeAction( idgaussianBlur, desc238, DialogModes.NO );

 

There is nothing wrong with this, it doesn't matter if the code uses 44 lines, 6 lines or even 1 line of code – I am just noting this as it can make your coding easier to manage.

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
June 4, 2024

For completeness, I originally mentioned that there are multiple code options to perform the task of processing multiple selected layers individually.

 

Here is another example using different code:

 

/*
Process Selected Layers
Based on:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/do-action-for-selected-layer/td-p/12604989
*/

#target photoshop

var selectedLayers = getSelectedLayersIdx();
for (var a in selectedLayers) {
   
   makeActiveByIndex(Number(selectedLayers[a]));

   // Your code here
   alert(app.activeDocument.activeLayer.name);
}

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;
      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 {
      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 makeActiveByIndex(idx, visible, add) {
   if (visible === undefined) visible = false; // Boolean to make the selected layer visible
   if (add === undefined) add = false;
   var desc = new ActionDescriptor();
   var ref = new ActionReference();
   ref.putIndex(charIDToTypeID("Lyr "), idx);
   desc.putReference(charIDToTypeID("null"), ref);
   if (add) desc.putEnumerated(stringIDToTypeID('selectionModifier'), stringIDToTypeID('selectionModifierType'), stringIDToTypeID('addToSelection'));
   desc.putBoolean(charIDToTypeID("MkVs"), visible);
   executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
}
Known Participant
June 2, 2024

Thank you so much Sir @Stephen Marsh  . . . 

This code is very cool. . . If the hidden layer is selected and the scripts are run, the hidden layer becomes the show layer. Can you fix that? Although I like the effect on the hidden layer. . . I don't like that it becomes a show layer. 

#I'm sorry if I say something wrong when I speak English, I have to translate it back to English

#target photoshop

/* Start Process selected layers - from jazz-y */
var s2t = stringIDToTypeID;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var lrs = executeActionGet(r).getList(p),
    sel = new ActionReference();

for (var i = 0; i < lrs.count; i++) {
    sel.putIdentifier(s2t('layer'), p = lrs.getReference(i).getIdentifier(s2t('layerID')));
    (r = new ActionReference()).putIdentifier(s2t('layer'), p);
    (d = new ActionDescriptor()).putReference(s2t("target"), r);
    executeAction(s2t('select'), d, DialogModes.NO);
/* End Process selected layers - from jazz-y */

// Your code here:
alert(activeDocument.activeLayer.name);

}

 

Stephen Marsh
Community Expert
Community Expert
June 3, 2024

@Thiha31203570tbl0 

 

I suspect that the following needs to be changed:

 

executeAction(s2t('select'), d, DialogModes.NO);

 

To possibly use a .putBoolean(stringIDToTypeID("makeVisible"), false) – however, the full code required is beyond my basic grasp of AM code.

 

Sorry to intrude @jazz-y or @c.pfaffenbichler or @r-bin – can you please offer a solution to not affect the layer visibility when looping over the selected layers?