1

I'm writing a script that looks for layers with a certain name in a document, and I need it to then check if it has any clipping masks applied to it, and select them all, so that I can merge and export them. I have lots of these layers littered through a PSD, with multiple PSDs. So doing this will hopefully save a tonne of time.

The issue I'm having is with the identifying clipping masks. I've looked through the reference files and I can't find anything relevant to them. Is there any way of doing this? Am I missing something here?

Here is the beginning of my code:

var doc = app.activeDocument  
var ratios = ["1/1", "4/3", "3/4", "3/2", "2/3", "16/9", "9/3", "7/2", "11/5"];  

for (var i = 0, il = doc.layers.length; i < il; i++) {  
    var curLayer = doc.layers[i];  
    for (var j = 0, jl = ratios.length; j < jl; j++) {  
        if (curLayer.name == ratios[j]) {  
            alert(curLayer.name); 
            // Check for clipping masks attached to this layer
        }
    }  
} 

Thanks for all your help!

  • I don't know about this specifically, but it's not unusual in a hierarchy for parent items to know virtually nothing about their children; all of the relationship info belongs to the child items. – Stan Rogers Jan 30 '16 at 4:55
1

I have a feeling that you could do that with ActionReference, but I've got no idea how.

...however, I wrote this script that should work, but it's also kind of stupid...

Both of these are based on the knowledge that if you group a Clipping mask base layer, it groups it and every single layer attached to it. This is the only type of layer that acts this way. So if you then check the group length and it's bigger than 1, then the layer must be the base layer of a clipping mask.

I put the first script here to illustrate the basic idea. The second script is an extended version of the first one.

This first script returns true if the current layer is the base layer of a clipping mask:

function clippingMaskBaseLayer() {

    var doc = app.activeDocument;

    app.runMenuItem( stringIDToTypeID('groupLayersEvent') );

    var clippingmask = doc.activeLayer.layers.length > 1 ? true : false;

    executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );

    return clippingmask;

}

This script gives you every layer in the clipping mask, except the base layer:

function clippingMaskLayers() {

    var doc = app.activeDocument;

    app.runMenuItem( stringIDToTypeID('groupLayersEvent') );

    var group = doc.activeLayer,
        groupLength = group.layers.length,
        clippingmask = groupLength > 1 ? true : false,
        collectedLayers = [];

    if ( clippingmask ) {

        for ( var i=0; i < groupLength-1; i++ ) {
            collectedLayers.push( group.layers[i] );
        }

    }

    executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );

    if ( clippingmask ) { return collectedLayers; } else { return false; }

}

If you remove the -1 from the for loop, you'll get the base layer as well.



There's one potential issue with these scripts: If you have multiple active layers when this function runs, all active layers will get grouped and the script things you got a clipping mask there.

I wrote it this way because it's simpler and in this case it shouldn't be a problem.

0

I ended up working out another way to do it. I instead grouped the layers into a layerset, and exported them out of the document that way. For those that would like to see it, have a look here:

https://gist.github.com/BeauAgst/4da366b933cc75a0606a

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.