Copy link to clipboard
Copied
I would like to find a way to segment my stacks automatically. For example. If I am stacking very large images, or have a folder of 100 images I would like to stack, I can run into disk space issues from the paging file and scratch disk etc. As well as not knowing if its frozen etc when processing that many images.
So Id like to say be able to break up the stacking into 4 images or x number of images at a time, provide Photoshop with a list of 100 or other large number of images, have Photoshop take the first 4 images, auto-align them, convert to smart object, set the stack mode, rasterise the smart object, save the image and close etc, then do the same for the next 4 images and so on until it works through the list of images.
Then take the resulting saved images and recursively do this until 1 final image is saved. I do not fancy having to do 4 at a time by hand and having to wait each time when I could just let it go and do something else during that time.
How would I go about this?
Copy link to clipboard
Copied
Load layers into a stack is a Photoshop script that has an interactive Dialog that you build up a file list then click on the Dialog OK button. The script will then Process the File List you put together in the scripts dialog into a new document layers stack.
The script has a function to load a file list into a new documents layer stack.
So if you a have folder of Image files that you want to load into new documents that contain 5 Images in each new document You should be able to write a Photoshop that would have you select the Folder of Images you want stacked. The Script would get the list of Image files that Photoshop Support or just the Image file types you want to stack. Once it has the list it would the process files file from the list at a time with Load Files into a Stack function that loads a list of file into a new document layers stack an theb doe youe other processing.[" convert to smart object, set the stack mode, rasterise the smart object"]. The script could leave these new documents open in photoshop or save PSD files to an output folder and closet the new document. It also look like the function supports an Align flag. So you also have that as an option... Here the function in Adobe Loads files into a Stack script line 107
Copy link to clipboard
Copied
Ive never scripted in Photoshop before, so I have no idea what to do with that
Copy link to clipboard
Copied
I cant find loadLayers in the Photoshop Javascript reference PDF, or many of the other functions used like auto align.
So from what I can tell, I need to generate a filelist (how?), then I need to write a loop that divides the filelist into a smaller filelist by whatever number I like, then inside that loop I want to load a stack, select all layers, auto align, convert to smart object, stack mode to say median, rasterise, save as a new file, add that file to a new third file list, close the file, edit->purge, and then when that loop reaches the end of the file list, reset that count, replace the file list with the new generated third file list, and let that keep going until the final generated file list only has 1 item in it.
Copy link to clipboard
Copied
I do not associate a PDF file with Photoshop. Some PDF file seen to open in Photoshop Layerd documents. However, IMO PDF are not Photoshop docyments the are acrobat documents. Photoshop can not open the PDF on my machine all photoshop can do is import pages and image from the PDF manuals.
A script has no problem getting the list of files in a Folder. When a Process a folder of file in a Photoshop script I filter the list to only contain Photoshop supported Image Files. I do not include PDF, Esp. Vector image files like .svg and .ai. I do include Camera RAW file because Photoshop will use its plugin ACR to convert the raw file into and RGB image and ACR will open a new Photoshop document containing a smart object layer or a backed layer. I can not help you process PDF file with Photoshop Automation. I have never tried. I think I may have import all the pages in a pdf. Each page opens as a new document. I had something like 100 open document. I believe a wrote a script to stack all the open page document into a new document then close all the opened page document so I was left the Photoshop that contained the PDF manual pages in a layer stack. I imported the manual using Photoshop UI.
Copy link to clipboard
Copied
I mean the javascript reference document such as here, I cant find the reference to code used https://www.adobe.com/content/dam/acom/en/devnet/photoshop/pdfs/photoshop-javascript-ref-2020.pdf
Copy link to clipboard
Copied
[ convert to smart object, set the stack mode, rasterise the smart object] when you write set the stack mode are you referring to one of the stack mode blending options. How are the Images related why 4 or 5 Are the images burst mode or time lapse images? Then recursively process the output folder till there is only one. It sounds like you want to do the 100 into a stack convert to smart object and blend. I would think breaking the process into your small groups and use auto align the output canvas sizes will vary and recursively processing these auto align may fail or the image quality degrade.
Copy link to clipboard
Copied
If you ar Processing normal Image file I think You should stack them all with Load Layers into a stack. Recursively process them is small groups I believe will develop problem. If its a resource capasity problem larger groups may worm.
theFiles = inputFolder.getFiles(/\.(nef|cr2|crw|dcs|raf|arw|orf|dng|psd|tif|jpg|png)$/i);
Copy link to clipboard
Copied
takes too much space doing it all at once, and can freeze or hang. Ive done it manually before for 100 images but sub dividing the stacking groups such as 4 lots of 25 then stacking the remaining 4, or 10 lots of 10, then the remaining 10, the number is arbitrary as long as I evenly divide it into the number of images. Results always worked out well.
For example, what code do I need to select all layers, convert to a smart object, set the stack mode. selectAllLayers seems to be an undefined function when I try to use it in my code
Copy link to clipboard
Copied
Many things you can do in Photoshop can not be scripted using Adobe Photoshop DOM code for there no method for that feature in Adobe Photoshop DOM. However if the Step you want to do can be recorder or inserhed into am Action. You can user Action Manager script code. Adobe even supplies a Plug-in the will log Action mamagers code into two logs one you desktop A VSB Log and a JavaScript Log. The code is not very readanle the thet is a JavaScript "Clean SL.jsx" the can process the JavaScript clean the code int a more readable fone of Code and Functions.
Menu Select>Select All layers will target all visible layer but the background layer.
The Scriptlistenes code will look like this:
// =======================================================
var idselectAllLayers = stringIDToTypeID( "selectAllLayers" );
var desc8 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref1.putEnumerated( idLyr, idOrdn, idTrgt );
desc8.putReference( idnull, ref1 );
executeAction( idselectAllLayers, desc8, DialogModes.NO );
Cleaned up by "Clean SL.jsx" the code looks like this:
// =======================================================
selectAllLayers();
function selectAllLayers() {
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
descriptor.putReference( charIDToTypeID( "null" ), reference );
executeAction( stringIDToTypeID( "selectAllLayers" ), descriptor, DialogModes.NO );
}
Copy link to clipboard
Copied
Ive got it working so far. I gave it a list of 13 files, and set stack number to 4, it stacks 3 sets of 4, spits out 3 new tiff files, and ignores the last one. It would recursively stack and then do the next 3. But I am having JS trouble.
When I make the initial file list its from
var folder = new Folder('D:/RAW Compare/teststack');
var flist1 = folder.getFiles('*.tif');
So the initial file list and saving files works fine.
When I try to build a new file list to replace the old one (the new files generated to stack), I use.
var nflist = new Array(); //this is outside the loop
nflist.push(saveNewTiff(false)); //inside the loop
The returned filename is correct, but doesnt work with loading new stacks, nor does nflist.push(File(filename)) etc. Still working on it.
Copy link to clipboard
Copied
Okay, my script is working now as I want it, I tested it on a set of 13 files, and set the stacknumber to 4. It stacks 3 groups of 4 images, ignores the last image, and saves 3 tiff files, then loops and stacks the remaining 3 tiff files together, saves a file, then saves a duplicate labelled FINAL_STACK to show which one it is. Work in progress, but I hope to automatically calculate the ideal stack number given a maximum stack number based on the number of images to minimise unused images.
var folder = new Folder('D:/RAW Compare/teststack');
var flist1 = folder.getFiles('*.tif');
//flist1.length = number of items
var stackDepth = 0;
var totalStackCount = 0;
var stackNumber = 4; //how many images to stack at once, you should make sure your files are evenly divisible by this
var recurseDepth = 0;
cTID = function(s) { return cTID[s] || (cTID[s] = app.charIDToTypeID(s)); };
sTID = function(s) { return app.stringIDToTypeID(s); };
const deleteRecursives = true; //delete recursive stacked images once they are finished
function runLoadStack(fileList) {
var loadLayersFromScript = true;
// @include 'Load Files into Stack.jsx'
//var fList = folder.getFiles('*.tif')
var aFlag = true;
//alert(fileList.length + " " + typeof(fileList));
loadLayers.intoStack(fileList, aFlag);
loadLayers.alignStack = function( stackDoc ){
selectAllLayers(stackDoc, 0);
}
}
function selectAllLayers2() {
var ref = new ActionReference();
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
var desc = new ActionDescriptor();
desc.putReference(cTID('null'), ref);
executeAction(sTID('selectAllLayers'), desc, DialogModes.NO);
}
function createSmartObject(){
var idnewPlacedLayer = stringIDToTypeID( 'newPlacedLayer' );
executeAction(idnewPlacedLayer, undefined, DialogModes.NO);
}
function changeStackMode(){ //set stack mode to median
var idapplyImageStackPluginRenderer = stringIDToTypeID( "applyImageStackPluginRenderer" );
var desc3 = new ActionDescriptor();
var idimageStackPlugin = stringIDToTypeID( "imageStackPlugin" );
var idmedn = charIDToTypeID( "medn" );
desc3.putClass( idimageStackPlugin, idmedn );
var idNm = charIDToTypeID( "Nm " );
desc3.putString( idNm, """Median""" );
executeAction( idapplyImageStackPluginRenderer, desc3, DialogModes.NO );
}
function rasteriseObject(){
var idrasterizeAll = stringIDToTypeID( "rasterizeAll" );
executeAction( idrasterizeAll, undefined, DialogModes.NO );
}
function saveNewTiff(fin){
var doc = app.activeDocument;
var fileName = File.decode(doc.name);
var n = fileName.lastIndexOf(".");
if (n > 0) fileName = fileName.substr(0, n);
var d = new Date();
if (fin==true){fileName="FINAL_STACK_"; }
fileName += "_" + ("00" + d.getHours()).slice(-2) + "_" + ("00" + d.getMinutes()).slice(-2)+"_"+("00" + d.getSeconds()).slice(-2) + ".tif";
fileName = folder + "/" + fileName
//saveTiff(fileName)
//alert(folder+fileName);
return saveTiff(fileName);
}
function saveTiff(filename){
tiffFile = new File(filename);
tiffSaveOptions = new TiffSaveOptions();
tiffSaveOptions.embedColorProfile = true;
tiffSaveOptions.alphaChannels = true;
tiffSaveOptions.layers = true;
tiffSaveOptions.imageCompression = TIFFEncoding.NONE;
//alert(filename);
activeDocument.saveAs(tiffFile, tiffSaveOptions, true, Extension.LOWERCASE);
return tiffFile;
}
function closeDocument(forceNotify){
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putEnumerated( s2t( "saving" ), s2t( "yesNo" ), s2t( "no" ));
descriptor.putInteger( s2t( "documentID" ), 482 );
descriptor.putBoolean( s2t( "forceNotify" ), forceNotify );
executeAction( s2t( "close" ), descriptor, DialogModes.NO );
}
function fixFilename(filename){
filename.splice(0,1); //remove leading forward slash
var drive = filename.slice(0,1);
drive = drive.toUpperCase();
filename.splice(0,2); //remove drive letter and slash
filename = drive + ":/" //fixed
return filename;
}
if (flist1.length > 1){
//check enough files for stacknumber
if (flist1.length < stackNumber){
stackNumber = flist1.length //under recursive stacking, this should ensure that final files are stacked
}
var i;
var wflist = new Array(); //working file list to split up work load
var nflist = new Array(); //folder.getFiles("*.tif"); //use this to build list of saved files for recursive
var deletelist = new Array();
//nflist.splice(0,nflist.length);
while (flist1.length > 1){
//shorten list of files
for (i = 0; i < stackNumber; i++){
wflist[i] = flist1[i];
}
//alert((wflist[0]));
//load files into stack
runLoadStack(wflist);
totalStackCount += wflist.length;
//select all layers
selectAllLayers2();
//auto align
//
//convert to smart object
createSmartObject();
//set stack mode to median
changeStackMode();
//rasterise smart object
selectAllLayers2();
rasteriseObject();
//save a file, add new file to nflist
tempfile = saveNewTiff(false); //save new tiff and return filename
nflist.push(tempfile);
//alert(nflist.length);
//deletelist.push(tempfile2);
//clear working file list array
wflist.splice(0,wflist.length);
//delete the files from full file list already stacked
flist1.splice(0, stackNumber); //should start at 0 and remove number of files stacked
stackDepth += stackNumber; //increase current stack depth by the number of files stacked
if (flist1.length < stackNumber){ //If we dont have enough files for stack number and its not final set of files then dont include them
flist1.splice(0,flist1.length);
//if we're finished, then repopulate the original file list using our saved stacked files
for (j=0; j<nflist.length; j++){ //copy array item by item
//nflist[j] = fixFilename(nflist[j]);
flist1[j] = new File(nflist[j]);
}
if (nflist.length < stackNumber){ stackNumber = nflist.length; }
nflist.splice(0,nflist.length)
//flist1 = nflist.getFiles();
//alert(typeof(flist1));
//alert(typeof(nflist));
}
//close file
if ( flist1.length <= 1){
saveNewTiff(true);
//delete temp files if possible
}
closeDocument(true);
}
m = "Files Stacked: " + totalStackCount + " nflist: " + nflist.length + " wflist: " +wflist.length + " flist1: " + flist1.length + " dfiles: " + deletelist.length;
alert(m);
}
Find more inspiration, events, and resources on the new Adobe Community
Explore Now