photoshop-python-api icon indicating copy to clipboard operation
photoshop-python-api copied to clipboard

Cannot replace an image layer

Open Edimo05 opened this issue 3 years ago • 11 comments

Describe the bug I am trying to replace an image layer in a photoshop file. For that purpose I am using this next code:

To Reproduce This is my python code: with Session() as ps: replace_contents = ps.app.stringIDToTypeID("placedLayerReplaceContents") desc = ps.ActionDescriptor idnull = ps.app.charIDToTypeID("null") desc.putPath(idnull, "G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg") ps.app.executeAction(replace_contents, desc)

Expected behavior It suppose to replace already existing image layer but instead of thar it show an error message and log.

Screenshots Photoshop error message: image

Terminal message: Traceback (most recent call last): File "g:\Blebleble\blablabla\blablabla\blablabla\Publicaciones\AUTOMATION\automate.py", line 43, in ps.app.executeAction(replace_contents, desc) File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\photoshop\api\application.py", line 355, in executeAction return self.app.executeAction(event_id, descriptor, display_dialogs) File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\comtypes\client\lazybind.py", line 182, in caller return self._comobj._invoke(descr.memid, descr.invkind, 0, *args) File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\comtypes\automation.py", line 745, in _invoke self.__com_Invoke(memid, riid_null, lcid, invkind, _ctypes.COMError: (-2147213497, None, (None, None, None, 0, None))

Desktop (please complete the following information):

  • OS: Windows 11 Home
  • Photoshop Version: Adobe Photoshop Version: 22.5.4 20211208.r.631 a0cb269 x64
  • Python Version: python-3.10

Additional context This code actually worked once but suddenly it stopped working.

Edimo05 avatar Aug 12 '22 04:08 Edimo05

Sorry but I can't help you directly. Though this happened to me too (including the code working only once), and I worked around it by simply importing the new image and getting rid of the old one in another way.

blunderedbishop avatar Aug 12 '22 10:08 blunderedbishop

Sorry but I can't help you directly. Though this happened to me too (including the code working only once), and I worked around it by simply importing the new image and getting rid of the old one in another way.

Thanks, I will give it a try.

Edimo05 avatar Aug 12 '22 12:08 Edimo05

Have you tried to look at #174? What's missing in your code is setting the active layer: ps.active_document.activeLayer = layer. Maybe that'll work.

blunderedbishop avatar Aug 12 '22 12:08 blunderedbishop

@Edimo05 You can try to add r in the file path, to ensure the code use raw path

desc.putPath(idnull, r"G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg")

loonghao avatar Aug 12 '22 13:08 loonghao

@Edimo05 You can try to add r in the file path, to ensure the code use raw path

desc.putPath(idnull, r"G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg")

@loonghao I tried and doesn't work. Still getting the same error.

Edimo05 avatar Aug 12 '22 14:08 Edimo05

