• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Iterating through all layers extremely slow

Explorer ,
Dec 18, 2016 Dec 18, 2016

Copy link to clipboard

Copied

I've attached a snipped that changes antialising on all text layers to "Smooth", on both hidden and unhidden layers.

The problem is that this is extreeemely slow, so I'm wondering if there is any way to make this faster? Also, is there an easy way to be able to see a progressbar when running the function?

// FUNCTION: APPLY FONT CHANGES

function fnChangeAntiAlias(target)

{

    // Get the layers of the active document

    var docLayers = target.layers;

    // For each layer in the document

    for (var i = 0; i < docLayers.length; i++)

    {

        // If the current layer is a LayerSet

        if (docLayers.typename == "LayerSet")

        {

            // Recursive: Re-run function with the current LayerSet as target

            fnChangeAntiAlias(docLayers);

        }

        // Else if the current layer is a text layer

        else if (docLayers.kind == LayerKind.TEXT)

        {

              docLayers.textItem.antiAliasMethod = AntiAlias.SMOOTH;

        };

    };

};

// Get the active document

var doc = app.activeDocument;

// Execute the function

fnChangeAntiAlias(doc);

TOPICS
Actions and scripting

Views

2.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Dec 18, 2016 Dec 18, 2016

This should be a bit faster.

#target photoshop;

if(documents.length){

var tLayers = getTextIds();

for(var a in tLayers){

selectLayerByID(Number(tLayers));

activeDocument.activeLayer.textItem.antiAliasMethod = AntiAlias.SMOOTH;

}

alert("All Done");

};

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)

...

Votes

Translate

Translate
Adobe
Guide ,
Dec 18, 2016 Dec 18, 2016

Copy link to clipboard

Copied

This should be a bit faster.

#target photoshop;

if(documents.length){

var tLayers = getTextIds();

for(var a in tLayers){

selectLayerByID(Number(tLayers));

activeDocument.activeLayer.textItem.antiAliasMethod = AntiAlias.SMOOTH;

}

alert("All Done");

};

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 getTextIds(){

   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 TextIDs=[];

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' ));

    TextIDs.push(ID);

}

   };

return TextIDs;

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 18, 2016 Dec 18, 2016

Copy link to clipboard

Copied

Haha, a bit? It went 100x faster now, thank you sir!

I gotta say though, ActionScripts looks cryptic to me, could you point me in a direction to learn about it?

Thanks again man, much appreciated

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 18, 2016 Dec 18, 2016

Copy link to clipboard

Copied

This should be a bit faster.

That should be a lot faster! The only downside I see is that it has to select the layer and set the "smooth" property using Photoshop's API, which can be a little slow.

SuperMerlin​, I made some adjustments to your code to set the smooth property through Descriptors without selecting layers, and using the layerIds you gathered. it should be a bit faster

#target photoshop

if(documents.length) { 

    var tLayers = getTextIds();

   

    for(var a = 0; a < tLayers.length; a++) { 

        setTextLayerToSmooth(tLayers);

    }

   

    alert("All Done"); 

}; 

function getTextIds() {

    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 TextIDs = [];

    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' ));

            TextIDs.push(ID);

        }

    }

    return TextIDs;

}

function setTextLayerToSmooth(layerId) {

    var antiAliasDesc = new ActionDescriptor();

    var antiAliasRef = new ActionReference();

    antiAliasRef.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "AntA" ) );

    antiAliasRef.putIdentifier( charIDToTypeID( "TxLr" ), layerId );

    antiAliasDesc.putReference( charIDToTypeID( "null" ), antiAliasRef );

    antiAliasDesc.putEnumerated( charIDToTypeID( "T   " ), charIDToTypeID( "Annt" ), charIDToTypeID( "AnSm" ) );

    executeAction( charIDToTypeID( "setd" ), antiAliasDesc, DialogModes.NO );

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 19, 2016 Dec 19, 2016

Copy link to clipboard

Copied

Yes you are right! But one thing I hate doing is woking with text in action manager since CS5, CS6 was a nightmare when it was first released and still has problems. As for the latest versions I do not know as my last version is CS6.

So anything action manager with text needs to be tested on the version it is to be used on.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 19, 2016 Dec 19, 2016

Copy link to clipboard

Copied

There is no easy way of learing Action Manager code, you need to delve into thr descriptors

Christoph wrote some hany code for looking at a layers descriptor.

