Skip to main content
Known Participant
February 27, 2013
Question

python : get all selected layers

  • February 27, 2013
  • 1 reply
  • 5452 views

Hi,

I actually use python com to do some stuff in photoshop cs6.

The problem is I can get activelayer :

The problem is in actually being able to get the names of the currently selected layers

from win32com.client import Dispatch

psApp = Dispatch("Photoshop.Application")

doc = psApp.Application.ActiveDocument

print "ActiveLayer:", doc.ActiveLayer.name

But I can't find a way to get the name of all selected layers ! is there a isSelected state, or any function to get the list of all selected layers ?

Thanks

This topic has been closed for replies.

1 reply

Paul Riggott
Inspiring
February 27, 2013

Sorry I don't know python, but with JavaScript you can do this...

var sLayers = getSelectedLayersIdx();
var Names = new Array();
for (var a in sLayers){
    Names.push(getLayerNameByIndex( Number(sLayers) ) );
    }
alert(Names.join('\n'));


function getLayerNameByIndex( idx ) {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), idx );
    return executeActionGet(ref).getString(charIDToTypeID( "Nm  " ));
};
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" )));
         }
     var vis = app.activeDocument.activeLayer.visible;
        if(vis == true) app.activeDocument.activeLayer.visible = false;
        var desc9 = new ActionDescriptor();
    var list9 = new ActionList();
    var ref9 = new ActionReference();
    ref9.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    list9.putReference( ref9 );
    desc9.putList( charIDToTypeID('null'), list9 );
    executeAction( charIDToTypeID('Shw '), desc9, DialogModes.NO );
    if(app.activeDocument.activeLayer.visible == false) selectedLayers.shift();
        app.activeDocument.activeLayer.visible = vis;
      }
      return selectedLayers;
};

Nicolas.kAuthor
Known Participant
February 27, 2013

Thanks Paul, I've seen this function looking for my problem but can't manage to transform it to python.

Really strange there isn't a simple way to get this, this is really something basic and usefull ...

Nicolas.kAuthor
Known Participant
February 28, 2013

There is no clean way of doing this as the numbers come from the document descripter.

The only thing you could do is call a function to get the ID ....

alert(getSelectedLayersIdx().join('\n'));

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(getLayerIDfromIDX(  desc.getReference( i ).getIndex() ));
            }catch(e){
               selectedLayers.push(getLayerIDfromIDX(  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(getLayerIDfromIDX( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))-1));
         }catch(e){
            selectedLayers.push( getLayerIDfromIDX(executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))));
         }
     var vis = app.activeDocument.activeLayer.visible;
        if(vis == true) app.activeDocument.activeLayer.visible = false;
        var desc9 = new ActionDescriptor();
    var list9 = new ActionList();
    var ref9 = new ActionReference();
    ref9.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    list9.putReference( ref9 );
    desc9.putList( charIDToTypeID('null'), list9 );
    executeAction( charIDToTypeID('Shw '), desc9, DialogModes.NO );
    if(app.activeDocument.activeLayer.visible == false) selectedLayers.shift();
        app.activeDocument.activeLayer.visible = vis;
      }
      return selectedLayers;
};
function getLayerIDfromIDX(idx) {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), idx );
return executeActionGet(ref).getInteger(stringIDToTypeID( "layerID" ));
};


Yes it's exactly what I do actually. Not very clean, but fast anyway so yes, I will keep it like that.

I'm testing all this and will post code soon.