Scripting Photoshop, Part 2 — A Practical Example

Photoshop script (JSX)

In Part 1 of this two-part tutorial about scripting Photoshop, we covered some of the basics of using scripts, as well as the many resources available. In this second part, we'll create a practical, real-world script from scratch.

As mentioned in the Introduction to Scripting Photoshop, toggling the visibility of a layer (on and off) is an example of conditional logic, something for which scripting is ideally suited. So, let's see how you would write such a script from scratch.

For this project we'll use JavaScript because it's the only cross-platform scripting language supported by the Creative Suite; however, you could just as easily write a similar script using AppleScript for Mac, or VBScript for PC.

Tip: Although you can write Photoshop scripts using JavaScript, AppleScript, or VisualBasic Script, JavaScript has two distinct advantages: it's platform independent (i.e., it works on both Mac and PC), and many Web designers are already familiar with it.
Tip: So what's the difference between a ".js" and a ".jsx" file? Fundamentally, nothing; they're both JavaScript files/scripts. However, if you double-click on a ".js" file in Apple's Finder or Windows' Explorer, it'll likely open in your browser (and display an error dialog). But if you have any of the CS3 applications installed, ".jsx" files will be associated with ExtendScript Toolkit. (For more information about ExtendScript Toolkit, see Chapter 9 of the JavaScript Reference Guide.)

JavaScript Jargon

Before we begin, an overview of some common terminology is required. Everything in Photoshop is represented as an "object" (e.g., ArtLayer, Channel), and each object is part of an array called a "collection" (e.g., ArtLayers, Channels). The hierarchy of these objects and collections comprises the Document Object Model (DOM).

Objects have associated "properties", which describe their characteristics (e.g., name, opacity); "methods", which define the actions you can take against them (e.g., copy(), resize()); and "events", which describe the actions that happen in response to other actions (e.g., onClick(), onChange()).

Other terms worth defining include variables and arrays. Variables are used for temporary storage, and can represent objects or data, such as strings (text), numbers, Booleans (true/false), and arrays. Arrays are variables that contain multiple values of the same type. For example, an array of integers could contain the values 1, 3, 7, 15, and 23 (all within the same variable).

Also note that JavaScript is case sensitive, meaning that words with different case are considered different, even if the they're spelled the same (e.g., "JavaScript" vs. "Javascript").

To learn more about scripting basics, refer to Chapter 2 of the Photoshop Scripting Guide.

Adobe Photoshop CS3: Javascript Scripting Reference Tip: The Scripting and Reference Guides are located in your "Adobe Photoshop CS3" install folder, in the "Scripting Guide" subfolder. The documents are also available in electronic format (PDF) from Adobe's Photoshop Development Center .

You can even purchase a printed book of the Photoshop Scripting Guide from Amazon.com  (although it's currently only available for Photoshop CS2).

Scripting From Scratch

In order to write scripts, you'll need an editing environment. Any script/text editor will work — even Mac TextEdit or Windows NotePad — but I recommend Adobe's ExtendScript Toolkit (ESTK). While ESTK may not be as sophisticated or feature-rich as some other editors, it's ability to target specific Creative Suite applications for playback and debugging makes it very convenient.

We'll begin by creating a variable to store our reference document. The simplest way to target the active document is to use the activeDocument property of the application object (JavaScript Scripting Reference, page 45), so we'll assign it to a variable as follows:

var docRef = activeDocument;

Similarly, we'll create a reference variable for the active layer by using the activeLayer property of the document object (JavaScript Scripting Reference, page 89):

var layerRef = docRef.activeLayer;

From now on, we can reference the active document and active layer as simply docRef and layerRef, respectively.

To toggle the visibility of the active layer, we'll need to look up the corresponding layer property for the artLayer object. In this case it's the visible property (JavaScript Scripting Reference, page 54). Therefore, the next line would look like this:

layerRef.visible = !layerRef.visible;

The exclamation mark above is JavaScript notation for "not". So, roughly translated, the above line means: make the visibility of the active layer equal to whatever visibility state it currently is not — or more simply, make the visibility the opposite of its current state.

At this point you should be able to run the script. First choose "Adobe Photoshop CS3" from the Target Application drop-down in the top left, and then press the Play button (Play button) on the ESTK toolbar. Alternatively, you can run the script via the File » Scripts menu in Photoshop (although you may need to restart Photoshop for the script to appear).

Note that you'll need at least one document open — one with a least one non-Background layer — otherwise you'll get a script error (which we'll fix shortly). Run the script a few times, and on different layers, to ensure that it's working correctly.

Error-Handling

All right, now it's time to add in some error-handling — code that will handle improper uses of the script. First we'll address the situation where no document is present using a simple conditional if statement (Scripting Guide, page 40). The general syntax for an if statement is:

if (condition) {action1} else {action2};

Photoshop documents are stored in the documents collection as an array, and in JavaScript, the number of elements within the array is determined by its length property (JavaScript Scripting Reference, page 102). So, to test for an open document, the if statement would look like this:

if (documents.length == 0) {action1} else {action2};

Note the double equal sign, which is an equality operator (versus a single equal sign, which is used to assign values).

Give yourself bonus points if you recognized that the above statement could also have been written as if (!documents.length).

For action1, we'll notify the user that there are no documents open by using an alert (Core JavaScript Classes: Global Elements), which is just a simple message dialog with an OK button on it. In addition, we'll put the rest of our script into action2:

Run the script with and without a (multilayer) document open in Photoshop to test the results.

Finally, since the Background layer of a flattened document cannot be hidden, we need to write one more if statement — nested inside the existing else statement — that tests for documents containing only a single Background layer. We'll do this by using the isBackground property of the artLayer object (JavaScript Scripting Reference, page 53).

if (docRef.layers.length == 1 && layerRef.isBackgroundLayer == true)

So this time we're testing the layers collection for a single layer and checking to see if it's a Background layer. The double-ampersand is an AND operator, which means that both conditions have to be met; otherwise, the script proceeds to the else statement.

The Final Results

That's it; you're done! Save your script into the Presets/Scripts folder. Here's what the final script should look like:

While scripting can take a long time to master, the flexibility it affords you makes it well worth the time invested — especially if your workflow involves a lot of repetitive tasks that can't be automated using traditional actions and batch processing.

Tip: For greater convenience, use Edit » Keyboard Shortcuts (Cmd/Ctrl+Opt/Alt+Shift+K) to assign shortcuts to your scripts. Also note that scripts may be recorded as part of an action, or even called from another script.

Additional Resources

Below are several online resources where you can learn more about scripting for Photoshop:

 

If you enjoyed this tutorial, please consider supporting this site. As always, I welcome your feedback and suggestions. Also, if you have a scripting project that you'd like to discuss with me, please contact me with the details and I'd be happy to provide you with a free estimate.