Skip to main content
New Participant
March 13, 2024
Answered

Help with writing a script to select hidden/not visible layers

  • March 13, 2024
  • 1 reply
  • 489 views

Hiya! I'm trying to automate a process that I do everytime I open a new psd with hundreds of layers. I want to select all the hidden layers and then apply a red color label to them.

I know you can do this through modifying the search functions at the top of the layer panel. 

 

I've tried using Script Listener to create a log of my process, but that resulted in just recording a select all layers and then turning everything red. It seems that filtering on Layer Panel can't be recorded?

 

var idselectAllLayers = stringIDToTypeID( "selectAllLayers" );
    var desc397 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref57 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        var idordinal = stringIDToTypeID( "ordinal" );
        var idtargetEnum = stringIDToTypeID( "targetEnum" );
        ref57.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc397.putReference( idnull, ref57 );
executeAction( idselectAllLayers, desc397, DialogModes.NO );


var idset = stringIDToTypeID( "set" );
    var desc399 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref58 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        var idordinal = stringIDToTypeID( "ordinal" );
        var idtargetEnum = stringIDToTypeID( "targetEnum" );
        ref58.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc399.putReference( idnull, ref58 );
    var idto = stringIDToTypeID( "to" );
        var desc400 = new ActionDescriptor();
        var idcolor = stringIDToTypeID( "color" );
        var idcolor = stringIDToTypeID( "color" );
        var idred = stringIDToTypeID( "red" );
        desc400.putEnumerated( idcolor, idcolor, idred );
    var idlayer = stringIDToTypeID( "layer" );
    desc399.putObject( idto, idlayer, desc400 );
executeAction( idset, desc399, DialogModes.NO );

 

 

I've also been trying to modify existing code, but that results in turning all my layers red. I appreciate any guidance or insight anyone has on this 🙂 

 

<javascriptresource> 
<name>Remove Unused Layers</name> 
<category>Delete</category>
</javascriptresource> 

#target photoshop

// Define selectLayerByIndex function
function selectLayerByIndex(index, add) {
    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) {}
}


// Define getSelectedLayersIdx function
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;
}

// Define isClippingLayer function
function isClippingLayer(layerID){
    var clipInfo=false;

    var ref = new ActionReference();
    ref.putIndex(charIDToTypeID("Lyr "), layerID);

    try{
        var desc = executeActionGet(ref);
    } catch(e) {
        // Not a valid layer
        return clipInfo;
    }

    var group = desc.getBoolean(stringIDToTypeID('group'));
    if(group) clipInfo = 'topClippingLayer';

    try{
        var ref = new ActionReference();
        ref.putIndex(charIDToTypeID('Lyr '), layerID+1);
        desc =  executeActionGet(ref);
    }catch(e){
        //alert("Top layer!");
        return clipInfo;
    }

    group = desc.getBoolean(stringIDToTypeID('group'));
    if(group && clipInfo == 'topClippingLayer' ) clipInfo = 'middleClippingLayer';
    if(group && clipInfo == false ) clipInfo = 'bottomClippingLayer';
    return clipInfo;
}


// Define deselectLayers function
function deselectLayers() {
    var desc01 = new ActionDescriptor();
    var ref01 = new ActionReference();
    ref01.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc01.putReference( charIDToTypeID('null'), ref01 );
    executeAction( stringIDToTypeID('selectNoLayers'), desc01, DialogModes.NO );
}

// Define selectAllLayers function
function selectAllLayers() {
    var desc29 = new ActionDescriptor();
    var ref23 = new ActionReference();
    ref23.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
    desc29.putReference(charIDToTypeID('null'), ref23);
    executeAction(stringIDToTypeID('selectAllLayers'), desc29, DialogModes.NO);
}

