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
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
Bob,
Thank you for the prompt response.
I am not sure why I need to use the workaround in this situation - as I mentioned, I call the saveAs function in a button click handler, not in a OS-originated event handler. Does the Photoshop bug affect some UI-originated events as well?
Thank you,
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
Bob,
Thank you so much, saveAs now works if used in the context of a listener added with macSafeAddEventListener.
However if I try to use forceClean and then call Document.saveAs, Photoshop reliably crashes.
I'm quite happy to use macSafeAddEventListener, but if you could make forceClean work too, that would be just fantastic!
Once again, thank you for the immediate assistance!
Anatoly
I have figured out that the crash occurs under a special condition: before using forceClean and saveAs I open and a modal dialog (a window with the CSXSWindowType.MODAL_DIALOG type). If, after closing such a window, I attempt to use the workaround and then do saveAs, Photoshop consistently crashes (looks like a stack overflow to me). If I don't use the modal window, everything works fine.
I am emailing you a minimal project that demonstrates the problem - please let me know if I can do anything to help,
Anatoly Paraev
Hi Bob,
I have been using the PsEventScrubber library, and I came accross one more function which crashes Photoshop if called after forceClean, which in turn is called immediately after using a modal dialog (CSXSWindowType.MODAL_DIALOG). This time it's Document.closeFile().
It looks like using forceClean in the current version of the library is dangerous - I am not sure if there are any other methods that can crash Photoshop if called under similar condition. Do you know why using a modal dialog is so dangerous for forceClean? Do you have any plans to fix this problem in later versions of the PsEventScrubber library?
Also, do you know if the Photoshop team has made any progress on the proper fix of this problem?
On an unrelated note, I noticed that you answered my another question about signing hybrid extension and using the ucf tool. Did you have a chance to take a look at this tool?
I know it's a lot of questions for one post, sorry for this:)
Thank you so much,
Anatoly
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
Bob, I just emailed you a minimal project that reproduces the crash (to bostucky@adobe.com).
Regarding the ucf.jar - here is the post: http://forums.adobe.com/thread/708614
Thank you,
Anatoly Paraev
Here it is: http://bit.ly/9rocLa
Bob, you are absolutely right, thank you so much!
If I wait for the close event in the dialog and then use the Photoshop DOM then everything works fine.
Thanks again, you really helped me with the Photoshop events.
If you could also help me with the ucf.jar tool, you'll be my hero!:)
Anatoly
North America
Europe, Middle East and Africa
Asia Pacific