loonghao / photoshop-python-api

Python API for Photoshop.
https://loonghao.github.io/photoshop-python-api/
MIT License
598 stars 68 forks source link

Photoshop API with python multithreading #313

Open djs45 opened 9 months ago

djs45 commented 9 months ago

Hello.

I need to use Photoshop API in a threading or multiprocessing function in python but i seems to be impossible. Can you help me ? Many thanks

I write a sample example :

##############################

import photoshop.api as ps

def testPS(): try: app = ps.Application() app.load("test.psd") except Exception as e: print (e)

import time import multiprocessing p = multiprocessing.Process(target=testPS) p.start() p.join()

print ("***")

from threading import Thread t1 = Thread(target=testPS) t1.start() t1.join()

print ("***")

Investigamer commented 8 months ago

It is technically possible to perform Photoshop actions in a multi-threaded or multi-process manner, however you will have to use a locking mechanism on any tasks Photoshop performs. Photoshop handles all automation calls synchronously, and if you issue a command while another command is already taking place it will throw an exception. Here's an example:

from threading import Lock
from concurrent.futures import ThreadPoolExecutor
from photoshop.api import Application

# Locking mechanism
ps_lock = Lock()

def some_task(num: int = 0):
    # Any Photoshop interaction MUST be locked
    with ps_lock:
        # Lock ensures other threads wait for the current thread to complete this step
        app = Application()
        app.activeLayer.name = f"Layer {num}"
    # Do some other non-Photoshop task, doesn't need to be locked
    print("Hello")
    return True

# Map some numbers to some_task in a thread pool
vars = [1, 2, 3, 4, 5]
with ThreadPoolExecutor() as exec:
    results = exec.map(some_task, vars)
    results = list(results)

Overall, it doesn't make a whole lot of sense to pair multi-threading/multi-process with Photoshop tasks, since you can only issue one task at a time and it means you have to manage and be mindful of document and layer state in each separate thread. Although, if you have some resource and time intensive tasks in between the Photoshop tasks, it may make sense under some circumstances. Generally speaking though, I would isolate those tasks and multithread them separately from the Photoshop tasks and then perform the photoshop tasks in series/synchronously before/afterwards.

Also bear in mind there are times where the application object can become stale from one thread to another, its generally a good idea to create the application object within the thread like shown here, although sharing the same object across threads is totally possible if you manage it correctly (I do so in my own application).

djs45 commented 5 months ago

Sorry I didn't see your answer. Thank you. I need multithreading to do another task at the same time as Photoshop do a task. I will try this. Many thanks.