// Define main function
function main(){
    app.displayDialogs = DialogModes.NO;
    var layercomps = false;
    if(!documents.length) return;
    var doc = app.activeDocument;
    if(!doc.saved){
        if(!confirm("Your document is not saved. \nAre you sure you want to continue?")){
            return;
        }
    }
   

    // Remove all invisible layers
    // Collect all layers and save the layer ID and Keep flag
    selectAllLayers();
    var layersSelected = getSelectedLayersIdx();
    var layerIDs = [];
    for(var d = 0; d < layersSelected.length; d++){
        layerIDs.push([layersSelected[d], "N"]);
    }
    deselectLayers();

    // We need to make sure clipping layers are selected too
    var clippingLayerIDs = [];
    for(var l in layerIDs) {
        if(layerIDs[l][1].toString() == "N") {
            var LID = Number(layerIDs[l][0]); // Layer ID
            var clipInfo = isClippingLayer( LID );
            if(clipInfo == 'bottomClippingLayer'){
                LID++; // Move on to the layers in question
                while ( isClippingLayer(LID) ) {
                    clipInfo = isClippingLayer( LID );
                    // Make sure we are not moving into the next clipping group!
                    if(clipInfo != 'bottomClippingLayer'){
                        clippingLayerIDs.push([LID, "N"]);
                        LID++;
                    } else {
                        break; // while loop
                    }
                }
            }
        }
    }
    layerIDs = layerIDs.concat(clippingLayerIDs);



    // Select all layers to be deleted
    deselectLayers();
    var layersSelected = false;
    for(var l in layerIDs) {
        if(layerIDs[l][1].toString() == "N") {
            selectLayerByIndex(Number(layerIDs[l][0]), true);
            layersSelected = true;
        }
    }
    // Apply red layer color label to selected layers
    if(layersSelected) {
        setLayerLabelCol("red");
    }

 

    alert("Done applying red layer color label to hidden layers!");
}

// Define isLocked function

function isLocked(myLayer){
    selectLayerByIndex(myLayer);

    if(activeDocument.activeLayer.allLocked || activeDocument.activeLayer.pixelsLocked || activeDocument.activeLayer.positionLocked || activeDocument.activeLayer.transparentPixelsLocked){
        return true;
    }
    return false;
}

// Define setLayerLabelCol function

function setLayerLabelCol(labelCol) {
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();
    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(c2t("null"), reference);
    descriptor2.putEnumerated(s2t("color"), s2t("color"), s2t(labelCol));
    descriptor.putObject(s2t("to"), s2t("layer"), descriptor2);
    executeAction(s2t("set"), descriptor, DialogModes.NO);
}

// Add other helper functions here...


try{
    main();
} catch(err) {
    alert(err);
}

 

This topic has been closed for replies.
Correct answer yll3m

Whoa! You're a wizard thanks for the help. I ran the code and it worked out for all top level layers. I made a small modifcation to make it look for hidden layer nested within groups. What do you think? 

#target photoshop

// Create an empty array to hold the invisible layers
var invisibleLayers = [];

// Function to recursively search for invisible layers
function findInvisibleLayers(layers) {
    for (var i = 0; i < layers.length; i++) {
        var currentLayer = layers[i];
        
        // Check if the current layer is a group
        if (currentLayer.typename === "LayerSet") {
            // If it's a group, recursively search its layers
            findInvisibleLayers(currentLayer.layers);
        } else {
            // Check if the layer is invisible
            if (!currentLayer.visible) {
                invisibleLayers.push(currentLayer);
            }
        }
    }
}

// Start the search from the top-level layers
findInvisibleLayers(app.activeDocument.layers);

// Set the label color for each invisible layer
if (invisibleLayers.length > 0) {
    for (var j = 0; j < invisibleLayers.length; j++) {
        var theLayer = invisibleLayers[j];
        app.activeDocument.activeLayer = theLayer;
        setLayerLabelCol("red");
        theLayer.visible = false; // Set the layer's visibility back to invisible
    }
} else {
    alert("No invisible layers found.");
}

///// FUNCTIONS /////

function setLayerLabelCol(labelCol) {
    // "none","red","orange","yellowColor","grain","blue","violet","gray" - new in 2024: "magenta", "seafoam", "indigo", "fuchsia"
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();
    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(c2t("null"), reference);
    descriptor2.putEnumerated(s2t("color"), s2t("color"), s2t(labelCol));
    descriptor.putObject(s2t("to"), s2t("layer"), descriptor2);
    executeAction(s2t("set"), descriptor, DialogModes.NO);
}

1 reply

Stephen Marsh
Community Expert
March 13, 2024
quote

