Skip to main content
RRowe
Inspiring
March 1, 2023
Answered

Script to toggle visibility of specific layers

  • March 1, 2023
  • 3 replies
  • 6075 views

I am wondering if it's possible for a script to find any and all layers in a PSD, targeting using either the layer name or the color of the layer, and turning the visibility off. If any targeted layer's visibility is already off, it would stay off and not turn on.

This topic has been closed for replies.
Correct answer c.pfaffenbichler

edited

 

// hide layer of certain color;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
    var theLayers = hideLayersOfColor ("orange");
    if (theLayers.length > 0) {
        alert (theLayers.join("\n"));
    }
};
////// collect layers //////
function hideLayersOfColor (thisColor) {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if group collect values;
    if (layerSet != "layerSectionEnd" /*&& layerSet != "layerSectionStart"*/ && isBackground != true) {
        var theName = layerDesc.getString(stringIDToTypeID('name'));
        var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
        var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
        var theColor = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("color")));
        var theVisibility = layerDesc.getBoolean(stringIDToTypeID('visible'));
//    var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
//    var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
    if (theColor == thisColor) {
        theLayers.push([theName, theIndex, theID, theColor, theVisibility]);
// hide layers;
        if (theVisibility == true) {
            var desc4 = new ActionDescriptor();
            var list1 = new ActionList();
            var ref1 = new ActionReference();
            ref1.putIdentifier( stringIDToTypeID( "layer" ), theID);
            list1.putReference( ref1 );
            desc4.putList( stringIDToTypeID( "null" ), list1 );
            executeAction( stringIDToTypeID( "hide" ), desc4, DialogModes.NO );
        }
    }
    };
    }
    catch (e) {};
    };
    return theLayers
    };

 

 

3 replies

Stephen Marsh
Community Expert
Community Expert
March 7, 2023

For sake of completeness, here is a version using the layer name rather than colour label.

 

This is looking for a case-sensitive regular expression based match including a word space either before or after the social media site name as per the layered example used in this topic for the text layers. This could just be using a text prefix such as "Hide_" or similar before the layer name.

 

/*
Hide All Social Media Named Layers.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-toggle-visibility-of-specific-layers/td-p/13618157
v1.0 - 7th March 2023, Stephen Marsh
*/

#target photoshop

function main() {

    if (!documents.length) {
        alert('There are no documents open!');
    } else {
        processAllLayersAndSets(activeDocument);
    }

    function processAllLayersAndSets(obj) {
        for (var al = obj.layers.length - 1; 0 <= al; al--) {
            activeDocument.activeLayer = obj.layers[al];
            socialmediaLayerVisibilityToFalse();
        }

        for (var ls = obj.layerSets.length - 1; 0 <= ls; ls--) {
            processAllLayersAndSets(obj.layerSets[ls]);
            socialmediaLayerVisibilityToFalse();
        }
    }

    function socialmediaLayerVisibilityToFalse() {
        try {
            if (/Facebook |Instagram |Twitter |LinkedIn | YouTube/.test(activeDocument.activeLayer.name) === true) {
                // Set the layer visibility to false
                activeDocument.activeLayer.visible = false;
            }
        } catch (e) {
            alert("Error!" + "\r" + e + ' ' + e.line);
        }
    }
}

activeDocument.suspendHistory('Hide All Social Media Named Layers...', 'main()');
RRowe
RRoweAuthor
Inspiring
March 7, 2023

Well, that covers all the ways this document may evolve. Thank you for the thorough attention on this!

Stephen Marsh
Community Expert
Community Expert
March 7, 2023

All good, I really don't like doing things by half.

Stephen Marsh
Community Expert
Community Expert
March 4, 2023

@RRowe 

 

Try this script, it would need to be written in AM code to run faster, which is beyond my current ability (I only got this far by standing on the shoulders of giants):

 

/*
Hide All Layers Labeled In Orange.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-toggle-visibility-of-specific-layers/td-p/13618157
v1.0 - 4th March 2023, Stephen Marsh
*/

#target photoshop