It should give you a start.

  1. //Written by Christoph Pfaffenbichler 
  2. // based on code by michael l hale; 
  3. // 2012, use it at your own risk; 
  4. #target photoshop 
  5. var ref = new ActionReference(); 
  6. ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );  
  7. var applicationDesc = executeActionGet(ref); 
  8. checkDesc2(applicationDesc); 
  9.  
  10. function checkDesc2 (aDesc) { 
  11. var c = aDesc.count; 
  12. var str = ''
  13. for(var i=0;i<c;i++){ //enumerate descriptor's keys 
  14.           str = str + 'Key '+i+' = '+typeIDToStringID(aDesc.getKey(i))+': '+aDesc.getType(aDesc.getKey(i))+'\n'+getValues (aDesc, i)+'\n'; 
  15.           }; 
  16. $.writeln("desc\n\n"+str); 
  17. }; 
  18. ////// check ////// 
  19. function getValues (aDesc, aNumber) { 
  20. switch (aDesc.getType(aDesc.getKey(aNumber))) { 
  21. case DescValueType.BOOLEANTYPE: 
  22. return aDesc.getBoolean(aDesc.getKey(aNumber)); 
  23. break; 
  24. case DescValueType.CLASSTYPE: 
  25. return aDesc.getClass(aDesc.getKey(aNumber)); 
  26. break; 
  27. case DescValueType.DOUBLETYPE: 
  28. return aDesc.getDouble(aDesc.getKey(aNumber)); 
  29. break; 
  30. case DescValueType.ENUMERATEDTYPE: 
  31. return (typeIDToStringID(aDesc.getEnumerationValue(aDesc.getKey(aNumber)))+"_"+typeIDToStringID(aDesc.getEnumerationType(aDesc.getKey(aNumber)))); 
  32. break; 
  33. case DescValueType.INTEGERTYPE: 
  34. return aDesc.getInteger(aDesc.getKey(aNumber)); 
  35. break; 
  36. case DescValueType.LISTTYPE: 
  37. return aDesc.getList(aDesc.getKey(aNumber)); 
  38. break; 
  39. case DescValueType.OBJECTTYPE: 
  40. return (aDesc.getObjectValue(aDesc.getKey(aNumber))+"_"+typeIDToStringID(aDesc.getObjectType(aDesc.getKey(aNumber)))); 
  41. break; 
  42. case DescValueType.REFERENCETYPE: 
  43. return aDesc.getReference(aDesc.getKey(aNumber)); 
  44. break; 
  45. case DescValueType.STRINGTYPE: 
  46. return aDesc.getString(aDesc.getKey(aNumber)); 
  47. break; 
  48. case DescValueType.UNITDOUBLE: 
  49. return (aDesc.getUnitDoubleValue(aDesc.getKey(aNumber))+"_"+typeIDToStringID(aDesc.getUnitDoubleType(aDesc.getKey(aNumber)))); 
  50. break; 
  51. default:  
  52. break; 
  53. }; 
  54. }; 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 19, 2016 Dec 19, 2016

Copy link to clipboard

Copied

So the way people are learning this is by using the Script Listener, then trying to remove parts from the code, re-run etc? Is there no good documentation on this? Is there at least some reference for the shortnames, like "Prpr" = Property, "NmbL" = Number of layers?

Another thing I'm wondering about, how is scripting in Photoshop between different versions? Will you normally have to make changes on both Javascripts and ActionManagerScripts when a new Photoshop version comes out? Or is Javascript "safer" to use in that regard?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 24, 2016 Dec 24, 2016

Copy link to clipboard

Copied

LATEST

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 19, 2016 Dec 19, 2016

Copy link to clipboard

Copied

I didn't quite understand the purpose of Christoph Pfaffenbichler's script though, nothing happens when I run it?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 19, 2016 Dec 19, 2016

Copy link to clipboard

Copied

The code should be copied and pasted into ExtendScript Toolkit.

You should have a document open with a layer selected, then run the code from within ExtendScript Toolkit (ESTK) in the console window it will show you the results.

There is a huge amount of information to be found at:-

Tonton Pixel | Blog of Michel MARIANI aka “Mikaeru”

Code needs to be tested on the version(s) it is intended to be run on, there are some major changes between versions.

Good luck.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 19, 2016 Dec 19, 2016

Copy link to clipboard

Copied

Thank you for all your help SuperMerlin, it's very enlightening, it doesn't seem there's a vast amount of people knowing much about this topic. I'll try to put two more questions in if you haven't lost your patience with me yet

I'm wondering about these three commands:

actionRef.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( 'NmbL' ));

actionRef.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

var count = executeActionGet(actionRef).getInteger(charIDToTypeID('NmbL')) +1;

Could you explain what they do? From what I understand the putProperty assigns the value "NumberOfLayers" to the class "Property". I have no idea what putEnumerated do. The executeActionGet will return the number of layers because of the putProperty, right? I'm sorry if these are stupid questions, I'm just struggling to wrap my mind around how this works just my looking at the code I've looked around on several scripts on github, but it seems noone make comments in their ActionManager code?

Thanks man, I really appreciate the help you have given me

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 20, 2016 Dec 20, 2016

Copy link to clipboard

Copied

Yes, the putProperty is the only property we want from the Document descriptor.

'Dcmn' = Document

The number of layers returned includes TWO entries for each layerset, one for the start and one for the end of the layerset.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 22, 2016 Dec 22, 2016

Copy link to clipboard

Copied

I'm sorry, I'm still confused So I tried removing the putProperty, and the script still worked, do I even need this? It doesn't seem to do anything?

Also, putEnumerated, could you explain what this actually does? I pass in the argument for document, ordinal and target, when I've done that I can get the number of layers by using executeActionGet(actionRef).getInteger(charIDToTypeID('NmbL')), but as I don't need putProperty to add the 'NmbL' property, why can I still get the number of layers?

If I just knew exactly what putEnumerated did it would be a lot easier to understand how this hangs together

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 22, 2016 Dec 22, 2016

Copy link to clipboard

Copied

Ok, the putProperty is there to select ONLY this property from the action descriptor, and with this line included it can/does speed the process of getting the infomation.

The putEnumerated is the setup to get the descriptor inforation.

executeActionGet goes and fetchs the information.

Experiment with Chistoph's code abobe.

change

//layer information

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

to

//document information

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

also

//Current app

ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 

These will show what is available, if you add the putProperty line in Christoph's code you will see it only retrieves that property.

actionRef.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( 'NmbL' ));

actionRef.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

Keep trying

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 22, 2016 Dec 22, 2016

Copy link to clipboard

Copied

Awesome, exactly what I was hoping for! Thank you for that detailed explanation, I think I get it now

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines