Copy link to clipboard
Copied
I would like to automate part of my workflow that involves opening stacked images as layers in Ps CS5 and running an PS action that composites the layers and processes the image. Something similar to 'Process Collection' in Bridge CS5 only with my own action instead of merge to HDR/Panorama.
Apparently this is possible with Mac 'Automator' - is there anything I can do in Windows? I don't have any experience with writing scripts, but have friends that can help. Can someone tell me if its possible and point me in the right direction please?
For the name, I was thinking more along the lines of using the name of the first image in the stack( or top layer name ) as part of the filename.
For the action, I think it depends on the action and how the script is to be used. My tests had images stacks of three images each. The action selects the top layer, inverts, selects the layer below, inverts, selects the layer below and inverts. So it inverts all the layers because it expects there to be three layers. I guess you could script running th
...Copy link to clipboard
Copied
I get the same error. If anyone can fix this, please message me - I can pay.
Copy link to clipboard
Copied
You would have to do something on the lines of the following, I haven't tested it though.
#target bridge
if( BridgeTalk.appName == "bridge" ) {
stacksToLayers = new MenuElement("command", "Stacks To Layers", "at the end of Tools");
}
stacksToLayers.onSelect = function () {
var stacks = app.document.stacks;
var stackCount = stacks.length;
for(var s = 0;s<stackCount;s++){
var stackFiles = getStackFiles( stacks
);if(stackFiles.length> 1){
var bt = new BridgeTalk;
bt.target = "photoshop";
var myScript = ("var ftn = " + psRemote.toSource() + "; ftn("+stackFiles.toSource()+");");
bt.body = myScript;
bt.onResult = function( inBT ) {myReturnValue(inBT.body); }
bt.send(500);
}
}
function getStackFiles( stack ){
var files = new Array();
for( var f = 0; f<stack.thumbnails.length;f++){
files.push(stack.thumbnails
.spec); }
return files;
};
function myReturnValue(str){
res = str;
}
function psRemote(stackFiles){
var loadLayersFromScript = true;
var strPresets = localize ("$$$/ApplicationPresetsFolder/Presets=Presets");
var strScripts = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/Scripts=Scripts");
var strFile2Stack = "Load Files into Stack.jsx";
var ipFilePath = app.path + "/" + strPresets + "/" + strScripts + "/" + strFile2Stack;
var ipFile = new File (ipFilePath);
$.evalFile( ipFile );
loadLayers.intoStack(stackFiles);
}
};
Copy link to clipboard
Copied
Well, it loaded into bridge without any error, which is further than I've gotten so far. But now I reveal how green I am. I don't know how to run it. I don't even know if it runs from bridge or photoshop. I've googled and there are suggestions that i need to make menu item? My apologies if I belong in a beginner forum, I've been googling for an hour, I've never found anything so inscrutable.
Copy link to clipboard
Copied
To use goto the Tools menu and select "Stacks To Layers".
Copy link to clipboard
Copied
Fantastic! Philip, PM me your email so I can paypal you a tip. (I'm serious, I couldn't get anyone on freelancer to tackle this. )
Now I just need to run the action on each layered file and save the result (and close the file)
Copy link to clipboard
Copied
This should run an action on all layers, save and close the files.
You will need to change the doAction to put in your action name and action set.
No tip required, that's what these forums are for,to help each other.
#target bridge |
if( BridgeTalk.appName == "bridge" ) {
stacksToLayers = new MenuElement("command", "Stacks To Layers", "at the end of Tools");
}
stacksToLayers.onSelect = function () {
var stacks = app.document.stacks;
var stackCount = stacks.length;
for(var s = 0;s<stackCount;s++){
var stackFiles = getStackFiles( stacks | |
if(stackFiles.length> 1){ | |
var bt = new BridgeTalk; | |
bt.target = "photoshop"; | |
var myScript = ("var ftn = " + psRemote.toSource() + "; ftn("+stackFiles.toSource()+");"); | |
bt.body = myScript; | |
bt.onResult = function( inBT ) {myReturnValue(inBT.body); } | |
bt.send(500); | |
} |
}
function getStackFiles( stack ){
var files = new Array(); | |
for( var f = 0; f<stack.thumbnails.length;f++){ | |
files.push(stack.thumbnails | |
} | |
return files; |
};
function myReturnValue(str){
res = str; |
}
function psRemote(stackFiles){
var loadLayersFromScript = true; | |
var strPresets = localize ("$$$/ApplicationPresetsFolder/Presets=Presets"); | |
var strScripts = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/Scripts=Scripts"); | |
var strFile2Stack = "Load Files into Stack.jsx"; | |
var ipFilePath = app.path + "/" + strPresets + "/" + strScripts + "/" + strFile2Stack; | |
var ipFile = new File (ipFilePath); | |
$.evalFile( ipFile ); | |
loadLayers.intoStack(stackFiles); | |
psdSaveOptions = new PhotoshopSaveOptions(); | |
psdSaveOptions.embedColorProfile = true; | |
psdSaveOptions.alphaChannels = true; | |
var saveFile = new File('~/desktop/'+(new Date().getTime().toString())+'.psd'); | |
var count = activeDocument.layers.length; |
for(var d = 0 ;d < count; d++){
activeDocument.activeLayer = activeDocument.layers | |
/* amend to use your action N.B. it is case sensitive */ | |
doAction("Action Name","Action Set"); | |
} |
activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
};
Copy link to clipboard
Copied
I am not sure that pushing the files from Bridge to Photoshop is the best way to do this. It might be better to do it the other way round.
This is a Photoshop script.
To use open Bridge with the stacks to process then run this script.
Make amendments for the action first.
You could test both and see what is best for you.
#target photoshop
app.bringToFront();
main();
function main(){
///////////////////////////////////////////////////////
// Change Action to your Actions name.
var Action = "Action"; //case sensitive
// Change ActionSetName to your Actions Set Name.
var ActionSetName = "Action Set Name"; //case sensitive
////////////////////////////////////////////////////////////////
if(!BridgeTalk.isRunning("bridge")){
alert("Please select the folder with Stacks to process in Bridge\nThen re-run this script again.");
return;
}
var bt = new BridgeTalk;
bt.target = "bridge";
bt.body ="function a(){return app.document.stacks.length;}; a();";
bt.onResult = function( inBT ) {stackCount(inBT.body); }
bt.onError = function( inBT ) {alert(inBT.body); }
bt.send(50);
bt.pump();
function stackCount(count){
for(var a = 0;a<count; a++){
stackFiles = new Array();
var bt = new BridgeTalk;
bt.target = "bridge";
bt.body =("var ftn = " + getStackFiles.toSource() + "; ftn("+a+");");
bt.onResult = function( inBT ) { stackEm(eval( inBT.body)); }
bt.onError = function( inBT ) {stackFiles = new Array(); }
bt.send(50);
function stackEm(stackFiles){
var thisDoc = open(File(stackFiles[0]));
doAction(Action,ActionSetName);
var Name = decodeURI(app.activeDocument.name).slice(0,-4);
thisDoc.layers[0].name = decodeURI(Name);
for(var a = 1;a<stackFiles.length;a++){
open(File(stackFiles));
Name = decodeURI(app.activeDocument.name).slice(0,-4);
doAction(Action,ActionSetName);
activeDocument.activeLayer.duplicate(thisDoc);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
thisDoc.layers[0].name = Name;
}
var saveFile = new File('~/desktop/'+(new Date().getTime().toString())+'.psd');
app.activeDocument.saveAs(saveFile);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
}
};
function getStackFiles( stackNumber ){
var stack = app.document.stacks[Number(stackNumber)];
var files = new Array();
for( var f = 0; f<stack.thumbnails.length;f++){
files.push(stack.thumbnails
.spec); }
return files.toSource();
};
};
Copy link to clipboard
Copied
Fantastic!!!
I couldn't get the photoshop one to work, but the bridge script works wonderfully! (at first it ran the action repeatedly on the first stack - so I just removed the loop around the action, that seemed to do it)
I am forever in your debt. I'm literally giddy with excitement. I feel as though I just watched Alan Turing crack the enigma!
I do have 2 questions about how to save the files.
1) I want to put them in a folder called "final" on my E drive. I tried this var saveFile = new File('E:/final'+(new Date().getTime().toString())+'.psd'); but just named them "final"
2) Is it possible to name the files the same name as the first image in the stack (I think that's the active document name). That way when I re-import to lightroom, they are next to each other.
You have truly helped me.
Copy link to clipboard
Copied
Please try this now and make amendments as usual.
#target bridge |
if( BridgeTalk.appName == "bridge" ) {
stacksToLayers = new MenuElement("command", "Stacks To Layers", "at the end of Tools");
}
stacksToLayers.onSelect = function () {
var stacks = app.document.stacks;
var stackCount = stacks.length;
for(var s = 0;s<stackCount;s++){
var stackFiles = getStackFiles( stacks | |
var Name = decodeURI(stackFiles[0].name).replace(/\.[^\.]+$/, ''); | |
if(stackFiles.length> 1){ | |
var bt = new BridgeTalk; | |
bt.target = "photoshop"; | |
var myScript = ("var ftn = " + psRemote.toSource() + "; ftn("+stackFiles.toSource() + "," + Name.toSource() +");"); | |
bt.body = myScript; | |
bt.onResult = function( inBT ) {myReturnValue(inBT.body); } | |
bt.send(500); | |
} |
}
function getStackFiles( stack ){
var files = new Array(); | |
for( var f = 0; f<stack.thumbnails.length;f++){ | |
files.push(stack.thumbnails | |
} | |
return files; |
};
function myReturnValue(str){
res = str; |
}
function psRemote(stackFiles,Name){
app.bringToFront(); | |
var loadLayersFromScript = true; | |
var strPresets = localize ("$$$/ApplicationPresetsFolder/Presets=Presets"); | |
var strScripts = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/Scripts=Scripts"); | |
var strFile2Stack = "Load Files into Stack.jsx"; | |
var ipFilePath = app.path + "/" + strPresets + "/" + strScripts + "/" + strFile2Stack; | |
var ipFile = new File (ipFilePath); | |
$.evalFile( ipFile ); | |
loadLayers.intoStack(stackFiles); | |
psdSaveOptions = new PhotoshopSaveOptions(); | |
psdSaveOptions.embedColorProfile = true; | |
psdSaveOptions.alphaChannels = true; | |
var outputFolder = new Folder("/e/Final"); | |
if(!outputFolder.exists) outputFolder.create(); | |
var saveFile = new File(outputFolder + '/'+ Name +'.psd'); | |
var Count = activeDocument.layers.length; | |
for(var d = 0 ;d < Count; d++){ | |
activeDocument.activeLayer = activeDocument.layers | |
/* amend to use your action N.B. it is case sensitive */ | |
doAction("Action Name","Action Set"); | |
} |
activeDocument.saveAs(saveFile, psdSaveOptions, true, Extension.LOWERCASE);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
};
Copy link to clipboard
Copied
That's astounding, thank you. I'm running a batch right now.
I am just now realizing the power of scripting. I assume we can add conditional statements.
I'm wondering if there a way to read the metadata to see if the flash has fired on a particular image?
Also, do you have any recommendations as to what to read as a beginner interested in learning scripting for bridge?
Copy link to clipboard
Copied
Yes scripts are very powerful and can save an enormous amount of time.
You can allready see if the flash has fired in Bridge, it shows this in the Metadata Camera Data (Exif) window, so long as the preferences - metadata has been selected. Yes conditional statements are used all the time.
As for documentation.
Adobe Software Developement Kit ( The offical documentation)
http://www.adobe.com/devnet/bridge.html
Peter Kahrel "ScriptUI for dummies"
http://www.kahrel.plus.com/indesign/scriptui.html
Then there are two forums.
https://forums.adobe.com/community/bridge/bridge_scripting/content
Hope this helps.
Copy link to clipboard
Copied
Thanks!
Copy link to clipboard
Copied
Just a follow up (should this be a separate thread? ) Is there any easy way to suppress dialog boxes (they halt my batch when they appear every 250 pics or so)
I looked online and found this command, but I think I may need to convert my action to javascript first?
app.displayDialogs = DisplayModes.NO;
Copy link to clipboard
Copied
Yes adding that line can stop a lot of prompts, and should be added when it is a Bridge script and utilizing Photoshop.There should be no need to convert your action to javaScript.
Copy link to clipboard
Copied
Okay, that sounds good, however I'm not having luck in knowing where to put it.
I put it as right before the app.bringToFront(); and it didn't run at all.
I put it right before the doaction line and it loaded the photos, but didn't run the action.
Copy link to clipboard
Copied
It would normally be put just after this line.
stacksToLayers.onSelect = function () {
Edit, it wouldn't harm to put it after
function psRemote(stackFiles,Name){
As then this would be part of the Photoshop script.
Lets hope it works
Copy link to clipboard
Copied
Well, the command seems to strong or something. If i put it after "stacksToLayers.onSelect = function () {" it won't even open photoshop
If I put it after the function "psRemote(stackFiles,Name){ " it opens photoshop but won't open the files.
Copy link to clipboard
Copied
As a last ditch effort to combat the occasional halting of this batch. I converted the action to javascript with scriptlistener.
Now I have about 12 paragraphs of inscrutable code. I'm not sure where to put it? (I tried just replacing the doAction line, but that didn't seem to work)
Do you have any suggestions? Either way, thanks for all your help. Even with the occasional halt, this script has changed my life.
Copy link to clipboard
Copied
Hi Philip,
thank you so much for your work on this script. On my system (Win7,64 bit, Adobe CC) the script runs properly ... However, I end up with many open Photoshop files. The files are named as "Untitled1", "Untitled2" etc. The files are not stored on the desktop (scripts from your post # 32), nor to a specific folder (scripts from your post # 35).
This is obviously a problem, because with my architectural photography I have often stacks with 20 layers or more. The generated PSD data with 2 GB or more (which must be saved as a PSB). Although I have 24 GB Ram in my computer, but that is not enough for more than 10 open files of this size.
It would therefore be fantastic if you can tell me what is going wrong on my system or what I have to do, so that the stacks are saved as PSD / PSB and closed.
Once again: Thank you very much for your effort, Kai
Copy link to clipboard
Copied
I have modified the script so that it saves all the files as PSBs, lets hope this sorts the problem.
#target bridge |
if( BridgeTalk.appName == "bridge" ) {
stacksToLayers = new MenuElement("command", "Stacks To Layers", "at the end of Tools");
}
stacksToLayers.onSelect = function () {
var stacks = app.document.stacks;
var stackCount = stacks.length;
for(var s = 0;s<stackCount;s++){
var stackFiles = getStackFiles( stacks | |
var Name = decodeURI(stackFiles[0].name).replace(/\.[^\.]+$/, ''); | |
if(stackFiles.length> 1){ | |
var bt = new BridgeTalk; | |
bt.target = "photoshop"; | |
var myScript = ("var ftn = " + psRemote.toSource() + "; ftn("+stackFiles.toSource() + "," + Name.toSource() +");"); | |
bt.body = myScript; | |
bt.onResult = function( inBT ) {myReturnValue(inBT.body); } | |
bt.send(500); | |
} |
}
function getStackFiles( stack ){
var files = new Array(); | |
for( var f = 0; f<stack.thumbnails.length;f++){ | |
files.push(stack.thumbnails | |
} | |
return files; |
};
function myReturnValue(str){
res = str; |
}
function psRemote(stackFiles,Name){
app.bringToFront(); | |
var loadLayersFromScript = true; | |
var strPresets = localize ("$$$/ApplicationPresetsFolder/Presets=Presets"); | |
var strScripts = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/Scripts=Scripts"); | |
var strFile2Stack = "Load Files into Stack.jsx"; | |
var ipFilePath = app.path + "/" + strPresets + "/" + strScripts + "/" + strFile2Stack; | |
var ipFile = new File (ipFilePath); | |
$.evalFile( ipFile ); | |
loadLayers.intoStack(stackFiles); | |
psdSaveOptions = new PhotoshopSaveOptions(); | |
psdSaveOptions.embedColorProfile = true; | |
psdSaveOptions.alphaChannels = true; | |
var outputFolder = new Folder("/e/Final"); | |
if(!outputFolder.exists) outputFolder.create(); | |
var saveFile = new File(outputFolder + '/'+ Name +'.psb'); | |
var Count = activeDocument.layers.length; | |
for(var d = 0 ;d < Count; d++){ | |
activeDocument.activeLayer = activeDocument.layers | |
/* amend to use your action N.B. it is case sensitive */ | |
doAction("Action Name","Action Set"); | |
} |
savePSB(saveFile);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
function savePSB(saveFile) {
var desc1 = new ActionDescriptor();
var desc2 = new ActionDescriptor();
desc2.putBoolean( stringIDToTypeID('maximizeCompatibility'), true );
desc1.putObject( charIDToTypeID('As '), charIDToTypeID('Pht8'), desc2 );
desc1.putPath( charIDToTypeID('In '), new File(saveFile) );
desc1.putBoolean( charIDToTypeID('LwCs'), true );
executeAction( charIDToTypeID('save'), desc1, DialogModes.NO );
};
}
};
Copy link to clipboard
Copied
Philip, thanks for your quick response.
The script runs without problems. But unfortunately the layered files are still not saved and not closed. And the files are called still "Untitled1", "Untitled2" etc. and remains opend in PS 😞
Perhaps I have misunderstood something ... I saved your script unchanged as JSX file in the Bridge scripts folder. Do I have to change the script to something or set something specific in Photoshop or Bridge, for it to work (maybe in the preferences)? Sorry for being such a Dummy 🙂
Just to be clear: There is a Folder on e/Final (as in LIne 56 in the script) but it remains empty.
Copy link to clipboard
Copied
Thank you Michael, Paul and JJMack. This has given me plenty to work with!!
Copy link to clipboard
Copied
I found a wierd bug in bridge/photoshop while using this script. Or is there something missing from the script?
I discovered that if I change just one raw file in camera raw (eg WB) then the 'load files into stack' script loads all the files with default settings, ignoring the changes made and saved while in Camera RAW.
On the otherhand if I change all the files, then the camera raw settings are observed and the files are loaded into a stack with the new settings.
The problem only seems to happen when the discussed script sends the files from bridge for processing. It doesn't happen if I manually go to BRIDGE >Tools>Photoshop>Loadfiles into Photoshop Layers.
Does anyone know if there is a fix? The script is below
var stacks = app.document.stacks;
var stackCount = stacks.length;
for(var s = 0;s<stackCount;s++){
var stackFiles = getStackFiles( stacks );
if(stackFiles.length> 1){
var bt = new BridgeTalk;
bt.target = "photoshop";
var myScript = ("var ftn = " + psRemote.toSource() + "; ftn("+stackFiles.toSource()+");");
bt.body = myScript;
bt.onResult = function( inBT ) {myReturnValue(inBT.body); }
bt.send(500);
}
}
function getStackFiles( stack ){
var files = new Array();
for( var f = 0; f<stack.thumbnails.length;f++){
files.push(stack.thumbnails
}
return files;
};
function myReturnValue(str){
res = str;
}
function psRemote(stackFiles){
var loadLayersFromScript = true;
var strPresets = localize ("$$$/ApplicationPresetsFolder/Presets=Presets");
var strScripts = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/Scripts=Scripts");
var strFile2Stack = "Load Files into Stack.jsx";
var ipFilePath = app.path + "/" + strPresets + "/" + strScripts + "/" + strFile2Stack;
var ipFile = new File (ipFilePath);
$.evalFile( ipFile );
loadLayers.intoStack(stackFiles);
}
Copy link to clipboard
Copied
Hi Everyone,
I have the same issue as Orchid Photo- I have hundreds of folders, each with 5 images in them- I need each set of 5 to be aligned then stacked as layers. I have tried the scripts kindly presented here, however I can't seem to get them to run (I have never run a script before). When I run, it says "Result:onSelect()" and the "Stack to Layers" appears in the tool menu, but nothing happens at all when I click it. Even if I highlight a folder, or the set of 5 images I want stacked and click "Stack to Layers", nothing happens.
What could I be doing wrong here? I appreciate any help I could get.
Also, just for clarification, I am assuming that this script will open multiple folders as different stacks in photoshop? Ultimately I want to save a single stacked 5 layer image (non-flattened) in its state of alignment, as a tiff in the original folder. (RGB, NIR and Red Edge bands of light).
Just for context, I am aligning slightly offsetting satellite images covering the same areas. Each folder has a frame (5 bands) that I'd like to realign so the surface features match perfectly over the 5 bands/frame.
Complicated eh? But any help would be immensely appreciated. Donations are available.
Copy link to clipboard
Copied
It is not clear what you have done what script your tried. I can guess you tried from the bridge something in the tool menu, Like menu Tools>Photoshop>Load Files into Photoshop Layers.... I would not expect scripts to open different folder if your using the bridge for I do not think selecting folders would be allowed. I would expect Photoshop to start, run the script and the script to open the file you select thumbnails for in the bridge and create a stack of layer in a new document.
The more information you supply about your situation, the better equipped other community members will be to answer. Consider including the following in your question: