Copy link to clipboard
I (foolishly) upgraded to Mac OSX Monterey, which in turn forced me to upgrade my Photoshop version to Photoshop 2022.
With Photoshop CC 2018 I used the following python code to get a specific layer by name:
from appscript import * self.psApp = app('/Applications/Adobe Photoshop CC 2018/Adobe Photoshop CC 2018.app') for layer_set in self.psApp.current_document.layer_sets(): for group in layer_set.layers.get(): if group.name() == "image_1": return group
Which worked great! Docs can be found here by the way.
But, when using the same code and replacing Adobe Photoshop CC 2018 with Adobe Photoshop 2022 I get an 'Unknown Property' error:
AttributeError: Unknown property, element or command: 'current_document'
And I can't get anything else to work anymore, the 'current_document' property seems to be gone or maybe renamed?
Any help would be greatly appreciated. The documentation for this is pretty much non-existent unfortunately.
Thanks in advance!
Copy link to clipboard
You obviously have a need to do this through Python, I can't help with that.
var selectLayer1 = app.activeDocument.artLayers.getByName("Layer 1"); app.activeDocument.activeLayer = selectLayer1;
app.activeDocument.activeLayer = app.activeDocument.layers["Layer 1"];
As the AS wraps the JS in double quotes, any double quotes in the JS need to be escaped with a \ backslash:
EDIT: Or you could change double quotes in the JS to use single open/close quotes so that there is no conflict with the double quotes used in the AS.
I am actually already able to send Applescript via python, I'll post it here for anybody else who wants to know how to do that:
from subprocess import Popen, PIPE def run_appscript(self, script): p = Popen(['osascript', '-'], stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True) stdout, stderr = p.communicate(script) # example def quit_photoshop(self): self.run_appscript('tell application "Adobe Photoshop 2022" to quit')
The only thing i'd miss is a way to communicate back from Photoshop to my Python/Applescript script. For example, if I want to get the name of a layer and use that later on in my script. Would you perhaps know a way to do so?
No problem, thank you for your help! I'll wait a bit to see if others might come up with something else but otherwise I'll mark your anwser as the correct one as it potentially could be a workaround
I obviously know how to get the layer name as a variable in JS, but I have no idea with the extra complexity that you have with adding two other scripting langauages into the mix – I find one language hard enough!
What are you doing in/with Python that can't be achieved using AS or JS?
I think I'm going to solve it by making the js write data to a temporary js file that I can in turn read with my python application, quite the workaround but it's looking like the only option to get information back out from photoshop.
Thank you for the explanation.
Copy link to clipboard
(Sorry about the necromancy)
Seems appscript can't pick up Photoshop's scripting definition anymore, and unfortunately appscript official development ended development many moons ago, so there's likely to be no fix for this.
One alternative is to use the PyObjC Python module to access Apple's ScriptingBridge for Objective-C. This is clunky, since you are effectively writing Objective-C code, but "translated" into Python, but it gets the job done and this is the solution I'm currently using.
Some sample code to get you started, here's how you could do what you wanted above:
from ScriptingBridge import SBApplication class YourClass: def some_method(self): self.psApp = SBApplication.applicationWithBundleIdentifier_("com.adobe.Photoshop") for layer_set in self.psApp.currentDocument().layerSets(): for group in layer_set.layers().get(): if group.name() == "image_1": return group
Photoshop Specific Limitations:
Translation between Objective-C and Python makes your code super verbose. For example:
Some (lots) of functions will need magic enum numbers from the Photoshop sdef file (like the b'Nevr' above). You can reference those by opening Script Editor, opening the Photoshop scripting dictionary, and then File -> Save As, open the file you just saved with a text editor, and you'll be able to see the values you need for each function.
I won't babble on more, but for Photoshop scripting this is seems like the most usable option now that appscript is dead.
Here's an old Apple doc explaining most things.
Ah just been looking around at the source for appscript and found this. Do not use ScriptingBridge lol. You can get appscript working with modern Photoshop versions by using the "terms" argument in the constructor:
from appscript import app app(photoshop_path, terms="sdef")