Skip navigation
Currently Being Moderated

Document::saveAs doesn't work in Photoshop

Aug 23, 2010 1:58 AM

Hello,

 

I am having a problem trying to save the current document in Photoshop to the PNG format.

I am trying to use the Document class from the com.adobe.photoshop package.

 

The code that I have looks like this:

 

public function saveAsPNG(filePath:String):Boolean

{

      var saveOpts:PNGSaveOptions = new PNGSaveOptions;

      saveOpts.interlaced = false;

      var file:File = new File(filePath);

      var currentDoc:Document = Photoshop.app.activeDocument;

      currentDoc.saveAs(file,saveOpts,true);

      return true;

}

 

I call this function in response to a button click in the UI. However when the execution gets to , I get the following error:

Error: General Photoshop error occurred. This functionality may not be available in this version of Photoshop.

 

This error looks like the one that occurs when I try to access Photoshop DOM from a system event handler (as discussed here), so I tried to apply the workaround recommended for system events in my function:

public function saveAsPNG(filePath:String):Boolean

{

      var obj: * = PsEventScrubber.getInstance().forceClean( this, saveAsPNG, arguments );

      if ( obj != null )

      {

            return (obj as Boolean);

 

      }

      var saveOpts:PNGSaveOptions = new PNGSaveOptions;

      saveOpts.interlaced = false;

      var file:File = new File(filePath);

      var currentDoc:Document = Photoshop.app.activeDocument;

      currentDoc.saveAs(file,saveOpts,true);

      return true;

}

 

Now I get an exception, and I can see that the logger is called with the following message:

[RequestResult after parsing result="[RequestResult status="PlugPlugRequestFailed" data=null]" ]

 

I also tried to use ActionDescriptors to do the same job, but I got the same problems as with the CSAW API. The code for the ActionDescriptor approach is below:

 

public function saveAsPNG1(filePath:String):Boolean

{

      var obj: * = PsEventScrubber.getInstance().forceClean( this, saveAsPNG1, arguments );

      if ( obj != null )

     {

          return (obj as Boolean);

     }

 

     var key_in:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("In  ");

     var key_png_interlaced:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("PGIT");

     var enum_png_interlaced_none:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("PGIN");

     var key_png_filter:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("PNGf");

     var enum_png_filter_adaptive:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("PGAd");

     var key_copy:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("Cpy ");

     var key_extn:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("Extn");

     var key_as:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("As  ");

     var class_png_format:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("PNGF");

     var event_save:int = com.adobe.csawlib.photoshop.Photoshop.app.charIDToTypeID("save");

 

    

     var result:ActionDescriptor = null;

     var desc:ActionDescriptor = new ActionDescriptor;

     var PNGDescriptor:ActionDescriptor = new ActionDescriptor;

 

 

     var file:File = new File(filePath);

     desc.putPath(key_in,file);

     desc.putBoolean(key_copy,true);

     desc.putBoolean(key_extn,true);

 

     PNGDescriptor.putEnumerated( key_png_interlaced, key_png_interlaced, enum_png_interlaced_none);

     PNGDescriptor.putEnumerated(key_png_filter, key_png_filter, enum_png_filter_adaptive);

 

     desc.putObject(key_as,class_png_format,PNGDescriptor);

     result = com.adobe.csawlib.photoshop.Photoshop.app.executeAction(event_save,de sc);

 

     return true;

}

 

With this approach the error occurs then the execution gets to the line

...

desc.putPath(key_in,file);

...

 

Am I doing something wrong here?

Has anyone tried to use the Document::saveAs API in Photoshop?

 

Thank you in advance,

Anatoly

 
Replies
  • Currently Being Moderated
    Aug 23, 2010 1:29 PM   in reply to Anatoly Paraev

    Anatoly,

     

    As we are learning more about the workaround and it's specific limitations and usage, we're reworking the library a bit.

     

    I don't expect you'll have any trouble with the next version which I hope to have out in an hour or so. There's also one addition method for applying the workaround.

     

    Bob

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 23, 2010 3:49 PM   in reply to Anatoly Paraev

    Anatoly,

     

    I see you have a filePath - did that come from a file dialog? If so, that's a system event, and you need the workaround.

     

    We're finding that you can get blindsided - you think you're in a safe context, but you're not...

     

    I've attached a new library. I ran the case of saving a PNG file (very similar to your code) without a failure.

     

    I am also working on updating the cookbook as this library contains a new method: macSafeAddEvenListener

     

    Here's an example of usage:

     

    var timer = new Timer( 100, 1 );

    PsEventScrubber.getInstance().macSafeAddEventListener( timer, TimerEvent.TIMER, myHandler );

     

    When the timer event fires, myHandler will be called in a safe context.

     

    With this approach you avoid needing a proxy handler, and there no scoping issues. I consider this approach to be the best, with the forceClean being reserved for those times when it's the only way.

     

    And on another note, there are still calls which can fail. Specifically a few of the Script Listener outputs can be problematic. If you run into any, please let me know.

     

    Regards

    Attachments:
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 23, 2010 4:54 PM   in reply to Anatoly Paraev

    Say what? I ran it both ways...

     

    Is it possible to send me the project or class file?

     

    bostucky@adobe.com

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 23, 2010 9:03 PM   in reply to Bob Stucky

    I just re-tested, my saveAs code works fine with the forceClean method.

     

    Bob

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 16, 2010 3:01 PM   in reply to Anatoly Paraev

    Not sure why it crashes - but I can tell you that the way it works is recursive in nature.

     

    When you call forceClean inside a function, it executes the workaround, and then calls the function again. Naturally then, forceClean gets called second time, detects that condition, skips the workaround part, and executes code that sets up the final return conditions. It's quite possible that your code is screwing up that second call detection.

     

    Could you send me the smallest possible sample of your code that fails? If I can figure out why, it's likely fixable.

     

    On the ucf tool, can you refresh my memory on the question (probably a good new post).

     

    Thanks

     

    Bob

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 16, 2010 3:13 PM   in reply to Anatoly Paraev

    Oops, that ucf thing got lost in my brain somewhere.

     

    I'l look a that tomorrow; and,  I won't forget this time!

     

     

    Bob

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 16, 2010 4:02 PM   in reply to Bob Stucky

    It hasn't arrived. Can you stuff it somewhere I can download?


     
    |
    Mark as:
  • Currently Being Moderated
    Sep 16, 2010 4:22 PM   in reply to Anatoly Paraev

    Got it, thanks


     
    |
    Mark as:
  • Currently Being Moderated
    Sep 22, 2010 2:07 PM   in reply to Anatoly Paraev

    I get the same with your code. I don't see anything wrong with the workaround code. That the dialog you've opened is not closed when the save function executes. PS would be still be in a modal state. That could do it.

     

    Bob

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points