• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

PSD JSX - Loop through layers and apply layer mask to size of the document on each layer

Explorer ,
Nov 06, 2024 Nov 06, 2024

Copy link to clipboard

Copied

Hello,

I keep getting errors when creating a layer mask using photoshop JSX script

I'm looking for a way to loop through all the layers and add a layer mask at the size of the document canvas.

Here are the functions I am running but I can't figure out how to get it up and running

Thanks for your time

// loop through each layer
function walkLayers(o) {
var i;
var layer;
var frame;
var psd_name = decodeURI(app.activeDocument.name);
var file_name = psd_name.substring(0, psd_name.lastIndexOf('.')) || psd_name;

for (i = 0; i < o.layers.length; i++) {
layer = o.layers[i];
layer.name = file_name;
applyLayerMask(layer)
 }
}

// Layer mask from selection
function applyLayerMask(layer) {
app.activeDocument.selection.selectAll(); // select entire canvas

// create a mask on layer
var c2t = function (s) {
return app.charIDToTypeID(s);
 };

var s2t = function (s) {
return app.stringIDToTypeID(s);
 };

var descriptor = new ActionDescriptor();
var reference = new ActionReference();

descriptor.putClass( s2t( "new" ), s2t( "channel" ));
reference.putEnumerated( s2t( "channel" ), s2t( "channel" ), s2t( "mask" ));
descriptor.putReference( s2t( "at" ), reference );
descriptor.putEnumerated( s2t( "using" ), c2t( "UsrM" ), s2t( "revealSelection" ));
executeAction( s2t( "make" ), descriptor, DialogModes.NO );

}
walkLayers(app.activeDocument);
TOPICS
Actions and scripting

Views

230

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Nov 06, 2024 Nov 06, 2024

I tried in version 2021 and 2024 and didn't get that error, however I didn't get the masks either.

 

This works for me, take from it what you like:

 

app.activeDocument.suspendHistory('Add reveal all layer mask to top-level layers...', 'maskAllLayers()');

