2 Replies Latest reply on Nov 25, 2016 11:00 AM by Jarda Bereza

    Push all selected layers EXCEPT GROUPS into an array

    barbasboth Level 1

      Hi, I've been googling for a couple of hours but can't seem to find a solution...

      I need my script to affect all _selected_ layers in a PSD. This works fine when there are no groups involved in a selection, but what I want to achieve is for the user to be able to select a mix of layers and groups, and the script would push all layers (including the ones in the groups, even if the individual layers are not selected, when a group is collapsed for example) into an array. I've been looking into the xtools scripts but network security is so tight on this work computer that I am unable to install anything to rely on those libraries & dependencies (so I have to write it myself unfortunately).Please help!

       

      At the moment this is the part of the script that is relevant:

       

       

      #target photoshop
      /*
      // Save the current preferences
      var startRulerUnits = app.preferences.rulerUnits
      var startTypeUnits = app.preferences.typeUnits
      var startDisplayDialogs = app.displayDialogs
      
      */
      app.preferences.rulerUnits = Units.PIXELS
      app.preferences.typeUnits = TypeUnits.PIXELS
      //
      
      var doc = app.activeDocument;
      var currentLayer = activeDocument.activeLayer;
      
      // Get array of selected layers within a group
      function getSelectedLayers(){
              var idGrp = stringIDToTypeID( "groupLayersEvent" );
              var descGrp = new ActionDescriptor();
              var refGrp = new ActionReference();
              refGrp.putEnumerated(charIDToTypeID( "Lyr " ),charIDToTypeID( "Ordn" ),charIDToTypeID( "Trgt" ));
              descGrp.putReference(charIDToTypeID( "null" ), refGrp );
              executeAction( idGrp, descGrp, DialogModes.ALL );
              var resultLayers=new Array();
          
              var a = app.activeDocument.activeLayer.layers.length; // establish this in advance so the function doesn't check every time
          
              for (var ix=0;ix<a;ix++){
                  alert(a[ix].name);
      //            if (a[ix].typename != "LayerSet") {
                      resultLayers.push(a[ix])
      //            }
              }
              var id8 = charIDToTypeID( "slct" );
                  var desc5 = new ActionDescriptor();
                  var id9 = charIDToTypeID( "null" );
                  var ref2 = new ActionReference();
                  var id10 = charIDToTypeID( "HstS" );
                  var id11 = charIDToTypeID( "Ordn" );
                  var id12 = charIDToTypeID( "Prvs" );
                  ref2.putEnumerated( id10, id11, id12 );
              desc5.putReference( id9, ref2 );
              executeAction( id8, desc5, DialogModes.NO);
              return resultLayers;
          
          }  
      var layersToUse = getSelectedLayers();
      
      // Loop through selected text layers
      
      for (e=0; e<layersToUse.length; e++) {
         
          currentLayer = layersToUse[e];
         
          // DO STUFF TO EACH LAYER      
      
      }
      
        • 1. Re: Push all selected layers EXCEPT GROUPS into an array
          Kukurykus Adobe Community Professional

          Not that you wanted, as you can't select many layers with my script, but just one or a group of layers what after all has to create new layer over selected layer or in selected group, but maybe you can play with it for your needs that you make somehow it will be working selecting more than one layer or/and group. Check the post from Fri Nov 18, 2016 5:45 pm in there: Creating and moving an artLayer inside "active" layerSet - Page 3 - PS-SCRIPTS.COM

          • 2. Re: Push all selected layers EXCEPT GROUPS into an array
            Jarda Bereza Level 4

            I think most easy solution could be:

             

            1) Group all selected layers (ctrl + g)

            var idMk = charIDToTypeID( "Mk  " );
                var desc24 = new ActionDescriptor();
                var idnull = charIDToTypeID( "null" );
                    var ref20 = new ActionReference();
                    var idlayerSection = stringIDToTypeID( "layerSection" );
                    ref20.putClass( idlayerSection );
                desc24.putReference( idnull, ref20 );
                var idFrom = charIDToTypeID( "From" );
                    var ref21 = new ActionReference();
                    var idLyr = charIDToTypeID( "Lyr " );
                    var idOrdn = charIDToTypeID( "Ordn" );
                    var idTrgt = charIDToTypeID( "Trgt" );
                    ref21.putEnumerated( idLyr, idOrdn, idTrgt );
                desc24.putReference( idFrom, ref21 );
                var idlayerSectionStart = stringIDToTypeID( "layerSectionStart" );
                desc24.putInteger( idlayerSectionStart, 17 );
                var idlayerSectionEnd = stringIDToTypeID( "layerSectionEnd" );
                desc24.putInteger( idlayerSectionEnd, 18 );
                var idNm = charIDToTypeID( "Nm  " );
                desc24.putString( idNm, """Group 1""" );
            executeAction( idMk, desc24, DialogModes.NO );
            

             

            2) Now your active layer is only group and contains everything as you said

            3) Go recursive all layers and folders (recursive code is in "Delete all empty layers" script (packed with Photoshop)

            4) Remember layer ID for every single layer and folder within recursive call (NOT layer index) (push layer into array)

            5) Step back in history

            var idslct = charIDToTypeID( "slct" );
                var desc26 = new ActionDescriptor();
                var idnull = charIDToTypeID( "null" );
                    var ref24 = new ActionReference();
                    var idHstS = charIDToTypeID( "HstS" );
                    var idOrdn = charIDToTypeID( "Ordn" );
                    var idPrvs = charIDToTypeID( "Prvs" );
                    ref24.putEnumerated( idHstS, idOrdn, idPrvs );
                desc26.putReference( idnull, ref24 );
            executeAction( idslct, desc26, DialogModes.NO );
            

             

            6) Your loop with array and function inside. You need select each layer one by one and select layer by ID (NOT index).

             

            The silly thing is that most function and methods works only with one selected layer. And rarely with multiple selected layers.

             

            If you are masochist and you need great performance, you can check my script "Delete all empty layers faster". It deletes all groups where are no layers or layers with zero dimensions or groups which contains groups without layers which are not locked. It doesn't use recursion and undos. Magic scripts for Photoshop