Skip navigation
Currently Being Moderated

Automatically re-link layer masks

Aug 17, 2012 6:22 AM

I was hoping someone might be able to help me with a question regarding linking layer masks. I regularly work on large Photoshop files with many layers and folders within folders and always have the problem moving a folder only to find that somewhere inside there was a layer with an unlinked mask and it gets left behind. Is there a way i can 'relink all layer masks' without having to manually go through and relink them all? Similar to the 'Close all folders' option i guess... Any help would be greatly appreciated.

 
Replies
  • Currently Being Moderated
    Aug 17, 2012 7:21 AM   in reply to scottyharland6
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 17, 2012 8:00 AM   in reply to scottyharland6

    This could work for Layer Masks, but not Vector Masks.

    // 2012; use it at your own risk;
    #target photoshop
    if (app.documents.length > 0) {
    linkLayerMasks(app.activeDocument)
    };
    ////// link all layer masks //////
    function linkLayerMasks (theParent) {
              for (var m = theParent.layers.length - 1; m >= 0;m--) {
                        var theLayer = theParent.layers[m];
                        app.activeDocument.activeLayer = theLayer;
                        var ref = new ActionReference();
                        ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
                        var layerDesc = executeActionGet(ref);
                        var layerMaskLinked = layerDesc.getBoolean(layerDesc.getKey(10));
    // link if unlinked;
                        if (layerMaskLinked == false) {
                                  var idsetd = charIDToTypeID( "setd" );
                                            var desc4 = new ActionDescriptor();
                                            var idnull = charIDToTypeID( "null" );
                                                      var ref2 = new ActionReference();
                                                      var idLyr = charIDToTypeID( "Lyr " );
                                                      var idOrdn = charIDToTypeID( "Ordn" );
                                                      var idTrgt = charIDToTypeID( "Trgt" );
                                                      ref2.putEnumerated( idLyr, idOrdn, idTrgt );
                                            desc4.putReference( idnull, ref2 );
                                            var idT = charIDToTypeID( "T   " );
                                                      var desc5 = new ActionDescriptor();
                                                      var idUsrs = charIDToTypeID( "Usrs" );
                                                      desc5.putBoolean( idUsrs, true );
                                            var idLyr = charIDToTypeID( "Lyr " );
                                            desc4.putObject( idT, idLyr, desc5 );
                                  executeAction( idsetd, desc4, DialogModes.NO );
                                  };
    // apply the function to layersets;
                        if (theLayer.typename == "ArtLayer") {}
                        else {
                                  linkLayerMasks(theLayer)
                                  }
                        }
              };
    
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 17, 2012 8:18 AM   in reply to scottyharland6

    I guess one could simply add a try-clause with the ScriptingListener-code for linking Vector Masks in the function linkLayerMasks

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 17, 2012 9:21 AM   in reply to scottyharland6

    Here is another version, this does not open any layersets, and should be faster as it references the layers rather than making active each one.

     

     

    #target photoshop
    app.bringToFront();
    main();
    function main(){
    if(!documents.length) return;
    linkLayers();
    }
    function linkLayers(){ 
       var ref = new ActionReference(); 
       ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); 
       var count = executeActionGet(ref).getInteger(charIDToTypeID('NmbL')) +1; 
       var Names=[];
    try{
        activeDocument.backgroundLayer;
    var i = 0; }catch(e){ var i = 1; };
       for(i;i<count;i++){ 
           if(i == 0) continue;
            ref = new ActionReference(); 
            ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
            var desc = executeActionGet(ref);
            var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
            var Id = desc.getInteger(stringIDToTypeID( 'layerID' ));
            if(layerName.match(/^<\/Layer group/) ) continue;
            if(desc.hasKey(charIDToTypeID("UsrM"))) link(i);
                }
    };
    function link(idx){
    var desc = new ActionDescriptor(); 
    var ref = new ActionReference(); 
    ref.putIndex( charIDToTypeID( "Lyr " ), idx ); 
    desc.putReference( charIDToTypeID('null'), ref ); 
    var desc2 = new ActionDescriptor(); 
    desc2.putBoolean( charIDToTypeID('Usrs'), true); 
    desc.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), desc2 ); 
    executeAction( charIDToTypeID('setd'), desc, DialogModes.NO ); 
    };
    
     
    
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 18, 2012 3:25 AM   in reply to Paul Riggott

    Not surprisingly Paul’s Script is neater.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points