6 Replies Latest reply on May 7, 2014 5:15 PM by fableOllie

    Getting selected layers by script (object refs, not indices!)

    fableOllie

      Hey guys - I'm working on a simple photoshop CC script that exports selected layers, but I'm having some problems with the selection code.

      Googling around I found a helpful snippet that returns a list of layer index values for my selected layers - however the returned indices don't equate to the indices I get when simply using app.activeDocument.layers().

      Can anyone suggest a method to get references to the layer objects that are selected? - or perhaps a function to convert the document indices from the function below to their respective layer objects?

       

      Many thanks in advance!

       

      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++){

                     selectedLayers.push(  desc.getReference( i ).getIndex());

                }

           }else{

                var ref = new ActionReference();

                ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' ));

                ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

                selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' )));

           }

           return selectedLayers;

      }

       

      var doc = app.activeDocument;

      var layersIndx = getSelectedLayersIdx(doc);

      alert("Selected layers indx: "+layersIndx);

       

      for(i =0; i<layersIndx.length; i++){

          index= layersIndx[i];

          alert("Index: "+index+" Name: "+doc.layers[index].name);

      }

        • 1. Re: Getting selected layers by script (object refs, not indices!)
          c.pfaffenbichler Level 9

          One can select Layers by their Index, so depending on what you want to achieve the Index could work just fine.

          What exactly do you want to do with the selected Layers?

          • 2. Re: Getting selected layers by script (object refs, not indices!)
            Level 1

            Hi c. pfaffenbichler  I have through the same question What exactly do you want to do with the selected Layers?

            • 3. Re: Getting selected layers by script (object refs, not indices!)
              c.pfaffenbichler Level 9

              This would for example select each one of the originally selected Layers in turn.

              One could use that as a starting point for some DOM operation but maybe one could instead stick with Action Manager code.

              // thanks to mike hale and paul mr;

              // 2013, use it at your own risk;

              #target photoshop

              if (app.documents.length > 0) {

              var myDocument = app.activeDocument;

              myDocument.suspendHistory("operation", "main(myDocument)");

              };

              ////////////////////////////////////

              function main () {

              var theLayers = getSelectedLayersIdx();

              // do stuff;

              // reselect layers;

              for (var p = 0; p < theLayers.length; p++) {

                selectLayerByIndex(theLayers[p], false);

                alert(app.activeDocument.activeLayer);

                };

              };

              // by mike hale, via paul riggott;

              // http://forums.adobe.com/message/1944754#1944754

              function selectLayerByIndex(index,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){

              alert(e.message);

              }

              };

              ////// by paul mr;

              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;

              };

              • 4. Re: Getting selected layers by script (object refs, not indices!)
                fableOllie Level 1

                Firstly, thanks for the fast responses!

                 

                To clarify my question - the getSelectedLayersIdx() above gives a list of integers that appear to be some kind of internal ID and are not necessarily sequential (at least in my tests). Whereas the list(array?) returned by doc.layers is of course just sequentially indexed.

                So I was looking for a way to translate between the two - no idea if its actually possible or a sensible approach?

                 

                To answer your questions - after I have the layer I copy it to a new temp document and do a few ops like cropping etc. before saving/exporting it.

                 

                pfaffenbichler- thanks for the selectLayerByIndex() - I can use this to select the layer I want then copy it - and complete my script.  Is there a way to copy a layer without having to select it? (I have some very large docs that will be slowed down by this)

                 

                Thanks again for the replies - I am not very familiar with the "macro-style" photoshop commands - any pointers on reference for this would be gratefully received.

                • 5. Re: Getting selected layers by script (object refs, not indices!)
                  c.pfaffenbichler Level 9

                  This uses the other file’s name ("aaa" in this case), using an index for that, too, may be preferable to avoid problems (in case more than one open file has the same name for example), but maybe it helps.

                  // thanks to mike hale and paul mr;

                  // 2013, use it at your own risk;

                  #target photoshop

                  if (app.documents.length > 0) {

                  var myDocument = app.activeDocument;

                  myDocument.suspendHistory("operation", "main(myDocument)");

                  };

                  ////////////////////////////////////

                  function main () {

                  var theLayers = getSelectedLayersIdx();

                  // do stuff;

                  // reselect layers;

                  for (var p = 0; p < theLayers.length; p++) {

                    duplicateLayer (theLayers[p], "aaa");

                    };

                  };

                  // by mike hale, via paul riggott;

                  // http://forums.adobe.com/message/1944754#1944754

                  function selectLayerByIndex(index,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){

                  alert(e.message);

                  }

                  };

                  ////// by paul mr;

                  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;

                  };

                  function duplicateLayer (theIndex, theDoc) {

                  // =======================================================

                  var idDplc = charIDToTypeID( "Dplc" );

                      var desc7 = new ActionDescriptor();

                      var idnull = charIDToTypeID( "null" );

                          var ref3 = new ActionReference();

                      ref3.putIndex(charIDToTypeID("Lyr "), theIndex);

                      desc7.putReference( idnull, ref3 );

                      var idT = charIDToTypeID( "T   " );

                          var ref4 = new ActionReference();

                          var idDcmn = charIDToTypeID( "Dcmn" );

                          ref4.putName( idDcmn, theDoc );

                      desc7.putReference( idT, ref4 );

                      var idVrsn = charIDToTypeID( "Vrsn" );

                      desc7.putInteger( idVrsn, 5 );

                  executeAction( idDplc, desc7, DialogModes.NO );

                  };