function maskAllLayers() {

  // Capture the initial layer visibility and layer selection
  var currentLayersState = getLayersVisiblity();

  // Ensure that a layer is selected
  try {
    activeDocument.activeLayer.link(activeDocument.activeL
...

Votes

Translate

Translate
Adobe
Community Expert ,
Nov 06, 2024 Nov 06, 2024

Copy link to clipboard

Copied

I tried in version 2021 and 2024 and didn't get that error, however I didn't get the masks either.

 

This works for me, take from it what you like:

 

app.activeDocument.suspendHistory('Add reveal all layer mask to top-level layers...', 'maskAllLayers()');

function maskAllLayers() {

  // Capture the initial layer visibility and layer selection
  var currentLayersState = getLayersVisiblity();

  // Ensure that a layer is selected
  try {
    activeDocument.activeLayer.link(activeDocument.activeLayer);
  } catch (e) { }

  // Loop over the root/top-level layers (change artLayers to layers to include groups)
  for (var i = 0; i < app.activeDocument.artLayers.length; i++) {

    app.activeDocument.activeLayer = activeDocument.artLayers[i];

    // Ensure that the layer is not a background layer
    if (!app.activeDocument.activeLayer.isBackgroundLayer) {

      // Add a reveal all layer mask to the layer
      function s2t(s) {
        return app.stringIDToTypeID(s);
      }
      var descriptor = new ActionDescriptor();
      var reference = new ActionReference();
      descriptor.putClass(s2t("new"), s2t("channel"));
      reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
      descriptor.putReference(s2t("at"), reference);
      descriptor.putEnumerated(s2t("using"), s2t("userMaskEnabled"), s2t("revealAll"));
      executeAction(s2t("make"), descriptor, DialogModes.NO);

    }

  }

  // Restore the initial layer visibility and selection
  setLayersVisiblity(currentLayersState);


  //// Functions ////

  function getLayersVisiblity() {
    // by jazz-y
    var s2t = stringIDToTypeID,
      t2s = typeIDToStringID;
    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
    r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
    var targetLayers = executeActionGet(r).getList(p),
      seletion = [],
      visiblity = {};
    for (var i = 0; i < targetLayers.count; i++) seletion.push(targetLayers.getReference(i).getIdentifier());
    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
    r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
    var len = executeActionGet(r).getInteger(p);
    for (var i = 1; i <= len; i++) {
      (r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerSection'));
      r.putIndex(s2t('layer'), i);
      if (t2s(executeActionGet(r).getEnumerationValue(p)) == 'layerSectionEnd') continue;
      (r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
      r.putIndex(s2t('layer'), i);
      var id = executeActionGet(r).getInteger(p);
      (r = new ActionReference()).putProperty(s2t('property'), p = s2t('visible'));
      r.putIndex(s2t('layer'), i);
      var visible = executeActionGet(r).getBoolean(p);
      visiblity[id] = visible;
    }
    return {
      selection: seletion,
      visiblity: visiblity
    };
  }

  function setLayersVisiblity(layersStateObject) {
    // by jazz-y
    var s2t = stringIDToTypeID;
    for (var a in layersStateObject.visiblity) {
      makeVisible = layersStateObject.visiblity[a] ? "show" : "hide";
      (r = new ActionReference()).putIdentifier(s2t('layer'), a);
      (d = new ActionDescriptor()).putReference(s2t('target'), r);
      executeAction(s2t(makeVisible), d, DialogModes.NO);
    }
    if (layersStateObject.selection.length) {
      var r = new ActionReference();
      for (var i = 0; i < layersStateObject.selection.length; i++)
        r.putIdentifier(s2t("layer"), layersStateObject.selection[i]);
      (d = new ActionDescriptor()).putReference(s2t("target"), r);
      d.putBoolean(s2t("makeVisible"), false);
      executeAction(s2t("select"), d, DialogModes.NO);
    } else {
      (r = new ActionReference()).putEnumerated(s2t("layer"), s2t('ordinal'), s2t('targetEnum'));
      (d = new ActionDescriptor()).putReference(s2t('target'), r);
      executeAction(s2t('selectNoLayers'), d, DialogModes.NO);
    }
  }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 06, 2024 Nov 06, 2024

Copy link to clipboard

Copied

This is wild, thanks! I'm going to study this code, much appreciated

This JSX feature works awesome with Generate Image Assets plugin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 06, 2024 Nov 06, 2024

Copy link to clipboard

Copied

LATEST

I've adjusted the code a bit to check to see if there is a mask and if it doesn't apply mask to that layer



app.activeDocument.suspendHistory('Add reveal all layer mask to top-level layers...', 'setLayersWithMask()');

function setLayersWithMask() {
  // Capture the initial layer visibility and layer selection
  var currentLayersState = getLayersVisiblity();

  // Ensure that a layer is selected
  try {
    activeDocument.activeLayer.link(activeDocument.activeLayer);
  } catch (e) { }

  // Loop over the root/top-level layers (change artLayers to layers to include groups)
  for (var i = 0; i < app.activeDocument.artLayers.length; i++) {
    
    app.activeDocument.activeLayer = activeDocument.artLayers[i];
    
    if(!hasChannelMaskByName(app.activeDocument.layers[i].name)){
        addMask();
    }
  }

  function addMask(apply){
    // by Stephen_A_Marsh
    if (apply == undefined) apply = false;
    try
    {
      // Add a reveal all layer mask to the layer
      function s2t(s) {
        return app.stringIDToTypeID(s);
      }
      var descriptor = new ActionDescriptor();
      var reference = new ActionReference();
      descriptor.putClass(s2t("new"), s2t("channel"));
      reference.putEnumerated(s2t("channel"), s2t("channel"), s2t("mask"));
      descriptor.putReference(s2t("at"), reference);
      descriptor.putEnumerated(s2t("using"), s2t("userMaskEnabled"), s2t("revealAll"));
      executeAction(s2t("make"), descriptor, DialogModes.NO);
        return true
    }
    catch (e)
    {
        return false
    }
  }

  /**
 * deletes layer mask from active layer
 * @Param  if apply is true, mask will be applied, if false — mask will be discarded
 * @Return boolean
 */
function deleteMask(apply)
{
    if (apply == undefined) apply = false;
    try
    {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putEnumerated(charIDToTypeID('Chnl'), charIDToTypeID('Chnl'), charIDToTypeID('Msk '));
        desc.putReference(charIDToTypeID('null'), ref);
        desc.putBoolean(charIDToTypeID('Aply'), apply);
        executeAction(charIDToTypeID('Dlt '), desc, DialogModes.NO);
        return true
    }
    catch (e)
    {
        return false
    }
};



  function hasChannelMaskByName( layerName ){
    // by Michael_L_Hale
    var ref = new ActionReference();
    ref.putName( charIDToTypeID( "Lyr " ), layerName );
    return executeActionGet( ref ).getBoolean( stringIDToTypeID( 'hasUserMask' ) );
}

  // Restore the initial layer visibility and selection
  setLayersVisiblity(currentLayersState);


  //// Functions ////

  function getLayersVisiblity() {
    // by jazz-y
    var s2t = stringIDToTypeID,
      t2s = typeIDToStringID;
    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
    r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
    var targetLayers = executeActionGet(r).getList(p),
      seletion = [],
      visiblity = {};
    for (var i = 0; i < targetLayers.count; i++) seletion.push(targetLayers.getReference(i).getIdentifier());
    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
    r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
    var len = executeActionGet(r).getInteger(p);
    for (var i = 1; i <= len; i++) {
      (r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerSection'));
      r.putIndex(s2t('layer'), i);
      if (t2s(executeActionGet(r).getEnumerationValue(p)) == 'layerSectionEnd') continue;
      (r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
      r.putIndex(s2t('layer'), i);
      var id = executeActionGet(r).getInteger(p);
      (r = new ActionReference()).putProperty(s2t('property'), p = s2t('visible'));
      r.putIndex(s2t('layer'), i);
      var visible = executeActionGet(r).getBoolean(p);
      visiblity[id] = visible;
    }
    return {
      selection: seletion,
      visiblity: visiblity
    };
  }

  function setLayersVisiblity(layersStateObject) {
    // by jazz-y
    var s2t = stringIDToTypeID;
    for (var a in layersStateObject.visiblity) {
      makeVisible = layersStateObject.visiblity[a] ? "show" : "hide";
      (r = new ActionReference()).putIdentifier(s2t('layer'), a);
      (d = new ActionDescriptor()).putReference(s2t('target'), r);
      executeAction(s2t(makeVisible), d, DialogModes.NO);
    }
    if (layersStateObject.selection.length) {
      var r = new ActionReference();
      for (var i = 0; i < layersStateObject.selection.length; i++)
        r.putIdentifier(s2t("layer"), layersStateObject.selection[i]);
      (d = new ActionDescriptor()).putReference(s2t("target"), r);
      d.putBoolean(s2t("makeVisible"), false);
      executeAction(s2t("select"), d, DialogModes.NO);
    } else {
      (r = new ActionReference()).putEnumerated(s2t("layer"), s2t('ordinal'), s2t('targetEnum'));
      (d = new ActionDescriptor()).putReference(s2t('target'), r);
      executeAction(s2t('selectNoLayers'), d, DialogModes.NO);
    }
  }

}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines