6 Replies Latest reply on Dec 7, 2016 12:33 AM by mohans007

    Reading text layer content takes too much time in large psd files

    mohans007

      Hi  All,

      I am trying to write a script which reads text content from visible text layers.
      I have multiple Photoshop files which varies in size from ~50 MB to ~500 MB.
      These files contain several text layers and other type of layers as well.

      I have to read text data from visible text layers only. Following is the code snippet I am using for this:

       

      var currentDoc = app.activeDocument;
      var numLayers = currentDoc.layers.length;
       var txtArr = new Array();
      
      for(var i = 0; i < numLayers; i++)
       {
        if((currentDoc.layers[i].kind != undefined) &&
         (currentDoc.layers[i].visible == true) &&
         (currentDoc.layers[i].kind == LayerKind.TEXT) // a text layer
          )
        {
         txtArr[txtArr.length] = currentDoc.layers[i].textItem.contents;
        }
       }
      

       

      Depending upon the size and number of layers in PSD file, it takes up to 5 - 6 minutes to complete the task, some time even more!

      I also tried to access file in binary mode to get the text data faster, and for this I refered to "Photoshop File Format Specification", but it seems structure given there may not be updated.
      Of course, there is chances that I might not used the structure correctly in script.
      But my concern is, in any way can I access the text layer data faster (in seconds rather than in minutes)?

       

      System configuration:

      Photoshop Version: Photoshop CC 2014 (64 bit)

       

      Operating system: Windows 7 - 64 bit

      Processor: Intel(R) Xeon(R) CPU E5-1680 v3 @ 3.20 GHz

      RAM: 32 GB

       

      Thanks in advance for your support.

        • 1. Re: Reading text layer content takes too much time in large psd files
          SuperMerlin Level 5

          This example will return the layer id, layer name and layer text for text layers that are visible.

           

          #target photoshop;
          
          alert(getTextInfo().join('\n'));
          
          function getTextInfo(){ 
             var ref = new ActionReference(); 
             ref.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( 'NmbL' ));
             ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); 
             var count = executeActionGet(ref).getInteger(charIDToTypeID('NmbL')) +1; 
             var TextDetails=[];
          try{
              activeDocument.backgroundLayer;
          var i = 0; }catch(e){ var i = 1; };
             for(i;i<count;i++){ 
                 if(i == 0) continue;
                  ref = new ActionReference(); 
                  ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
                  var desc = executeActionGet(ref);
                  if( desc.hasKey( stringIDToTypeID( 'textKey' ) ) ){
                   var ID = desc.getInteger(stringIDToTypeID( 'layerID' ));
                  var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
                  var descText = desc.getObjectValue(stringIDToTypeID('textKey'));
                  var contents = descText.getString( stringIDToTypeID('textKey'));
                  var vis = desc.getBoolean(charIDToTypeID( 'Vsbl' ));
              if(vis) TextDetails.push([[ID],[layerName],[contents]]);
          }
             }; 
          return TextDetails;
          };
          
          
          
          
          2 people found this helpful
          • 2. Re: Reading text layer content takes too much time in large psd files
            mohans007 Level 1

            SuperMerlin

            Superb!

            Your code reduces the reading time drastically (minutes to seconds)!

             

            The only problem now I am facing is, the layers are grouped and by switching off visibility of a group doesn't change visibility property of the layers under it. So the function is reading text data from those layers as well.

            If I switch off visibility of undesired text layers one-by-one then the function works perfectly. But it would be difficult in my case as there are multiple groups in each file and multiple layers in each group.

             

            Really impressed with the way you have used descriptors and action references. And I am sure you must have solution for this problem also.

            Thanks again for your kind support.

            • 3. Re: Reading text layer content takes too much time in large psd files
              SuperMerlin Level 5

              Please try this...

               

              #target photoshop;
              
              var tLayers = getTextInfo();
              var visText = new Array();
              for(var a in tLayers){
              selectLayerByID(Number(tLayers[a][0]));
              if(activeDocument.activeLayer.parent.typename == "Document"){
                  if(activeDocument.activeLayer.visible) visText.push([[Number(tLayers[a][0])],[tLayers[a][1]],[tLayers[a][2]]]);
                  }
              if(activeDocument.activeLayer.parent.typename == "LayerSet"){
              if(activeDocument.activeLayer.parent.visible  == true || activeDocument.activeLayer.visible == true){
                  visText.push([[Number(tLayers[a][0])],[tLayers[a][1]],[tLayers[a][2]]]);
                  }
              }
              }
              alert(visText.join('\n'));
              
              function selectLayerByID(ID, add) {
                  add = (add == undefined)  ? add = false : add;
                  var ref = new ActionReference();
                  ref.putIdentifier(charIDToTypeID('Lyr '), ID);
                  var desc = new ActionDescriptor();
                  desc.putReference(charIDToTypeID('null'), ref);
                  if (add) {
                      desc.putEnumerated(stringIDToTypeID('selectionModifier'), stringIDToTypeID('selectionModifierType'), stringIDToTypeID('addToSelection'));
                  }
                  desc.putBoolean(charIDToTypeID('MkVs'), false);
                  executeAction(charIDToTypeID('slct'), desc, DialogModes.NO);
              };
              
              function getTextInfo(){ 
                 var ref = new ActionReference(); 
                 ref.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( 'NmbL' ));
                 ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); 
                 var count = executeActionGet(ref).getInteger(charIDToTypeID('NmbL')) +1; 
                 var TextDetails=[];
              try{
                  activeDocument.backgroundLayer;
              var i = 0; }catch(e){ var i = 1; };
                 for(i;i<count;i++){ 
                     if(i == 0) continue;
                      ref = new ActionReference(); 
                      ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
                      var desc = executeActionGet(ref);
                      if( desc.hasKey( stringIDToTypeID( 'textKey' ) ) ){
                       var ID = desc.getInteger(stringIDToTypeID( 'layerID' ));
                      var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
                      var descText = desc.getObjectValue(stringIDToTypeID('textKey'));
                      var contents = descText.getString( stringIDToTypeID('textKey'));
                      var vis = desc.getBoolean(charIDToTypeID( 'Vsbl' ));
                  TextDetails.push([[ID],[layerName],[contents]]);
              }
                 }; 
              return TextDetails;
              };
              
              
              
              
              
              
              1 person found this helpful
              • 4. Re: Reading text layer content takes too much time in large psd files
                Nikhil Katyan

                SuperMerlin can you please suggest some tutorials where I can learn extendscript scripting. I got a few links but found nothing about how to use Action references and descriptors. It would be really helpful. Thanks in advance .

                • 5. Re: Reading text layer content takes too much time in large psd files
                  SuperMerlin Level 5

                  Sorry but there isn't any documentation, except what is supplied with Photoshop, this site, and, https://www.ps-scripts.com

                  A good place to start is to study xbytors set of tools.. xtools

                  It's an uphill battle, but keep trying, you will get there.