Copy link to clipboard
Copied
Hi, so i am trying to make a script that goes goes through all the layers of an a document, sets the size of the layer to a specified width and height and export it in a separate file. I finished the script but it really really slow. I read that accessing layers from the DOM is slow and that i should use the ActionManager instead, but I can't find any documentation on how to use the ActionManager.
This is what I have so far:
Ok so right now I am creating a document with the size I want. Copy the layer I want from the current doc to the new one and save the document. When I see a group I create a folder on the Directory and call the function recursively.
var refDoc;
var tempDoc;
function main(){
refDoc = app.activeDocument;
tempDoc = app.documents.add(500, 500, 72, "tempDoc", NewDocumentMode.RGB, DocumentFill.TRANSPARENT);
app.activeDocument = refDoc;
mainFolder = app.activeDocument.path + "/test";
savetAllLayers(app.activeDocument, mainFolder);
tempDoc.close (SaveOptions.DONOTSAVECHANGES);
}
function saveAllLayers(group, folderName){
var groupFolder = new Folder(folderName)
for (var i = 0; i < group.layers.length; i++){
if (group.layers.typename.valueOf() === "LayerSet"){
var groupFolder = new Folder(folderName + "/" + group.layers.name);
if (!groupFolder.exist){
groupFolder.create();
}
saveAllLayers(group.layers, groupFolder);
}
else if (group.layers.typename.valueOf() === "ArtLayer"){
try {
app.activeDocument = refDoc;
group.layers.copy();
app.activeDocument = tempDoc;
var targetLayer = tempDoc.artLayers.add();
tempDoc.paste();
tempDoc.activeLayer.resize(500, 500);
var options = new ExportOptionsSaveForWeb();
options.fomat = SaveDocumentType.PNG;
options.PNG8 = false;
options.transparency = true;
options.optimized = true;
//Export Save for Web in the current folder
tempDoc.exportDocument(File(folderName +'/' + group.layers.name +'.png'), ExportType.SAVEFORWEB, options);
targetLayer.remove();
} catch (e){
alert("Error on layer: " + group.layers.name + "\n\n\n" + e.message);
}
}
}
return
}}
How can I use the ActionManager to achieve this? Thank you.
I don't think that AM will help to much, the time eating operation is the resize and you can't do anything with AM to make it faster,
the only think in where the AM could help is the going through layers, other than that I don't see how you can make it faster...
Here is a code with AM that will do what your function is doing, I've compared the time for both of them and there is a small improvement with AM in terms of time but it's not that much noticeable.
...
function BCM_saveAsFolders( pathname ){
Copy link to clipboard
Copied
The code in that thread is largely based on stuff Mike and Paul have provided (I may have added mistakes of my own, though) but I can’t locate the threads from which I took it.
Calculating width height in script
If you remove the lines
alert ("width: "+theWidth+", height: "+theHeight+", index: "+m+", name: "+theName);
selectLayerByIndex(m,false);
and instead collect the info in an Array for example it should run faster than the corresponding DOM code.
Maybe you should search
Copy link to clipboard
Copied
I don't think that AM will help to much, the time eating operation is the resize and you can't do anything with AM to make it faster,
the only think in where the AM could help is the going through layers, other than that I don't see how you can make it faster...
Here is a code with AM that will do what your function is doing, I've compared the time for both of them and there is a small improvement with AM in terms of time but it's not that much noticeable.
function BCM_saveAsFolders( pathname ){
refDoc1 = app.activeDocument;
var sizes = {w:500, h:500};
var tempDoc1 = app.documents.add(500,500, 72, "BCM_rrrre_tempDoc1", NewDocumentMode.RGB, DocumentFill.TRANSPARENT);
app.activeDocument = refDoc1;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
var aa = 0;
try{app.activeDocument.backgroundLayer}catch(err){aa = 1};
var count = executeActionGet(ref).getInteger(charIDToTypeID('Cnt ')) - aa;// the number of layers in the document
var x, y, r = 0;
var currentFolder = new Folder(pathname);
if(!currentFolder.exists){currentFolder.create()};
for(i = count; i >= 0 ; i--){// the recursive loop
ref = new ActionReference();
ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
try{
var desc = executeActionGet(ref);
}catch(err){ break; }
var layerName = desc.getString(charIDToTypeID( 'Nm ' ));
var Id = desc.getInteger(stringIDToTypeID( 'layerID' ));
var ls = desc.getEnumerationValue(stringIDToTypeID("layerSection"));
ls = typeIDToStringID(ls);
var vis = desc.getInteger(stringIDToTypeID( 'visible' ));r
if(ls == 'layerSectionContent'){
duplicateTotempDoc1umentAndSaveByIDX(i, (currentFolder.fullName +"/"+layerName), sizes, tempDoc1);
app.activeDocument = refDoc1;
}
if(ls == 'layerSectionStart'){// if it's the start of a layer set
currentFolder = new Folder(currentFolder.fullName +"/"+layerName);
if( !currentFolder.exists ){
currentFolder.create();
}
}
if(ls == 'layerSectionEnd'){// if it's the end of a layerSet
var cPthStr = currentFolder.fullName.toString();
currentFolder = new Folder(cPthStr.substring(0,cPthStr.lastIndexOf("/")));
}
}
tempDoc1.close (SaveOptions.DONOTSAVECHANGES);
}
function duplicateTotempDoc1umentAndSaveByIDX(idx, pathname, size, tempDoc1){
// =======================================================duplicate layer to a new document
var idDplc = charIDToTypeID( "Dplc" );
var desc57 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref47 = new ActionReference();
ref47.putIndex( charIDToTypeID( "Lyr " ), idx );
desc57.putReference( idnull, ref47 );
var idT = charIDToTypeID( "T " );
var ref48 = new ActionReference();
var idDcmn = charIDToTypeID( "Dcmn" );
ref48.putName( idDcmn, "BCM_rrrre_tempDoc1" );
desc57.putReference( idT, ref48 );
var idVrsn = charIDToTypeID( "Vrsn" );
desc57.putInteger( idVrsn, 5 );
executeAction( idDplc, desc57, DialogModes.NO );
app.activeDocument = tempDoc1;
tempDoc1.activeLayer.resize(500, 500);
var options = new ExportOptionsSaveForWeb();
options.format = SaveDocumentType.PNG;
options.PNG8 = false;
options.transparency = true;
options.optimized = true;
//Export Save for Web in the current folder
tempDoc1.exportDocument(new File(pathname +'.png'), ExportType.SAVEFORWEB, options);
tempDoc1.activeLayer.remove();
}
// var startTime = new Date().getTime();
BCM_saveAsFolders(Folder.desktop +"/test");
// var endTime = new Date().getTime();
// alert(endTime - startTime);
Copy link to clipboard
Copied
Two things you could try:
app.activeDocument.suspendHistory("Executing script, please wait...", "savetAllLayers(app.activeDocument, mainFolder)")
Copy link to clipboard
Copied
Thank you. What exactly does suspenHistory do? and should i call it?
Copy link to clipboard
Copied
Sorry, forgot this. suspendHistory tells Photoshop to run a part of script without saving the undo state for each step. Basically everything is one big undo (which is typically what you'd want in any case). Calling it gives one info text (becomes title or something) and the second parameter is a peace of Javascript you want to run like calling one function. Not 100% sure if passing parameters as references/values works.