Skip to main content
Participant
May 6, 2014
Answered

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

  • May 6, 2014
  • 2 replies
  • 9166 views

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;

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

}

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

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

, "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 );

};

2 replies

c.pfaffenbichler
Community Expert
Community Expert
May 6, 2014

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

, 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;

};

Participant
May 6, 2014

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.

c.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.

c.pfaffenbichler
Community Expert
c.pfaffenbichlerCommunity ExpertCorrect answer
Community Expert
May 7, 2014

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

, "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 );

};

c.pfaffenbichler
Community Expert
Community Expert
May 6, 2014

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?

May 6, 2014

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