@loonghao I tried this code (https://loonghao.github.io/photoshop-python-api/examples/#replace-images) but I cannot import examples._psd_files. I already installed photoshop_python_api.

Edimo05 avatar Aug 12 '22 14:08 Edimo05

Have you tried to look at #174? What's missing in your code is setting the active layer: ps.active_document.activeLayer = layer. Maybe that'll work.

@blunderedbishop I tried change my code to this: with Session() as ps: ps.active_document.activeLayer = doc.ArtLayers["08"] replace_contents = ps.app.stringIDToTypeID("placedLayerReplaceContents") desc = ps.ActionDescriptor idnull = ps.app.charIDToTypeID("null") desc.putPath(idnull, r"G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg") ps.app.executeAction(replace_contents, desc)

and it shows next error: Traceback (most recent call last): File "g:\Blebleble\blablabla\blablabla\blablabla\Publicaciones\AUTOMATION\automate.py", line 40, in ps.active_document.activeLayer = doc.ArtLayers["08"] File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\photoshop\api_document.py", line 83, in activeLayer self.app.activeLayer = layer File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\comtypes\client\lazybind.py", line 218, in setattr self._comobj._invoke(descr.memid, descr.invkind, 0, value) File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\comtypes\automation.py", line 737, in _invoke array[i].value = a File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\comtypes\automation.py", line 231, in _set_value elif (hasattr(value, 'len') and len(value) == 0 File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 303, in len raise TypeError("This dispatch object does not define a Count method") TypeError: This dispatch object does not define a Count method

maybe I placed that code u mentioned wrong?

Edimo05 avatar Aug 12 '22 14:08 Edimo05

@Edimo05 ArtLayers is a list, you need artLayer + index to access it

doc.ArtLayers["08"]
with Session() as ps:
    ps.active_document.activeLayer = doc.artLayers.getByName("08")
    replace_contents = ps.app.stringIDToTypeID("placedLayerReplaceContents")
    desc = ps.ActionDescriptor
    idnull = ps.app.charIDToTypeID("null")
    desc.putPath(idnull, r"G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg")
    ps.app.executeAction(replace_contents, desc)

loonghao avatar Aug 13 '22 03:08 loonghao

@Edimo05 ArtLayers is a list, you need artLayer + index to access it

doc.ArtLayers["08"]
with Session() as ps:
    ps.active_document.activeLayer = doc.artLayers.getByName("08")
    replace_contents = ps.app.stringIDToTypeID("placedLayerReplaceContents")
    desc = ps.ActionDescriptor
    idnull = ps.app.charIDToTypeID("null")
    desc.putPath(idnull, r"G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg")
    ps.app.executeAction(replace_contents, desc)

@loonghao now is showing this error: Traceback (most recent call last): File "g:\Blebleble\blablabla\blablabla\blablabla\Publicaciones\AUTOMATION\automate.py", line 55, in ps.active_document.activeLayer = doc.ArtLayers.getByName("08") File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 628, in getattr ret = self.oleobj.Invoke(retEntry.dispid, 0, invoke_type, 1) pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Adobe Photoshop', 'Illegal argument - argument 1\n- Required value is missing', None, 0, -2147220262), None)

Edimo05 avatar Aug 13 '22 04:08 Edimo05

@Edimo05

doc.ArtLayers.getByName("08") 

ArtLayers first letter lowercase

doc.artLayers.getByName("08")

loonghao avatar Aug 13 '22 06:08 loonghao

@Edimo05

doc.ArtLayers.getByName("08") 

ArtLayers first letter lowercase

doc.artLayers.getByName("08")

@loonghao nothing man, same error:

Traceback (most recent call last): File "g:\Blebleble\blablabla\blablabla\blablabla\Publicaciones\AUTOMATION\automate.py", line 75, in ps.active_document.activeLayer = doc.artLayers.getByName("08") File "C:\Users\bliblibli\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 628, in getattr ret = self.oleobj.Invoke(retEntry.dispid, 0, invoke_type, 1) pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Adobe Photoshop', 'Illegal argument - argument 1\n- Required value is missing', None, 0, -2147220262), None)

Edimo05 avatar Aug 13 '22 14:08 Edimo05

@Edimo05 replace image only support ArtLayer as a smart object layer image

Please convert the 08 layer as a smart-object first and then execute the following code

from photoshop import Session

with Session() as ps:
    doc = ps.active_document
    doc.activeLayer = doc.artLayers.getByName("08")
    replace_contents = ps.app.stringIDToTypeID("placedLayerReplaceContents")
    desc = ps.ActionDescriptor
    idnull = ps.app.charIDToTypeID("null")
    desc.putPath(idnull, r"G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg")
    ps.app.executeAction(replace_contents, desc)

loonghao avatar Aug 13 '22 15:08 loonghao

@Edimo05 replace image only support ArtLayer as a smart object layer image

Please convert the 08 layer as a smart-object first and then execute the following code

from photoshop import Session

with Session() as ps:
    doc = ps.active_document
    doc.activeLayer = doc.artLayers.getByName("08")
    replace_contents = ps.app.stringIDToTypeID("placedLayerReplaceContents")
    desc = ps.ActionDescriptor
    idnull = ps.app.charIDToTypeID("null")
    desc.putPath(idnull, r"G:\BLEBLE\BLABLABLA\BLABLABLA\BLABLABL\BLABLA\2022\August\Images\09.jpeg")
    ps.app.executeAction(replace_contents, desc)

@loonghao finally works. That layer was already an smart object, I think I missed ps.active_document. Thanks a lot!!!

Edimo05 avatar Aug 13 '22 18:08 Edimo05

@Edimo05 good to hear, closing issue.

loonghao avatar Aug 14 '22 02:08 loonghao