How to Develop Photoshop Tools in Python

Pre Reqs:

  • Ability to read and understand javascript
  • Writing Adobe Scripts in Javascript
  • Python Knowledge and practices
  • PySide or TkInter Knowledge
  • Basic Troubleshooting

Tools:

  • Adobe Documentation Javascript Guide
  • Adobe SDK
  • Pycharm (or preferred python IDE)

Intro:

Hello out there. If you are reading this then you either want to save yourself time, save someone else time or you want to make a cross platform application without developing an adobe plugin.

Whatever your reason you will learn the various situations this skill may be useful and I will cover a lot of the headaches of digging through undocumented functions to deliver a final product.

Warning – You cannot use this technique to write Generator Scripts due to generator needing to access node.js

What you will learn:

  • The major difference between Javascript and Python
  • How to convert javascript scripts to python scripts
  • Using the Action Manager
  • Using COM in Python
  • Finding functions not documented in adobe documentation
  • How to troubleshoot to find the information you need

Getting Started:

If you haven’t done so please go through http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/photoshop/pdfs/photoshop-cc-scripting-guide.pdf

File() Folder() vs path module

In Javascript you access files and folders with a File() or Folder() Object. You can then do logic checks to see if a var type equals either object.

03-JavaFileFolder

In python you have to check if the provided path is a directory or a file.

03-PythonFileFolder

For Loops

The easiest way to re-implement the a for I = 0; I < x; i++ is by using for I in range (0,x)

04-JavaCodeConvertAfter

How to Convert a Function from Javascript to Python

There are 4 major Find Replace Search’s which will take care of 90% of all work involved

  • Find (;) Replace with () <-nothing
  • Find (var) Replace with () <-nothing
  • Find ({) Replace with (:) <-Colon
  • Find (}) Replace with () <-nothing
  • Find (new) Replace with () <-nothing

Other than that you want to:

Example:

Before:                                                                After:         

04-JavaCodeConvertBefore04-JavaCodeConvertAfter-2

How to connect python to Photoshop:

Using win32COM Library

  1. Import win32COM.client from win32COM Library0-comtypes
  2. Find Adobe Registry details

01-RegistryPhotoshopStart

01-RegistryPhotoshop

For Photoshop the registry is Photoshop.Application.80

  1. Dispatch Connection to Adobe Registry Remember to use:80 to reference the latest version of photoshop

02-CodeSnippetWin32

Using comtypes Library

If you do not have comtypes library use pip –install comtypes 0-pipInstallcom

  1. import CreateObject from comtypes.client0-comtypes
  2. Find application Registry details

01-RegistryPhotoshopStart

01-RegistryPhotoshop

For Photoshop the registry is Photoshop.Application.80

  1. Create a Connection to Application Registry. Remember to use :80 to reference the latest version of application

02-CodeSnippetCOMTypes

Finding functions not documented in adobe documentation

This caused me some trouble while trying to use dot notation for ArtLayers and LayerSets.

To find the python equivalent of all functionality available the easiest way is to use makepy.py to create an API form the Adobe Photoshop object Library.

How I used Makepy.py

  1. Create a new Python Script
  2. Import makepy and genCache modules from win32com.client
  3. Run the main() function for makepy
  4. Use gen cache to return Generated python file path
  5. Run Script and select the Photoshop Object Library
  6. Navigate to path and copy file to local directory

05-MakePyCmdFull

05-MakePyObjectLibrarySelection

05-MakePyResult

How to use this file

Open the generated file with your chosen IDE – you will see the Generated Constants that PS uses to hold all enums, then all classes with their parameters.

To access all these functions in your script you only have to call the Dispatch object you created and use dot notation to call the function or variable.

For Ex:

psApp = CreateObject(“Photoshop.Application.80”)

artLayers = psApp.activeDocument.artLayers

Using the Action Manager to optimize your script

This is the fun part of Adobe Photoshop in my opinion – though it is hard to get a grasp for the lack of documentation I am going to try to simplify this as much as possible.

Why use Action Manager for every command you can?

You want a performance friendly automation tool? Every access to the DOM is going to cost you atleast a second of processing time – it’s just the facts. ActionManager utilized a lower level access to photoshop objects and commands – BUT THERES NO DOCUMENTATION.  You have to use script listener to find out what actions you have access to.

Please follow the Adobe Scripting guide for usage and installation of the script listener

Resources before you begin

You are going to need a way to understand what each string or type id means.

I Use http://www.pcpix.com/photoshop/enum.htm

This is a type to plain English translation of all enum’s the action manager can use

Classes you will need to have

06-ActionManagerClasses

How to read an action

Throughout working with action manager I have broken down build of and reading of an action into 3 parts. Description, Reference, Execution.

Warning: This is my personal way of viewing the action manager. It could be wrong but it works for my understanding

  1. Define a description of the Action
  2. Build a reference to the Action
  3. Execute the Action

Lets take a well known example which is SetActiveLayerByIndex().

06-ActionManagerExample

  1. First you are Initializing a new Action Description and Reference
  2. The object you are referencing is a Layer(Lyr ) Object with an index of idx
  3. You are adding this reference as the default reference object to the Action Description (Which describes the action you want to execute). This default reference is noted with the “null” value
  4. You are adding a special parameter to MakeVisible(MKVs) and setting visibility to parameter
  5. You are Executing the Action “Select” with the current photoshop Dispatch Object, we don’t want any dialogs so we use no dialogs or the int(3)

Boom you’ve just set active layer by index.

Lets take a more obscure example and break it down. Lets offset the active layer by an x,y amount

06-ActionManagerExample2

  1. So here we are Getting the TypeID for Transform. Transform controls the position, scale and rotation of our asset.
  2. We are creating a description for the mainEventDetails to add our references and special commands
  3. We are getting the FreeTransform TypeID, QuadCenterState since we are working with a four sided flat object, then we get the Average(Exact Middle) of the CenterState
  4. We are setting this as the target for our action so we put in this information as an enumeration
  5. We now create a separate description which will tell our action how much to offset the FreeTransform.(Each different action taken requires another description. First we set our target then we set what happens to our target)
  6. We get the Type ID for Horizontal Offset by Pixels
  7. We build an enumeration with a UnitDouble(The offset amount passed through the parameters)
  8. We get the Type ID for Vertical Offset by Pixels
  9. We build an enumeration with a UnitDouble(The offset amount passed through the parameters)
  10. We cache the type ID for the Offset Command
  11. Afterwards we build the description for the Offset Event in the MainEventDetails. (Sinze it needs to be added as an enumeration we reference idOffset twice then the details)
  12. We execute the Transform Event with the mainEventDetails as the description for the transform event. We don’t want any dialogs so we use no dialogs.

If you wanted user input you would set to show dialogs then the user can control the positioning of the active layer.

Final Words

This is meant to serve as a guide for you to create python scripts that run in photoshop. With python you can connect to any other application and gather information.

I wrote a translations script which takes keys from an excel document, iterates over all text layers and upon finding a key replaces and formats the text with the new foreign language value from the excel document

Resource Links:

http://www.adobe.com/devnet/photoshop/scripting.htmlContains API’s for JavaScript and scripting tutorials

http://www.adobe.com/devnet/photoshop/sdk.html – Adobe Photoshop SDK for locating PSContants and other built-in classes

http://www.pcpix.com/photoshop/enum.htm – Action Manager ID’s List

http://www.tonton-pixel.com/blog/wp-content/uploads/DecisionTable.pdf – Decision Table for conflicting String ID’s

http://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python – Switch Case Replacement Discussion

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s