Copy link to clipboard
Copied
Hello,
I'm having a fever and trying to accomplish something that seems very simple without knowing anything about scripting.
I've made an action that applies some simple effects (blur, threshold and high pass). What I want to do is to repeat the action for n times and save an incremental png for each repetition so that I end up with a numbered file sequence of the action being applied more and more ( like in this example Photoshop Cs5 Filters Animation on Vimeo).
After som googling I ended up using AppleScript and was able to repeat the action for as many times as I want, but I'm completely stuck on the file saving part. This is what I have at the moment:
Any help is greatly appreciated!
tell application "Adobe Photoshop CC 2015.5"
set StartingPoint to current document
set theFilePath to file path of current document
repeat with n from 1 to 10
set myFile to theFilePath & ":output:image" & {n as string} & ".png"
do action "CrazyAction" from "Default Actions"
save current document in file myFile as PNG with options {class:PNG save options, interlaced:false}
end repeat
end tell
In case someone comes up with the solution I also have another related question: how can I make sure the output file names will have some padding in the number? Ideally I'd end up with image001.png, image002.png and so on rather than image1.png, image2.png.
Many thanks in advance!
One of the things you can do with javascript that you can't do with applescript is to use the scriptlistener plugin. This plugin is put into the photoshop plugins folder, and when it's there (you don't want to leave it there all the time) it will record pretty much everything you do, much like an action, but it will generate code to a log file on your desktop. I used it for recording running an action and for saving the png. Those parts of the code are in the functions in the script. So I just e
...Copy link to clipboard
Copied
If you don't know much about scripting, I would use javascript rather than applescript, as it's cross platform and most people here on the forum know javascript better or only - like me - and can then help you. Saving a file in javascript, and i'm assuming applescript boils down to setting up a variable for the file name and doing a saveas, incriminating the file name by some number in a loop.
Copy link to clipboard
Copied
Thanks for the reply, maybe that's my solution but I'd have no idea how to script that. To me the AppleScript syntax seemed like a much more friendly approach for a complete beginner.
Copy link to clipboard
Copied
Would anybody be able to help me script this using JavaScript or other popular script language? I feel like it should be pretty simple to achieve.
To a currently open document in Photoshop
repeat n times:
Trigger my action
Save an incrementally named image
So that I end up with an image sequence where the action has been applied again as many times as there are images.
Thanks
Copy link to clipboard
Copied
One of the things you can do with javascript that you can't do with applescript is to use the scriptlistener plugin. This plugin is put into the photoshop plugins folder, and when it's there (you don't want to leave it there all the time) it will record pretty much everything you do, much like an action, but it will generate code to a log file on your desktop. I used it for recording running an action and for saving the png. Those parts of the code are in the functions in the script. So I just established a base folder name, a base file name, and a starting counter. The script will then run your action and save a png to that base folder and change the base file name by the counter increasing by one each time. You need to put in the name of your action and the name of the action set into the script.
#target photoshop
var fileName = 'myFile-';
var folderPath = new Folder (Folder.desktop +'/action test/')//create whatever path you want here. Make sure the folder exists!
var doc = activeDocument;
var counter = 1//counter for changing the filename
for (var i=0;i<4;i++){//Change number 4 to whatever number you want it to repeat + 1
runMyAction ("twirl", "Chuck");//put in action name and action set name. This line can be duplicated for different actions.
savePNG ()
counter++
}
function runMyAction(myAction, myActionSet){
var idPly = charIDToTypeID( "Ply " );
var desc25 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref8 = new ActionReference();
var idActn = charIDToTypeID( "Actn" );
ref8.putName( idActn, myAction );//changed to a variable
var idASet = charIDToTypeID( "ASet" );
ref8.putName( idASet, myActionSet );//Changed to a variable
desc25.putReference( idnull, ref8 );
executeAction( idPly, desc25, DialogModes.NO );
}
function savePNG(){
var idsave = charIDToTypeID( "save" );
var desc28 = new ActionDescriptor();
var idAs = charIDToTypeID( "As " );
var desc29 = new ActionDescriptor();
var idPGIT = charIDToTypeID( "PGIT" );
var idPGIT = charIDToTypeID( "PGIT" );
var idPGIN = charIDToTypeID( "PGIN" );
desc29.putEnumerated( idPGIT, idPGIT, idPGIN );
var idPNGf = charIDToTypeID( "PNGf" );
var idPNGf = charIDToTypeID( "PNGf" );
var idPGAd = charIDToTypeID( "PGAd" );
desc29.putEnumerated( idPNGf, idPNGf, idPGAd );
var idCmpr = charIDToTypeID( "Cmpr" );
desc29.putInteger( idCmpr, 9 );
var idPNGF = charIDToTypeID( "PNGF" );
desc28.putObject( idAs, idPNGF, desc29 );
var idIn = charIDToTypeID( "In " );
desc28.putPath( idIn, new File( folderPath + '/'+ fileName + counter+ ".png" ) );//set folder path and name
var idDocI = charIDToTypeID( "DocI" );
desc28.putInteger( idDocI, 200 );
var idCpy = charIDToTypeID( "Cpy " );
desc28.putBoolean( idCpy, true );
var idsaveStage = stringIDToTypeID( "saveStage" );
var idsaveStageType = stringIDToTypeID( "saveStageType" );
var idsaveBegin = stringIDToTypeID( "saveBegin" );
desc28.putEnumerated( idsaveStage, idsaveStageType, idsaveBegin );
executeAction( idsave, desc28, DialogModes.NO );
}
Copy link to clipboard
Copied
Thank you Chuck! Works beautifully, and very nice tip about the scriptlistener plugin!
Copy link to clipboard
Copied
Yea, some things you can't script without using the scriptlistener, so I'm not sure how people who use applescript code that type of stuff.
Copy link to clipboard
Copied
Hi, I know it's been a while since this was first posted. But I currently have a "RunActionX-Times.jsx" pasted below. However, it does not save a file incrementally as each action is looped. Does anyone know a way to achieve that? Thanks in advance.
#target photoshop
app.bringToFront();
function main(){
var dlg =
"dialog{text:'Script Interface',bounds:[100,100,500,230],"+
"panel0:Panel{bounds:[10,10,390,120] , text:'' ,properties:{borderStyle:'etched',su1PanelCoordinates:true},"+
"statictext0:StaticText{bounds:[30,10,160,30] , text:'Run Action X Times..' ,properties:{scrolling:undefined,multiline:undefined}},"+
"Xtimes:EditText{bounds:[200,10,261,30] , text:'1' ,properties:{multiline:false,noecho:false,readonly:false}},"+
"ActionSet:DropDownList{bounds:[10,50,180,70]},"+
"ActionName:DropDownList{bounds:[200,50,370,70]},"+
"button0:Button{bounds:[40,80,140,100] , text:'Ok' },"+
"button1:Button{bounds:[240,80,340,100] , text:'Cancel' }}}";
var win = new Window(dlg,"Action Runner");
win.center();
var actionSets = new Array();
actionSets = getActionSets();
for (var i=0,len=actionSets.length;i<len;i++) {
item = win.panel0.ActionSet.add ('item', "" + actionSets[i]);
};
win.panel0.ActionSet.selection=0;
var actions = new Array();
actions = getActions(actionSets[0]);
for (var i=0,len=actions.length;i<len;i++) {
item = win.panel0.ActionName.add ('item', "" + actions[i]);
};
win.panel0.ActionName.selection=0;
win.panel0.ActionSet.onChange = function() {
win.panel0.ActionName.removeAll();
actions = getActions(actionSets[parseInt(this.selection)]);
for (var i=0,len=actions.length;i<len;i++) {
item = win.panel0.ActionName.add ('item', "" + actions[i]);
}
win.panel0.ActionName.selection=0;
};
var done = false;
while (!done) {
var x = win.show();
if (x == 0 || x == 2) {
win.canceled = true;
//Cancelled
done = true;
} else if (x == 1) {
done = true;
var result = valiDate();
if(result != true) {
alert(result);
return;
}else
{
var XTimes = parseInt (win.panel0.Xtimes.text);
for (var a =0;a<XTimes;a++){
doAction(win.panel0.ActionName.selection.text, win.panel0.ActionSet.selection.text);
}
}
}
}
}
main();
function valiDate(){
return true;
};
function getActionSets() {
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
var i = 1;
var sets = [];
while (true) {
var ref = new ActionReference();
ref.putIndex(cTID("ASet"), i);
var desc;
var lvl = $.level;
$.level = 0;
try {
desc = executeActionGet(ref);
} catch (e) {
break; // all done
} finally {
$.level = lvl;
}
if (desc.hasKey(cTID("Nm "))) {
var set = {};
set.index = i;
set.name = desc.getString(cTID("Nm "));
set.toString = function() { return this.name; };
set.count = desc.getInteger(cTID("NmbC"));
set.actions = [];
for (var j = 1; j <= set.count; j++) {
var ref = new ActionReference();
ref.putIndex(cTID('Actn'), j);
ref.putIndex(cTID('ASet'), set.index);
var adesc = executeActionGet(ref);
var actName = adesc.getString(cTID('Nm '));
set.actions.push(actName);
}
sets.push(set);
}
i++;
}
return sets;
};
function getActions(aset) {
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
var i = 1;
var names = [];
if (!aset) {
throw "Action set must be specified";
}
while (true) {
var ref = new ActionReference();
ref.putIndex(cTID("ASet"), i);
var desc;
try {
desc = executeActionGet(ref);
} catch (e) {
break; // all done
}
if (desc.hasKey(cTID("Nm "))) {
var name = desc.getString(cTID("Nm "));
if (name == aset) {
var count = desc.getInteger(cTID("NmbC"));
var names = [];
for (var j = 1; j <= count; j++) {
var ref = new ActionReference();
ref.putIndex(cTID('Actn'), j);
ref.putIndex(cTID('ASet'), i);
var adesc = executeActionGet(ref);
var actName = adesc.getString(cTID('Nm '));
names.push(actName);
}
break;
}
}
i++;
}
return names;
};
Copy link to clipboard
Copied
Next time use </> icon when pasting the code. Now it's misfunctional. Loop Action
Copy link to clipboard
Copied
Oh good to know, will do. Sorry about that!
Copy link to clipboard
Copied
Maybe something wrong is with your action.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Recreate you saving step:
Copy link to clipboard
Copied
I'm able to get the Loop Action to work, it's just being able to have it save incrementally with each iteration. Any idea on how to achieve that?
Copy link to clipboard
Copied
Search the forum for other posts with scripts that save such files. As running a hard-coded action only takes a single line of code, it should be easy enough to incorporate this into an existing script.
Edit: I misread that, I was thinking of a single action run with an incremental save manually repeated, not automatically repeating N number of times.
I'll post a script a little later...
Copy link to clipboard
Copied
@key10reeder – Try this script:
/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/repeat-action-and-save-file/td-p/8532556
v1.2 - A mashup, based on:
https://forums.adobe.com/thread/2649334
https://forums.adobe.com/message/11234144
https://community.adobe.com/t5/photoshop/saving-sequential-file-names-of-the-same-file-to-multiple-files/td-p/12023959
*/
#target photoshop
if (app.documents.length > 0) {
// Save path
try {
var path = app.activeDocument.path.fsName;
} catch (e) {
var path = Folder.selectDialog("Unsaved base file, select the output folder:");
}
function main() {
// Change the number to be however many times the action should be repeated
for (i = 0; i < 2; i++) {
// Change the action and action set as required
app.doAction("Molten Lead", "Default Actions.atn");
incrementalSave();
}
function incrementalSave() {
try {
var name = activeDocument.name;
var n = name.lastIndexOf(".");
if (n > 0) name = name.substr(0, n);
var indexNo = 0;
var preFix = 0;
do {
preFix = zeroPad(indexNo + 1, 3);
var file = new File(path + "/" + name + "-" + preFix + ".png");
++indexNo;
}
while (file.exists)
var saveOptions = new PNGSaveOptions();
// Range from 0 Largest file size to 9 smallest file size
saveOptions.compression = 0;
saveOptions.interlaced = false;
app.activeDocument.saveAs(file, saveOptions, true, Extension.LOWERCASE);
function zeroPad(n, s) {
n = n.toString();
while (n.length < s) n = '0' + n;
return n;
}
} catch (e) {
alert(e);
}
}
}
app.activeDocument.suspendHistory("Repeat action N times (history suspended)", "main()");
alert("x" + i + " PNG files saved to:" + "\r" + path.fsName);
} else {
alert("You must have a document open!");
}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Did you try the tip I posted 5 hours ago?
Copy link to clipboard
Copied
Thanks Kukurykus, I did try this method you advised, however it still saves over the same .png each time rather than saving a new .png incremntally each time the action is run. I'd like for it not to save-over the 1 .png but instead create a new .png each time as the image changes incrimentally.
Copy link to clipboard
Copied
When you expand the item in your action is there a path without file name?
Copy link to clipboard
Copied
No, here's what the expanded item looks like:
Copy link to clipboard
Copied
Correrction: *Yes*, there is a path WITHOUT a file name.
I read your reply as "is there path WITH a file name" my apologies.
Copy link to clipboard
Copied
I ended figuring out a way to do it with the help of adding this script to the end of the action: https://www.artstation.com/marketplace/p/3bYW/increment-save-photoshop-script
So I go to File > Script > Browse > load the RunActionX-Times.jsx and run it 100x or however many times. Then each time the action runs, at the end it runs a script which saves an incremental file allowing a sequence to build up in a folder which can later be brought into a PNG sequence.
Pretty happy, thanks for all of the help! 🙂
Copy link to clipboard
Copied
If your action is not too long just script it and add to code you provided 😉
Copy link to clipboard
Copied
@key10reeder wrote:
Thanks Stephen, Made this a jsx file, went to File > Scripts > Browse and select it, then some reason I'm getting these two errors: (see screenshots)
Also, do I need to add any paths in the script for each png to incrementally save to each time the action is looped?
Apologies, from your initial posting I presumed a certain level of scripting knowledge/experience.
I commented the code, you need to change two things:
// Change the number to be however many times the action should be repeated
In this case, the number 2 to how many times you wish to repeat the action and incremental filename save.
// Change the action and action set as required
Change the name of the action set from Default Actions.atn to your action set name, the .atn is not required it is just there for clarity. Then change the name of the referenced action from Molten Lead to the name of the action in the set. Don't remove the quote marks.
As for the paths, no. The script will use the active document path to save the incremental versions, for unsaved files you will be prompted to select a location to set the path. The code could be easily changed to either automatically create a default folder or prompt the user to select or create a folder rather than presuming the active document path.