Copy link to clipboard
Copied
I use a workflow script and actions to retouch large numbers of files and it would be fabulous if I could do some layer mask brushing on each image "mid batch". Is it possible to create a Pause Script (60-120 seconds would be ideal) that can be called from an action or inserted into my pressing script?
Can anyone tell me a) if this possible b) which Javascript commands I should try ?
Works well on CS6.
Worse on CC2018 due to the use of refresh()
You can draw, adjust adjustments layers and even invoke other scripts.
...var cs6 = (parseInt(app.version)==13)
var time = 60;
var old_time;
var msg = new Window("palette", "Draw or do something while script is waiting");
msg.preferredSize.width = 200;
msg.txt = msg.add("statictext", undefined, "");
msg.txt.preferredSize.width = 220;
msg.txt.justify = "center";
msg.btn = msg.add("button", undefined, "Continue");
msg.btn.onClick = function() { msg.h
Copy link to clipboard
Copied
Hi OrchidPhoto,
yes, you can say: "script wait any time" e.g. like this:
alert("wait a second");
$.sleep( 999 ); /*Milliseconds*/
alert ("done");
But in this time IMHO the script is always activ and you cannot work in PS meantime, sorry.
Copy link to clipboard
Copied
OrchidPhoto wrote:
I use a workflow script and actions to retouch large numbers of files and it would be fabulous if I could do some layer mask brushing on each image "mid batch". Is it possible to create a Pause Script (60-120 seconds would be ideal) that can be called from an action or inserted into my pressing script?
"that can be called from an action" I do not understand if your using an action to begin with you can pause an action with a stop message like "Piant on the layer mask to make it better. When done click on "PLAY" in the Actions Palette to continue the action.
However you also write batch. Having interaction in a batch process sort of negate it being a batch process.
Copy link to clipboard
Copied
hey JJMack can you provide an example..
Copy link to clipboard
Copied
It more important to understand that it is not possible to pause an action or a script. That you can program both to simulate a pause. What is good about that is everything is programmed into a single file. There is only one file to maintain. However the file when used must be used twice to get its full function. If you look at the action palette and expand an action part way so you can see all the steps but not the setting used in the steps. You can highlight the action and click the play button and the action will run. You could also have highlighted one of the action step and clicked the play button and the action would have starter from the highlighted step. So you could say a action contains many actions. Inserting a STOP in an action in effect breaks and action into at least two every stop you add basically adds an additional action. So if you add a single stop into an action it brakes the action into the first part and a second part. So when you highlighted the action it will play the first part and stop when it encounter the stop and the step after the stop is highlighted. when you click the play button a second time the second part plays plays and the action complete it job. The Stop is not a pause its a place holder. You do not have to play the second part. You can do the same in a script you can program Part One and program Part Two what you need do is program the place holder. It could be a crude as a prompt which part do you want to execute One or Two or the place holder could be set by part one so that when and it the script is run the second time part two would execute.
You might call the Actions and Scripts "Run or Play Twice" programs....
Here is and example of one of my run twice scripts I created to be used within actions.
SaveAndRestoreResolution.jsx
/* ======================================================================================
// 2009 John J. McAssey (JJMack) http://www.mouseprints.net/
//
// This script is supplied as is. It is provided as freeware.
// The author accepts no liability for any problems arising from its use.
//
// This script is designed to be used by a Photoshop Action twice
// A good pratice to use when creating an actions that use this scipt is for the action
// not to do a save or play some other action between its two useages of this Script.
//
// The first time this script is used by an action the documents current resolution
// and ruler units are saved into the document's meta-data Info Instructions field.
//
// The second time this script used by the action the script retreives what was
// saved in the meta-data during the first usage, resolution and ruler units.
// The document is resized to the saved resolution,
// Photoshop's ruler units are set to saved units
// and the saved data is removed from the document's meta-data Info Instructions field.
//
// ===================================================================================== */
/*
<javascriptresource>
<about>$$$/JavaScripts/SaveAndRestoreResolution/About=JJMack's SaveAndRestoreResolution.^r^rCopyright 2009 Mouseprints.^r^rRun twice script utility for action.^rNOTE:Don't play other actions between runs!^r^rFirst Run records Photoshop's preferences Units and documents DPI resolution.^rSecond Run restores the recorded setting and removes the recording.</about>
<category>JJMack's Action Run Twice Utility</category>
</javascriptresource>
*/
if (app.documents.length > 0) {
if (app.activeDocument.info.instructions.indexOf("<Resolution>") == -1 ){ // no footprint fisrt useage
//alert("first");
// Retreive Document information for Foot Print
var units = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS; // set ruler units to PIXELS
var typeunits = app.preferences.typeUnits;
var res = app.activeDocument.resolution;
// put footprint in metadata info instructions
app.activeDocument.info.instructions = app.activeDocument.info.instructions + "<Units>" + units + "</Units>" + "<Tunits>" + typeunits + "</Tunits>" + "<Resolution>" + res + "</Resolution>";
//alert( "Saved =" + "<Units>" + units + "</Units>" + "<Tunits>" + typeunits + "</Tunits>" + "<Resolution>" + res + "</Resolution>" );
app.preferences.rulerUnits = units; // restore ruler units
}
else {
//alert("second");
// Retreive saved information
unitsOffset = app.activeDocument.info.instructions.indexOf("<Units>") + "<Units>".length;
unitsLength = app.activeDocument.info.instructions.indexOf("</Units>") -unitsOffset;
savedUnits = app.activeDocument.info.instructions.substr(unitsOffset, unitsLength);
tunitsOffset = app.activeDocument.info.instructions.indexOf("<Tunits>") + "<Tunits>".length;
tunitsLength = app.activeDocument.info.instructions.indexOf("</Tunits>") -tunitsOffset;
savedTunits = app.activeDocument.info.instructions.substr(tunitsOffset, tunitsLength);
resOffset = app.activeDocument.info.instructions.indexOf("<Resolution>") + "<Resolution>".length;
resLength = app.activeDocument.info.instructions.indexOf("</Resolution>") + -resOffset;
savedResolution = app.activeDocument.info.instructions.substr(resOffset, resLength);
//alert("Resolution = " + savedResolution + " Units = " + savedUnits );
// Restore resolution
app.preferences.rulerUnits = Units.PIXELS;
activeDocument.resizeImage(null, null, savedResolution, ResampleMethod.NONE);
// Restore ruler units
// I get a message Enumerated value expected if I try to use var savedUnits app.preferences.rulerUnits = savedUnits;
// perhaps if I knew Javascript I would not need to use the following if else if .....
if ( savedUnits == "Units.INCHES" ){ app.preferences.rulerUnits = Units.INCHES;}
else if ( savedUnits == "Units.CM" ){ app.preferences.rulerUnits = Units.CM;}
else if ( savedUnits == "Units.PERCENT" ){ app.preferences.rulerUnits = Units.PERCENT;}
else if ( savedUnits == "Units.MM" ){ app.preferences.rulerUnits = Units.MM;}
else if ( savedUnits == "Units.PIXELS" ){ app.preferences.rulerUnits = Units.PIXELS;}
else if ( savedUnits == "Units.POINTS" ){ app.preferences.rulerUnits = Units.POINTS;}
else if ( savedUnits == "Units.PICAS" ){ app.preferences.rulerUnits = Units.PICAS;}
// Restore Type units
if ( savedTunits == "TypeUnits.PIXELS" ){ app.preferences.typeUnits = TypeUnits.PIXELS;}
else if ( savedTunits == "TypeUnits.POINTS" ){ app.preferences.typeUnits = TypeUnits.POINTS;}
else if ( savedTunits == "TypeUnits.MM" ){ app.preferences.typeUnits = TypeUnits.MM;}
// Remove footprint from metadata info instructions
before = app.activeDocument.info.instructions.substr(0,app.activeDocument.info.instructions.indexOf("<Units>"));
afterOffset = app.activeDocument.info.instructions.indexOf("</Resolution>") + "</Resolution>".length;
after = app.activeDocument.info.instructions.substr(afterOffset, app.activeDocument.info.instructions.length - afterOffset);
//alert ("before = " + before + " after = " + after);
app.activeDocument.info.instructions = before + after;
}
}
else { alert("You must have at least one open document to run this script!"); }
Copy link to clipboard
Copied
I have a few questions:
I could make a useful script to repeat a long sequence of actions just copying a main block of code and adjusting some variables.
You'd gave me valuable tips there. Thanks.
Now, I'm trying to understand that such thing called ScriptUI.
I searched here and at Google, but it isn't clear to me. Is it an other kind of scripts with windows and input resources?
Also, I tryed to reproduce your SaveAndRestoreResolution script above without success.
First run, nothing happens, just FileInfo in History palette.
I run a rotate 90º Action and run SaveAndRestoreResolution again (2º run) and nothing happens, just FileInfo in History palette again.
Am I missing something?
What I'm trying to do is a way to stop some script and run from where I paused it.
I already learned about $.sleep(milisecond) command and it works fine.
In fact, I look for a way to better debug a script I'm writing at time.
Run a bit and see what is going on; run another bit and see.
Or run with sleep command at each step. But screen is not refreshed and I cannot see results this way.
Thus, I'm looking for a pause command.
If you send me some ideas, I'd appreciate.
Copy link to clipboard
Copied
Gabarito wrote
Now, I'm trying to understand that such thing called ScriptUI.
Also, I tryed to reproduce your SaveAndRestoreResolution script above without success.
First run, nothing happens, just FileInfo in History palette.
I run a rotate 90º Action and run SaveAndRestoreResolution again (2º run) and nothing happens, just FileInfo in History palette again.
ScriptUI is part of Photoshop Scripting support documented here
Photoshop CC Scripting Guide 2015.pdf
Adobe added a bug into Scripting Support that breake my scripts like SaveAndRestoreResolution. My scripts insert and remove their information in the document metadatd field info.Instructions they all preserver any other data in that field. In CC 2015.5 adobe broke my scripts. My scripts can not longer remove their data if there is no other data in the instruction field but their data. To get around Adobe bug I set up Onen Document and new docyment script event handlers to add garbage to the field if is it not there. So there will be other data in the field so may script will once again be able to remove their data.
the handler code:
if (app.activeDocument.info.instructions.indexOf("Garbage") == -1 ) app.activeDocument.info.instructions = app.activeDocument.info.instructions + "Garbage";
Copy link to clipboard
Copied
Thank you, but I'm still unable to understand what ScriptUI is.
PDF only says:
Adobe provide the ScriptUI component, which works with th ExtendedScript Javascript interpreter to provide JavaScript scripts with the ability to create and interact with user interface elements. It provides an object model for windows and user-interface control elements within Adobe applications".
How to get that?
Some example?
And how to pause/stop and resume scripts?
What do you guys use to debug a script?
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Far better PDF.
I have too many lessons to study...
Thanks.
But how do you debug your scripts?
How do you run step-by-step your codes?
Copy link to clipboard
Copied
I do not like the extendscript UI its UI jumps around windows to much for me so much so that I find it to distracting for my use. I only use its Object viewer to gets information about Photoshop's object. There are also bugs in extendscript. I use notepad++ to edit my scripts for the JavaScript syntax formatting. And I debug with a sledge hammer many JavaScript alerts statement that are later removed or commented out. I do not even know JavaScript or understand a regular expression. I just hack at Photoshop scripting. I have a programming background and have work with an within many operating systems that are not written in JavaScript. The only scripting language I knew well was Rex which looms very much like PL1 without a need to declare variables. Adobe also replace Script UI in CC 2015 with a new implementation not Flash based now supports HTML 5. Most of the bugs introduces have been fixed. Most of my scripts do not have a Script UI dialog.
Copy link to clipboard
Copied
Many thanks for explanations.
I have too much material to study.
And I'll put alerts on my code too. Good idea.
Copy link to clipboard
Copied
One more thing:
Running your script above, I got a little error at this line:
before = app.activeDocument.info.instructions.substr(0,app.activeDocument.info.instructions.indexO f("<Units>"));
I found out that indexOf was separated by space:
instructions.indexO f("<Units>"));
Just a small typo error.
Copy link to clipboard
Copied
Yes that is something this site's Jive does occasionally it also remove a required blank(space) in some code statement quote strings fields.
Been a problem here for years.
Copy link to clipboard
Copied
You can try running the first half of the script normally, then show a ScriptUI palette where you want to break. The palette should contain a 'Continue' button. Add the rest of the functionality of the script to the callback of this Continue button.
Copy link to clipboard
Copied
Photoshop ScriptUI does not actually support Palette Windows in a Photoshop Script run in from Photoshop. The Script though suspended and waiting on the palette being used. Photoshop UI is not given back control. So the user can do nothing in Photoshop but use the Palette window. I have been able to write a Photoshop Script that opens palette window from a Photoshop Extention and use Photoshop with the Palette window open.
Copy link to clipboard
Copied
Works well on CS6.
Worse on CC2018 due to the use of refresh()
You can draw, adjust adjustments layers and even invoke other scripts.
var cs6 = (parseInt(app.version)==13)
var time = 60;
var old_time;
var msg = new Window("palette", "Draw or do something while script is waiting");
msg.preferredSize.width = 200;
msg.txt = msg.add("statictext", undefined, "");
msg.txt.preferredSize.width = 220;
msg.txt.justify = "center";
msg.btn = msg.add("button", undefined, "Continue");
msg.btn.onClick = function() { msg.hide(); }
msg.show();
msg.frameLocation = [50, 100];
$.hiresTimer;
set_performance("stepByStep");
app.displayDialogs = DialogModes.ERROR;
try {
while (msg.visible && time > 0)
{
if (old_time != time.toFixed(0))
{
msg.txt.text = "You have: " + time.toFixed(0) + " sec";
old_time = time.toFixed(0);
}
if (cs6) app.bringToFront();
else app.refresh();
time -= ($.hiresTimer/1000000);
}
}
catch (e) { }
set_performance("accelerated");
msg.close();
alert("Script End")
function set_performance(mode)
{
try {
var r1 = new ActionReference();
r1.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "PbkO" ) );
r1.putEnumerated( charIDToTypeID( "capp" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
var d1 = new ActionDescriptor();
d1.putReference( charIDToTypeID( "null" ), r1 );
var d2 = new ActionDescriptor();
d2.putEnumerated( stringIDToTypeID( "performance" ), stringIDToTypeID( "performance" ), stringIDToTypeID( mode ) );
d1.putObject( charIDToTypeID( "T " ), charIDToTypeID( "PbkO" ), d2 );
executeAction( charIDToTypeID( "setd" ), d1, DialogModes.NO );
}
catch (e) { throw(e); }
}
Copy link to clipboard
Copied
Very interesting!!!
It's what I was looking for.
But where do I put my code?
Inside that try statement?
try {
while (msg.visible && time > 0)
{
if (old_time != time.toFixed(0))
{
msg.txt.text = "You have: " + time.toFixed(0) + " sec";
old_time = time.toFixed(0);
}
Here???
if (cs6) app.bringToFront();
else app.refresh();
Here???
time -= ($.hiresTimer/1000000);
}
}
catch (e) { }
So, where?
Copy link to clipboard
Copied
Place the first part of your code before all this script. Place the second part instead of the alert ("Script End") command.
It's better to make my entire script as a function and call it in the necessary places in your scripts.
Copy link to clipboard
Copied
Yes, of course, make your script as a function and call it according.
Many thanks.
Copy link to clipboard
Copied
Sorry if I'm asking dumb questions, but I'm not a programmer and just now trying to put some code to run.
But I have no idea where I can insert my script.