Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Photoshop API with python multithreading #313

Open
djs45 opened this issue Oct 10, 2023 · 3 comments
Open

Photoshop API with python multithreading #313

djs45 opened this issue Oct 10, 2023 · 3 comments

Comments

@djs45
Copy link

djs45 commented Oct 10, 2023

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
Copy link
Contributor

Investigamer commented Nov 3, 2023

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
Copy link
Author

djs45 commented Jan 23, 2024

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.

@Mideky-hub
Copy link

Try using joblib and delay the function using delayed (func)(**kwargs), backend with threading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants