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);
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)
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;
};
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
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 );
}
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.
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.
- //Written by Christoph Pfaffenbichler
- // based on code by michael l hale;
- // 2012, use it at your own risk;
- #target photoshop
- var ref = new ActionReference();
- ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
- var applicationDesc = executeActionGet(ref);
- checkDesc2(applicationDesc);
- function checkDesc2 (aDesc) {
- var c = aDesc.count;
- var str = '';
- for(var i=0;i<c;i++){ //enumerate descriptor's keys
- str = str + 'Key '+i+' = '+typeIDToStringID(aDesc.getKey(i))+': '+aDesc.getType(aDesc.getKey(i))+'\n'+getValues (aDesc, i)+'\n';
- };
- $.writeln("desc\n\n"+str);
- };
- ////// check //////
- function getValues (aDesc, aNumber) {
- switch (aDesc.getType(aDesc.getKey(aNumber))) {
- case DescValueType.BOOLEANTYPE:
- return aDesc.getBoolean(aDesc.getKey(aNumber));
- break;
- case DescValueType.CLASSTYPE:
- return aDesc.getClass(aDesc.getKey(aNumber));
- break;
- case DescValueType.DOUBLETYPE:
- return aDesc.getDouble(aDesc.getKey(aNumber));
- break;
- case DescValueType.ENUMERATEDTYPE:
- return (typeIDToStringID(aDesc.getEnumerationValue(aDesc.getKey(aNumber)))+"_"+typeIDToStringID(aDesc.getEnumerationType(aDesc.getKey(aNumber))));
- break;
- case DescValueType.INTEGERTYPE:
- return aDesc.getInteger(aDesc.getKey(aNumber));
- break;
- case DescValueType.LISTTYPE:
- return aDesc.getList(aDesc.getKey(aNumber));
- break;
- case DescValueType.OBJECTTYPE:
- return (aDesc.getObjectValue(aDesc.getKey(aNumber))+"_"+typeIDToStringID(aDesc.getObjectType(aDesc.getKey(aNumber))));
- break;
- case DescValueType.REFERENCETYPE:
- return aDesc.getReference(aDesc.getKey(aNumber));
- break;
- case DescValueType.STRINGTYPE:
- return aDesc.getString(aDesc.getKey(aNumber));
- break;
- case DescValueType.UNITDOUBLE:
- return (aDesc.getUnitDoubleValue(aDesc.getKey(aNumber))+"_"+typeIDToStringID(aDesc.getUnitDoubleType(aDesc.getKey(aNumber))));
- break;
- default:
- break;
- };
- };
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?
Copy link to clipboard
Copied
@simene49649793, you may be interested in this topic: charIDToTypeID and stringIDToTypeID finder script!
Copy link to clipboard
Copied
I didn't quite understand the purpose of Christoph Pfaffenbichler's script though, nothing happens when I run it?
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.
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
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.
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
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
Copy link to clipboard
Copied
Awesome, exactly what I was hoping for! Thank you for that detailed explanation, I think I get it now