function main() {

    if (!documents.length) {
        alert('There are no documents open!');
    } else {
        processAllLayersAndSets(activeDocument);
    }

    function processAllLayersAndSets(obj) {
        for (var al = obj.layers.length - 1; 0 <= al; al--) {
            activeDocument.activeLayer = obj.layers[al];
            orangeLayerVisibilityToFalse();
        }

        for (var ls = obj.layerSets.length - 1; 0 <= ls; ls--) {
            processAllLayersAndSets(obj.layerSets[ls]);
            orangeLayerVisibilityToFalse();
        }
    }

    function orangeLayerVisibilityToFalse() {
        try {
            // Courtesy of Paul Riggott
            // Colors returned:
            // "none","red","orange","yellowColor","grain","blue","violet","gray"
            var ref = new ActionReference();
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            var appDesc = executeActionGet(ref);
            if (typeIDToStringID(appDesc.getEnumerationValue(stringIDToTypeID('color'))) == "orange") {
                // Set the layer visibility to false
                activeDocument.activeLayer.visible = false;
            }
        } catch (e) {
            alert("Error!" + "\r" + e + ' ' + e.line);
        }
    }
}

activeDocument.suspendHistory('Hide All Layers Labeled In Orange...', 'main()');

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

RRowe
RRoweAuthor
Inspiring
May 30, 2023

@Stephen Marsh Hello again! I've noticed something happening with this script, and taking a look at the script myself I can't see anything obvious that would be causing this issue. The script perfectly turns the visibility off of any layer labeled in orange, but it is also turning ON any layer whose visibility is off when the script is run. 

I discovered this when I duplicated your script and modified it to target any blue layers. I ran the orange layers script, it turned orange off, then ran the blue layer script. Blue layers turned off but it cause the orange layers to turn back on. I tested with other non-colored layers by turning them off before running either script and the same thing happened. Anything off when running the script gets turned on. Any ideas?

c.pfaffenbichler
Community Expert
c.pfaffenbichlerCommunity ExpertCorrect answer
Community Expert
May 30, 2023

edited

 

// hide layer of certain color;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
    var theLayers = hideLayersOfColor ("orange");
    if (theLayers.length > 0) {
        alert (theLayers.join("\n"));
    }
};
////// collect layers //////
function hideLayersOfColor (thisColor) {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if group collect values;
    if (layerSet != "layerSectionEnd" /*&& layerSet != "layerSectionStart"*/ && isBackground != true) {
        var theName = layerDesc.getString(stringIDToTypeID('name'));
        var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
        var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
        var theColor = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("color")));
        var theVisibility = layerDesc.getBoolean(stringIDToTypeID('visible'));
//    var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
//    var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
    if (theColor == thisColor) {
        theLayers.push([theName, theIndex, theID, theColor, theVisibility]);
// hide layers;
        if (theVisibility == true) {
            var desc4 = new ActionDescriptor();
            var list1 = new ActionList();
            var ref1 = new ActionReference();
            ref1.putIdentifier( stringIDToTypeID( "layer" ), theID);
            list1.putReference( ref1 );
            desc4.putList( stringIDToTypeID( "null" ), list1 );
            executeAction( stringIDToTypeID( "hide" ), desc4, DialogModes.NO );
        }
    }
    };
    }
    catch (e) {};
    };
    return theLayers
    };

 

 

Stephen Marsh
Community Expert
Community Expert
March 1, 2023

Yes it is possible.

 

please provide s sample screenshot of the before and alter layers panel to illustrate. A sample file would also be helpful as well as some specific details.

RRowe
RRoweAuthor
Inspiring
March 1, 2023

I have attached a sample PSD and two screen shots of the layers, before and after. 
As you can see in the sample file, the targeted layers are colored orange, but that could be done in any fashion. For example, instead of being orange, the layer name could be the target. Perhaps the layer name could include a specific word or phrase. Whatever targets properly. 

Stephen Marsh
Community Expert
Community Expert
March 2, 2023

The layers labeled with orange are all text layers... So no colour labels or special keywords are required if this is only for text layers.