macOS下如何通过Python自动化调用Adobe Photoshop 2025执行.jsx脚本
macOS下如何通过Python自动化调用Adobe Photoshop 2025执行.jsx脚本
看起来你已经折腾了好几种osascript命令,但都因为参数类型或者语法不对报错了,好在直接在PS里运行JSX是正常的,那问题就出在怎么用AppleScript正确把JSX脚本传给Photoshop执行上,我来帮你拆解问题并解决:
先说说你之前的命令为啥报错
- 第一个命令:
osascript -e 'tell application "Adobe Photoshop 2025" to do javascript ("path/to/my/jsx/file")'
Photoshop的do javascript指令需要的是JavaScript代码文本,不是文件路径,你直接传路径会被当成JS语法解析,自然会报语法错误(Expected: ;)。 - 第二个命令:
osascript "path/to/my/jsx/file"
osascript默认是用来执行AppleScript的,JSX不是AppleScript语法,所以会解析失败。 - 第三个命令:
osascript -e 'tell application "Adobe Photoshop 2025" to do javascript (POSIX file "path/to/my/jsx/file")'POSIX file是AppleScript里的文件对象,但do javascript不接受这种对象类型,它只认文本内容,所以报错“Can’t get POSIX file.”
正确的解决方案:读取JSX内容再传给Photoshop
核心思路是:先用AppleScript读取JSX文件的文本内容,再把内容传给Photoshop的do javascript执行。下面给你两种可行的方式:
方式1:修改你的runjavascript.scpt文件
把原来的scpt内容替换成下面的AppleScript代码,它会先读取JSX文件内容,再传给PS执行:
tell application "Adobe Photoshop 2025" activate -- 确保PS处于激活状态,避免权限问题 set jsxFilePath to "/Users/ishikagurnani/Documents/full_automate_photobooth.jsx" -- 读取JSX文件的UTF-8内容 set jsxContent to read file (POSIX file jsxFilePath) as «class utf8» -- 执行JSX脚本 do javascript jsxContent end tell
方式2:直接在Python代码里构造osascript命令(无需单独scpt文件)
如果你不想维护单独的scpt文件,可以直接在Python的process_photos方法里构造完整的AppleScript命令,这样还能直接复用你定义的script_path变量:
def process_photos(self): print(f"Photos detected: {self.photos}") try: # 直接构造AppleScript命令读取并执行JSX subprocess.run( [ "osascript", "-e", 'tell application "Adobe Photoshop 2025"', "-e", "activate", "-e", f'set jsxContent to read file (POSIX file "{self.script_path}") as «class utf8»', "-e", "do javascript jsxContent", "-e", "end tell" ], check=True ) print("Photoshop script executed successfully!") except subprocess.CalledProcessError as e: print(f"Error running Photoshop script: {e}")
额外注意事项
- 权限问题:macOS的隐私设置里,要确保你的Python环境(比如终端、PyCharm等)有权限访问目标文件夹和Adobe Photoshop 2025,否则可能出现文件读取失败或者无法控制PS的情况。
- 如果你的JSX脚本需要处理新添加的图片,记得在JSX里获取图片路径(或者你可以在Python里把图片路径传给JSX,这需要修改AppleScript和JSX的交互逻辑,比如把路径作为参数传入)。
修正后的完整Python代码示例
from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler import time import subprocess class PhotoHandler(FileSystemEventHandler): def __init__(self, target_folder, script_path): self.target_folder = target_folder self.script_path = script_path self.photo_count = 0 self.photos = [] def on_created(self, event): if event.is_directory: return if event.src_path.endswith(('.jpg', '.jpeg', '.png', '.ARW')): self.photos.append(event.src_path) self.photo_count += 1 if self.photo_count == 3: self.process_photos() self.photo_count = 0 self.photos = [] def process_photos(self): print(f"Photos detected: {self.photos}") try: # 直接构造AppleScript命令读取并执行JSX subprocess.run( [ "osascript", "-e", 'tell application "Adobe Photoshop 2025"', "-e", "activate", "-e", f'set jsxContent to read file (POSIX file "{self.script_path}") as «class utf8»', "-e", "do javascript jsxContent", "-e", "end tell" ], check=True ) print("Photoshop script executed successfully!") except subprocess.CalledProcessError as e: print(f"Error running Photoshop script: {e}") # Configuration folder_to_watch = r"/Users/ishikagurnani/Pictures/Test/Auto Imported Photos" script_path = r"/Users/ishikagurnani/Documents/full_automate_photobooth.jsx" event_handler = PhotoHandler(folder_to_watch, script_path) observer = Observer() observer.schedule(event_handler, folder_to_watch, recursive=False) observer.start() try: print("Monitoring folder for new photos...") while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
备注:内容来源于stack exchange,提问作者Ishika Gurnani
相关产品推荐
相关产品推荐

