photoshop-python-api
photoshop-python-api copied to clipboard
How to add a image as a layer?
Hello, I tried to use: **_from photoshop import Session
with Session(action="new_document") as ps:
desc = ps.ActionDescriptor
desc.putPath(ps.app.charIDToTypeID("null"), "your/image/path.jpg")
event_id = ps.app.charIDToTypeID("Plc ") # `Plc` need one space in here.
ps.app.executeAction(event_id, desc)_**
But I get the following error:
_**File "C:\Python39\lib\site-packages\photoshop\api\application.py", line 355, in executeAction
return self.app.executeAction(event_id, descriptor, display_dialogs)
File "C:\Python39\lib\site-packages\comtypes\client\lazybind.py", line 182, in caller
return self._comobj._invoke(descr.memid, descr.invkind, 0, *args)
File "C:\Python39\lib\site-packages\comtypes\automation.py", line 745, in _invoke
self.__com_Invoke(memid, riid_null, lcid, invkind,
_ctypes.COMError: (-2147212704, None, (None, None, None, 0, None))**_
Any idea why it could be? Thanks!!!
@Gaston2388
have you tried to replace this path using your actual file path?

Hi @loonghao, Yes, I replaced it. But it doesn't work. My program:
from photoshop import Session
with Session() as ps:
ps.app.documents.add(name='Image')
layer_set = ps.active_document.layerSets.add()
layer_set.name = "Image1"
desc = ps.ActionDescriptor
desc.putPath(ps.app.charIDToTypeID("null"),
"C:\\Python39\\img.jpg")
event_id = ps.app.charIDToTypeID("Plc ") # `Plc` need one space in here.
ps.app.executeAction(ps.app.charIDToTypeID("Plc "), desc)
Thanks!!!
@Gaston2388 Very strange, I tested your code to replace the image path it was successful on my side.

May I ask what is your windows version and photoshop version? examples of this API only this one doesn't work or did all not work?
Hi @loonghao , Thanks for answering.
I am using: Windows 10 Pro Photoshop CS6 Python 3.9
Thanks!!!
@Gaston2388 well, Photoshop CS6 is too old, I haven't tested it in the cs6 version. examples of this API only this one doesn't work or did all not work?
@loonghao I tried several things that worked. Examples that didn't work for me are this and Replace Images ("""Replace the image of the current active layer with a new image.""")
Yeah frankly I have to concur, I would definitely upgrade to at least 2020. The improvements to Photoshop made since then are monumental, you won't believe the efficiency gains alone.
BRUH THIS EXAMPLE IS WRONG!
with Session(action="new_document") as ps:
desc = ps.ActionDescriptor # <-
desc.putPath(ps.app.charIDToTypeID("null"), "your/image/path.jpg")
event_id = ps.app.charIDToTypeID("Plc ") # `Plc` need one space in here.
ps.app.executeAction(event_id, desc)
Look at that line with # <-, desc is given THE CLASS ps.ActionDescriptor!
At least that line should be: desc = ps.ActionDescriptor(), then desc is AN INSTANCE OF ps.ActionDescriptor.
What's more, CS6 should not be able to run that "convert to smart object" example as well. (because of some id change)
I just wonder if our maintainers have ever tried this example. It SHOULDN'T be able to run on EVERY version of ps!
Well, it still won't work after you add the missing () because it lacks other parameters.
I'll include a working example in my PR.
BRUH THIS EXAMPLE IS WRONG!
with Session(action="new_document") as ps: desc = ps.ActionDescriptor # <- desc.putPath(ps.app.charIDToTypeID("null"), "your/image/path.jpg") event_id = ps.app.charIDToTypeID("Plc ") # `Plc` need one space in here. ps.app.executeAction(event_id, desc)Look at that line with
# <-, desc is given THE CLASSps.ActionDescriptor! At least that line should be:desc = ps.ActionDescriptor(), then desc is AN INSTANCE OFps.ActionDescriptor. What's more, CS6 should not be able to run that "convert to smart object" example as well. (because of some id change) I just wonder if our maintainers have ever tried this example. It SHOULDN'T be able to run on EVERY version of ps!
It turned out that in session they give an instance of ActionDescriptor to session object as attribute, so it can work (but maybe not properly) without that (). The real reason is that this ActionManager code lacks some parameters, because its js equivalent doesn't work on ExtendScript either.
"give an instance of ActionDescriptor to session object as attribute" is like defining an empty dict at the top of a py file and use it EVERY time you need to use a dict without cleaning it.