Skip to main content
Inspiring
July 10, 2014
Question

Layer comps ID and name

  • July 10, 2014
  • 3 replies
  • 3683 views

Hello all,

I'm facing unusual problem currently. In CC 2014 it's now possible to switch right in main document layer comps of placed files (smart objects or linked).

Properties panel shows layer comp names of those smart objects.

But... I looked into scriptListener code and switching of layer comps in child files is done through compID. But if you want to switch layer comp in the opened file (edit contents), it is performed with layer comp name.

I need to be able to pass layer comp id from parent file to opened child file, and switch layer comp accordingly.

so, 2 questions:

1) Is it possible to switch layer comp in document by layer comp ID somehow?

2) Is it possible to get layer comp name, if you know layer comp ID (and vice versa)?

I know this information is inside image resource block in .psd file, but parsing .psd with script would be an overhead. I tried to do it with plugin, but no success yet - can't get this data inside filter plugin...

thanks!

This topic has been closed for replies.

3 replies

Known Participant
September 23, 2015

This is still a thing... I found what I *think* should be the layer comp info through the Action Manager descriptors, but it returns -1 no matter what comp is applied. I definitely have a linked smart object with a layer comp set.

      // get application description object

      var actref = new ActionReference();

      actref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

      var appDesc = executeActionGet(actref);

      // get layer count from app description

      var layerCount = appDesc.getInteger(stringIDToTypeID("numberOfLayers"));

      // process layers

      for (var l = 0; l <= layerCount; l++) {

        try {

          actref = new ActionReference();

          actref.putIndex( charIDToTypeID( "Lyr " ), l)

          layerDesc = executeActionGet(actref)

          isSmartObject = layerDesc.hasKey(stringIDToTypeID('smartObject'))

          if(isSmartObject)

          {

            // get object descriptors

            var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'))

            // var placedDesc = soDesc.getEnumerationValue(stringIDToTypeID('placed'))

            var compsDesc = soDesc.getObjectValue(stringIDToTypeID('compsList'))

            var name = layerDesc.getString(stringIDToTypeID('name'))

            var id = layerDesc.getInteger(stringIDToTypeID('layerID'))

            var fileReference = soDesc.getString(stringIDToTypeID("fileReference"))

            var compID = compsDesc.getInteger(stringIDToTypeID('compID'))

            var originalCompID = compsDesc.getInteger(stringIDToTypeID('originalCompID'))

            $.writeln ("compID: " + compID);

            $.writeln ("originalCompID: " + originalCompID);

          }

        }

      }

prints:

compID: -1

originalCompID: -1

But if I hook up generator.getDocumentInfo, I get this back:

        {

            "id": 19,

            "index": 3,

            "type": "layer",

            "name": "raster blue",

            "bounds": {

                "top": 251,

                "left": 112,

                "bottom": 353,

                "right": 302

            },

            "visible": true,

            "clipped": false,

            "generatorSettings": false,

            "smartObject": {

                "ID": "1f863200-620b-11e5-88ac-a70971fb3c91",

                "placed": "472d38d4-620b-11e5-88ac-a70971fb3c91",

                "antiAliasType": 16,

                "type": 2,

                "transform": [

                    112,

                    251,

                    302,

                    251,

                    302,

                    353,

                    112,

                    353

                ],

                "comp": 1024141590

            }

        },

So maybe it's a bug with the "compsList" ActionDescriptor object not being updated properly?

Participating Frequently
February 1, 2017

So, I figured it out... generator turned out to be a wild goose chase because the schema it prints for a document isn't the same schema that is used by ActionDescriptors. I figured out how to create a function that would print out all the keys in a descriptor:

function printKeysFromActionDesc( atnDesc )

{

    for( var i=0; i<atnDesc.count; i++ ){

        var key = atnDesc.getKey(i);

        $.writeln( typeIDToStringID(key) );

    }

}

then using this I was able to start inspecting wtf the real schema was.

the value of the currently selected layer comp on a smart object is under "smartObjectMore" > "comp"

here's some of Max's code modified:

  // get application description object

  var actref1 = new ActionReference();

  actref1.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

  var appDesc = executeActionGet(actref1);

 

  // get layer count from app description

  var layerCount = appDesc.getInteger(stringIDToTypeID("numberOfLayers"));

 

  // process layers

  for (var l = 0; l <= layerCount; l++) {

     

      var actref2 = new ActionReference();

      actref2.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

      actref2.putIndex( charIDToTypeID( "Lyr " ), l);

     

      var layerDesc;

      try{ layerDesc = executeActionGet(actref2); }

      catch(e){ continue; }

     

      var isSmartObject = layerDesc.hasKey(stringIDToTypeID('smartObject'));

      if(isSmartObject)

      {

        // get object descriptors

        var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));

        var soMoreDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObjectMore'));

        var compsDesc = soDesc.getObjectValue(stringIDToTypeID('compsList'));

        var compList = compsDesc.getList(stringIDToTypeID('compList'));

         var compObjDesc = compList.getObjectValue(2);

       

        $.writeln ( "name: " + compObjDesc.getString(stringIDToTypeID('name')) );

        $.writeln ( "id: " + compObjDesc.getInteger(stringIDToTypeID('ID')) );

        $.writeln ( "comp: " + soMoreDesc.getInteger(stringIDToTypeID('comp')) );       

      }

  }

 

Within that code block, you can see getting a layer's comp and a list of all possible comps in "compList". (NOTE: "compList" is inside "compsList")

I also suspect that within "smartObjectMore", you can get the same data as "compsList" under "compInfo"

So, I think I can answer the 2 original questions in this thread now:

1) Is it possible to switch layer comp in document by layer comp ID somehow?

Yes, if you install the ScriptListener photoshop plugin, you can see the code required to do this which looks something like:

var idsetPlacedLayerComp = stringIDToTypeID( "setPlacedLayerComp" );

    var desc11 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref9 = new ActionReference();

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref9.putEnumerated( idLyr, idOrdn, idTrgt );

    desc11.putReference( idnull, ref9 );

    var idcompID = stringIDToTypeID( "compID" );

    desc11.putInteger( idcompID, 1770071028 );

executeAction( idsetPlacedLayerComp, desc11, DialogModes.NO );

I haven't tried this myself, but I'm guessing that this code is implying that a null value means that the compID will be applied to the selected layer.

2) Is it possible to get layer comp name, if you know layer comp ID (and vice versa)?

yep, if you pull the compList as in my earlier example, you'll have an array of all the layer comps including "name" and "ID" which should give you what you need to lookup either one.

Known Participant
February 1, 2017

You, sir, deserve a medal.
giphy.gif

Inspiring
July 13, 2014

I have switched to generator api, there is all relevant data in document info.

there's info on getting data passed from extend script to generator, but I haven't seen how to make it vice versa. calling generator from extend script is described, but getting data from generator to extend script is not

c.pfaffenbichler
Community Expert
August 6, 2014
there's info on getting data passed from extend script to generator

Could you please post a link to that info?

Inspiring
August 6, 2014

Calling Generator Plugins from ExtendScript · adobe-photoshop/generator-core Wiki · GitHub

the funniest thing is that my plugin doesn't work with built-in generator anyway, only with external developer version (probably built-in is too old)

c.pfaffenbichler
Community Expert
July 13, 2014

Looks like this is another feature that it has not been deemed worthwhile to provide (reasonably convenient) Scripting support for. (edited)

And quite frankly apart from the likely performance issues I wouldn’t even know how to go about "parsing .psd" …

Maybe you should post a Feature Request for improved Scripting access to the feature over at

Photoshop Family Customer Community