Copy link to clipboard
Copied
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.kind != undefined) &&
(currentDoc.layers.visible == true) &&
(currentDoc.layers.kind == LayerKind.TEXT) // a text layer
)
{txtArr[txtArr.length] = currentDoc.layers.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.
Please try this...
...#target photoshop;
var tLayers = getTextInfo();
var visText = new Array();
for(var a in tLayers){
selectLayerByID(Number(tLayers[0]));
if(activeDocument.activeLayer.parent.typename == "Document"){
if(activeDocument.activeLayer.visible) visText.push([[Number(tLayers[0])],[tLayers[1]],[tLayers[2]]]);
}
if(activeDocument.activeLayer.parent.typename == "LayerSet"){
if(activeDocument.activeLayer.parent.visible == true || activeDocument.activeLayer.visible == true){
visText.push([
Copy link to clipboard
Copied
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;
};
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Please try this...
#target photoshop;
var tLayers = getTextInfo();
var visText = new Array();
for(var a in tLayers){
selectLayerByID(Number(tLayers[0]));
if(activeDocument.activeLayer.parent.typename == "Document"){
if(activeDocument.activeLayer.visible) visText.push([[Number(tLayers[0])],[tLayers[1]],[tLayers[2]]]);
}
if(activeDocument.activeLayer.parent.typename == "LayerSet"){
if(activeDocument.activeLayer.parent.visible == true || activeDocument.activeLayer.visible == true){
visText.push([[Number(tLayers[0])],[tLayers[1]],[tLayers[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;
};
Copy link to clipboard
Copied
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 .
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
SuperMerlinā
Thanks a lot for support.