Hiya! I'm trying to automate a process that I do everytime I open a new psd with hundreds of layers. I want to select all the hidden layers and then apply a red color label to them... It seems that filtering on Layer Panel can't be recorded?

 


By @yll3m

 

That's correct, a general guide is that if you can't record it into an action, then the ActionManager code that ScriptingListener creates also can't be recorded.

 

You can try the following script. It may be slow on large layer counts – a more advanced scripter than I could likely code this faster.

 

/*
Set All Invisible Layers to Red Layer Label Colour.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/help-with-writing-a-script-to-select-hidden-not-visible-layers/td-p/14487818
v1.0, 14th March 2024, Stephen Marsh
*/

#target photoshop

// Create an empty array to hold the invisible layers
var invisibleLayers = [];

// Loop over the top-level layers
for (var i = 0; i < app.activeDocument.layers.length; i++) {
    var theLayer = app.activeDocument.layers[i];
    // Check if the layer is invisible
    if (isLayerInvisible(theLayer)) {
        invisibleLayers.push(theLayer);
    }
}

// Set the invisible layer to the red label colour
if (invisibleLayers.length > 0) {
    for (var j = 0; j < invisibleLayers.length; j++) {
        var theLayer = invisibleLayers[j];
        var layerName = theLayer.name;
        // Select the invisible layer
        app.activeDocument.activeLayer = theLayer;
        // Set the label color
        setLayerLabelCol("red");
        // Set the selected layer visibility back to invisible
        theLayer.visible = false;
    }
} else {
    alert("No invisible layers found.");
}


///// FUNCTIONS /////

function isLayerInvisible(theLayer) {
    return !theLayer.visible;
}

function setLayerLabelCol(labelCol) {
    // "none","red","orange","yellowColor","grain","blue","violet","gray" - new in 2024: "magenta", "seafoam", "indigo", "fuchsia"
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();
    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(c2t("null"), reference);
    descriptor2.putEnumerated(s2t("color"), s2t("color"), s2t(labelCol));
    descriptor.putObject(s2t("to"), s2t("layer"), descriptor2);
    executeAction(s2t("set"), descriptor, DialogModes.NO);
}

 

yll3mAuthorCorrect answer
New Participant
March 13, 2024

Whoa! You're a wizard thanks for the help. I ran the code and it worked out for all top level layers. I made a small modifcation to make it look for hidden layer nested within groups. What do you think? 

#target photoshop

// Create an empty array to hold the invisible layers
var invisibleLayers = [];

// Function to recursively search for invisible layers
function findInvisibleLayers(layers) {
    for (var i = 0; i < layers.length; i++) {
        var currentLayer = layers[i];
        
        // Check if the current layer is a group
        if (currentLayer.typename === "LayerSet") {
            // If it's a group, recursively search its layers
            findInvisibleLayers(currentLayer.layers);
        } else {
            // Check if the layer is invisible
            if (!currentLayer.visible) {
                invisibleLayers.push(currentLayer);
            }
        }
    }
}

// Start the search from the top-level layers
findInvisibleLayers(app.activeDocument.layers);

// Set the label color for each invisible layer
if (invisibleLayers.length > 0) {
    for (var j = 0; j < invisibleLayers.length; j++) {
        var theLayer = invisibleLayers[j];
        app.activeDocument.activeLayer = theLayer;
        setLayerLabelCol("red");
        theLayer.visible = false; // Set the layer's visibility back to invisible
    }
} else {
    alert("No invisible layers found.");
}

///// FUNCTIONS /////

function setLayerLabelCol(labelCol) {
    // "none","red","orange","yellowColor","grain","blue","violet","gray" - new in 2024: "magenta", "seafoam", "indigo", "fuchsia"
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();
    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(c2t("null"), reference);
    descriptor2.putEnumerated(s2t("color"), s2t("color"), s2t(labelCol));
    descriptor.putObject(s2t("to"), s2t("layer"), descriptor2);
    executeAction(s2t("set"), descriptor, DialogModes.NO);
}
Stephen Marsh
Community Expert
March 14, 2024

I think that's great! As your original screenshot didn't indicate that there were groups I didn't go the extra mile!