Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

About progress bar and Photoshop

Guest
Oct 01, 2013 Oct 01, 2013

I have been reading a lot about how to make a progress bar in photoshop (scripting) and my conclusion is that it is not worthy. The only way to make a progress bar is by using Palette window but Photoshop does not support it. If we use a dialog window, since it is modal, it will freeze whatever your script is doing so, you cannot use it (how to track the progress of a script if the script is paused while the dialog is being shown?). Although Photoshop does not support Palette, there are two workarounds that would make it work and they are using either app.refresh() or waitForRedraw() (and undocumented function that seems to me to do exactly the same thing that app.refresh() does). But as the manual says, app.refresh() will slow down considerably your code. According to my experimentation, each time you call app-refresh(), your script will waste about 1 second (no matter how powerful your computer is). That is a lot of time! In practical terms, you would use app.refresh() only a few times so your progress bar could be refreshed only a few times during the whole duration of your script, still one second lost for each time you use it. In other words, there is no good way of making a progress bar in photoshop scripting.

My question is: am I right? Is there a way to code a progress bar in PS that would not delay the code unreasonably?

TOPICS
Actions and scripting
6.1K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Guest
Oct 11, 2013 Oct 11, 2013

Just a follow up to my post above.

I ended up giving up the approach I was taking, that was to use the DOM. Too slow. It was taking one minute to process each image. Although I could live with that, I wanted something better, if it existed.

After reading and studying a lot the way of Action Manager, I managed to do the same thing using AM and now the progress bar is not necessary anymore. AM is too fast to need a progress bar!

Cheers.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 11, 2013 Oct 11, 2013

Hi,

palette windows aren't supported in PS since they close as soon as the code is done with them - i.e. you can't show a palette as you'd do with a dialog, waiting for the user to interact with them as modeless windows.

The app.refresh() / waitForRedraw() workaround is "broken" on CC (I use quotes because it was not supposed to work, but did anyway on CS6 and former versions).

Yet..

If you want to implement Palettes in Photoshop now the only reliable way is via BridgeTalk, as shown here. A bit weird because it's PS that sends a message to itself, but it works.

That said I've always used ProgressBars either inside 'dialog' windows or using disposable 'palette' windows - if there's a slowdown, I've never found it unacceptable.

Davide Barranca

www.davidebarranca.com

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Oct 11, 2013 Oct 11, 2013

Hi,

Thank you for the reply.

During my research on Photoshop script (I had never coded anything in PS script until around 2 weeks ago but I have a good experience with VBA and other languages which helps) I had found your page but I didn't want to follow your method first because BridgeTalk is a total stranger to me and secondly because in the last paragraph of that article, you write "since in a quite complex project I’m spending my time on (which started way before I knew about this technique), I’m still unable to make it work. The debugging is… quite complicate!".

My project is not complicated but still, considering my level of expertise, I am pretty sure it would take some time for me to get comfortable with it. Thanks anyway for the direction.

The main reason I gave up on using the progress bar was not the progress bar itself but the overall extreme slow speed of the DOM. The DOM hates recursion, hates going through layers and selecting them, etc. I'd say that from the one minute that it was taking to process an image (my file has around 300 layers), around 10 seconds was due to the implementation of the progress bar, so it was not the biggest culprit. The DOM itself is the problem.

What I am doing is re-writing everything (the routine using the DOM is done and does well what I want but it's slow) but using AM. I have learned enough about it (mostly from the people at ps-scripts.com), learned all the commands that I need in that weird AM style and I am blown away by its speed. Basically I do all I need using only AM commands, avoiding - when possible - to select layers to do work on them, until the last minute. I am not finished yet and I have no final measure but as far as I can foresee, I will be able to cut that one minute time to mere seconds, probably less than 5. It is really fast, as expected actually from good programming.

So, I place now very low priority into the progress bar. And if I have to learn even more complicated stuff to make it worthy, I will probably pass.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 11, 2013 Oct 11, 2013

Since I wrote that post I've learnt that BridgeTalk is pretty sensitive - for instance to binary code: instead to let .toSource() functions that needs to go to the message, you'd better of wrapping them into a String literal.

True, AM is lightning fast compared to DOM! But I won't use BridgeTalk for a Palette if the Palette is needed just for a progress bar. Such a Palette will stay alive while your script does all the things it's supposed to do without the need of waitForRedraw().

In my snippets library I've found this one that might help:

/*

* Create a progress window

* @param  {String}  title           = title

* @param  {String}  message         = message (updatable)

* @param  {Boolean} hasCancelButton = add a Cancel button (default: false)

* @usage          w = new createProgressWindow "Title", "Message", true

*/

createProgressWindow = function(title, message, hasCancelButton) {

  var win;

  if (title == null) {

    title = "Work in progress";

  }

  if (message == null) {

    message = "Please wait...";

  }

  if (hasCancelButton == null) {

    hasCancelButton = false;

  }

  win = new Window("palette", "" + title, undefined);

  win.bar = win.add("progressbar", {

    x: 20,

    y: 12,

    width: 300,

    height: 20

  }, 0, 100);

  win.stMessage = win.add("statictext", {

    x: 10,

    y: 36,

    width: 320,

    height: 20

  }, "" + message);

  win.stMessage.justify = 'center';

  if (hasCancelButton) {

    win.cancelButton = win.add('button', undefined, 'Cancel');

    win.cancelButton.onClick = function() {

      win.close();

      throw new Error('User canceled the pre-processing!');

    };

  }

  this.reset = function(message) {

    win.bar.value = 0;

    win.stMessage.text = message;

    return win.update();

  };

  this.updateProgress = function(perc, message) {

    if (perc != null) {

      win.bar.value = perc;

    }

    if (message != null) {

      win.stMessage.text = message;

    }

    return win.update();

  };

  this.close = function() {

    return win.close();

  };

  win.center(win.parent);

  return win.show();

};

Cheers,

Davide

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Oct 11, 2013 Oct 11, 2013

Sorry if I ask something dumb but I pasted the code above in a blank ESTK tab, as I do with all code that I want to test and learn, and if call the function and I set the ESTK itself as the target, it runs well and I get the cute little dialog. But if I set PS (CS6) as the target, I get a "createProgressWindows is not a function" error.

Why is it so?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 12, 2013 Oct 12, 2013

This one works as expected here in PS CC.

var pBar = new createProgressWindow("Work in Progress", "Please wait", false);

for(var i = 1; i <= 10; i++) {

    $.sleep(1000);

    pBar.updateProgress (i*10, "Waiting, " + i*10 + "% completed.");

}

Davide

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Oct 17, 2013 Oct 17, 2013

It works almost fine with ExtendScript Toolkit CS6 as the target. The static text flickers: it starts aligned to the left than instantly jumps to the center position for each update, but it is very visible.

It does not work fine with Photoshop CS6 64-bit as the target. It does not update the progress bar at all. Sleep() does not allow it to update. Progress bar stays empty all the time until it is done. Only app.refresh() or the waitForRedraw() routine can make this kind of progress bar work in PS, by calling them after each update, but then they add a delay of around 1-2 seconds for each time you update the progress bar.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 18, 2013 Oct 18, 2013

Only app.refresh() or the waitForRedraw() routine can make this kind of progress bar work in PS

Just to be clear for other readers of this thread. The progressbar updating does seem not to be working in CS6 and app.refresh() does seem to be a workaround.

But for other versions of Photoshop the progressbar works without app.refresh();

And I think there is more to what makes 'good programming' ( or scripting ) than speed. If you feel the user needs feedback that the script is still working by using a progressbar then the bar is useful even if it needs app.refresh() to work correctly. The app.refresh() call itself will give feedback the script is still processing. You can always balance the extra time the app.refresh() calls take by updating the bar fewer time. With the example above instead of updating the bar in every pass of the loop only update when i is even.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Oct 18, 2013 Oct 18, 2013

I agree with you regarding the usefulness of app.refresh() in PS CS6 despite it introducing a delay but ideally it should be a decision for the programmer to take: you would use app.refresh() IF you wanted to purposedly delay a little the execution for any reason but not because you just have to. The way it is you either use it to make the progress bar work/workable, or your progress bar will never work unless you use some more advanced solution like I think a flash interface or those Photoshop-like panels, things that I don't know how to code so I can't say much more about it.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 27, 2017 Nov 27, 2017
LATEST

I know this is an old post! But it is a fear that awakens interest: Davide_Barranca this script you posted looks interesting I come to ask you: I have a script that takes too long to process ... Where can I add my code so that the progress bar works correctly in this script?

  1. createProgressWindow = function(title, message, hasCancelButton) { 
  2.   var win; 
  3.   if (title == null) { 
  4.     title = "Work in progress"
  5.   } 
  6.   if (message == null) { 
  7.     message = "Please wait..."
  8.   } 
  9.   if (hasCancelButton == null) { 
  10.     hasCancelButton = false
  11.   } 
  12.   win = new Window("palette", "" + title, undefined); 
  13.   win.bar = win.add("progressbar", { 
  14.     x: 20
  15.     y: 12
  16.     width: 300
  17.     height: 20 
  18.   }, 0, 100); 
  19.   win.stMessage = win.add("statictext", { 
  20.     x: 10
  21.     y: 36
  22.     width: 320
  23.     height: 20 
  24.   }, "" + message); 
  25.   win.stMessage.justify = 'center'
  26.   if (hasCancelButton) { 
  27.     win.cancelButton = win.add('button', undefined, 'Cancel'); 
  28.     win.cancelButton.onClick = function() { 
  29.       win.close(); 
  30.       throw new Error('User canceled the pre-processing!'); 
  31.     }; 
  32.   } 
  33.   this.reset = function(message) { 
  34.     win.bar.value = 0
  35.     win.stMessage.text = message; 
  36.     return win.update(); 
  37.   }; 
  38.   this.updateProgress = function(perc, message) { 
  39.     if (perc != null) { 
  40.       win.bar.value = perc; 
  41.     } 
  42.     if (message != null) { 
  43.       win.stMessage.text = message; 
  44.     } 
  45.     return win.update(); 
  46.   }; 
  47.   this.close = function() { 
  48.     return win.close(); 
  49.   }; 
  50.   win.center(win.parent); 
  51.   return win.show(); 
  52. };
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Oct 17, 2013 Oct 17, 2013

In my snippets library I've found this one that might help

This code looks vaguely familiar....

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 18, 2013 Oct 18, 2013

This code looks vaguely familiar...

Chances are...

About 80% of my snippets come from either X, Mike Hale or Marc Autret (for ScriptUI stuff) - the progressbar I thought was by Marc, and I can even check, if the app I use to manage snippets, properly called "Snippets" would be so kind to actually start when I launch it and not hang causing me fatal heartattacks.

Davide

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines