Recently I’ve seen adobe’s intro to scripting guide.
Getting Started
To start off with, you need Adobe’s Photoshop and also Adobe’s ExtendScript Tookit. The Toolkit is your IDE, and while not the greatest IDE, it has a quick launch to PS, that I have yet to recreate in my favorite IDE’s. It also has a decent object viewer for classes, and functions. As a plus, It has a debugger and a primitive profiling system. I’ll go ahead and warn you, the intellisense is mediocre at best, but works some of the time. After you have these two programs you are ready to roll. (p.s. make sure that you have the dropdown box above your code set on Adobe Photoshop” and not “ExtendScript Toolkit”)
The Basics
The way the photoshop object model is designed, is quite nice, IMO. Everything is based under “App” and for most of our purposes “Document.” Things cascade down from here and most of it and falls under logical classes. Real quick, let’s create a document and add a layer named “Hello World.” Something simple to get the blood flowing in the fingers.
1 2 3 4 5 | doc = app.documents.add(500,500); layer = doc.artLayers.add(); layer.name = "Hello World"; |
Pretty simple so far. We’re creating a new document, adding a layer, and changing the name. Another pretty useful line of code is:
1 | docRef = app.activeDocument; |
This will give us the a reference to whatever document is currently open. If there are no documents open, the program will throw an error. You can fix this by:
1 2 3 4 5 6 7 | if(app.documents.length == 0) {alert("No documents are open, please open at least one document.");} else {docRef = app.activeDocument;} |
The alert method is one of your best friends. This will quickly pop up any information that you need to know. Some people will say, use breakpoints and the dataviewer, but I think that it takes longer to get the same information.
If we wanted to loop through all the layers and alert the user of the names we would use:
1 2 3 4 5 6 7 8 9 | docRef = app.activeDocument; for(var i = 0; i < docRef.layers.length; i++) { alert(docRef.layers[i].name); } |
We could also highlight each layer as we loop through it.
1 2 | for(var i = 0; i < docRef.layers.length; i++) {docRef.activeLayer = docRef.layers[i];} |
Scripts to Save You A Headache
this.
Running A Script from a Hotkey
This is something which I found really gives users some power quick. Running scripts via “File”->”Scripts” ->”Browse For Scripts” is annoying, time consuming, and not useful for artists. The solution is to create an action that is assigned to a hotkey, and then record running the script via “File”->”Scripts” ->”Browse For Scripts”. Once you’ve done this you can run that script everytime you press the hot key. Now we have the power of running scripts from one button. This not only saves time, but makes using your scripts feasible.
F2 Rename
For those of you who are Windows users and Photoshop users, one thing that really peaves me is double-clicking a layer to rename it. Not only is this a pain, a lot of time I’ll miss the text on the layer is my double click will pull up layer styles. This is basic windows functionality. I have a hard time not being able to do this. With a few lines of code, you can make it happen.
1 2 3 4 5 6 7 8 9 | var docRef = app.activeDocument; var current = docRef.activeLayer; var layerTitle = prompt("Enter Layer Name", current.name); if(layerTitle != null) {current.name = layerTitle;} |
What we are doing here is: getting the active document, getting the active layer, using a built in “Prompt” to return a string, and assign it to the current layer. I put the assigning of the name inside a if statement because if a user exits or cancels the dialog box, “Prompt” returns null. All in all, this doesn’t really save you any time, you still have to click the layer then hit F2, but if you know your Photoshop commands, you know that (alt and [) and (alt and ]) move your selected layer up and down. Combined with this script, you can quickly name multiple layers.
Toggle Visibility
Another annoying aspect of Photoshop is the visibility of a layer. If I want to turn the layer on or off, I have to click on an itty bitty tiny “eye” button. I find this to be a pain, especially when I’m having to turn off many layers and zoom in and out of an atlas to figure out which layer is which. I created a shortcut to this. A single key which toggles the visibility of your currently selected layer. Combined with ctrl left-clicking in the document you can quickly change the visibility of layers without having to explicitly select a layer in the “layers” window or click the “eye” button.
1 2 3 4 5 6 7 8 | var docRef = app.activeDocument; if(docRef.activeLayer.visible) {docRef.activeLayer.visible = false;} else {docRef.activeLayer.visible = true;} |
Delete All Open Windows
If you’ve ever programmed in Photoshop, you will eventually end up writing a script that creates a new document every time you run the script. After testing, debugging, and trying to get the script to work, you will see that photoshop has 40 documents open. You need to delete them all. When you click close, the window will ask you, “Do you want to save?” Hell no, you just want it to go away…Now you have to do this 40 times, UNFORGIVABLE! This definitely gives me a headache, Javascript to the rescue. (Disclaimer: I take no responsibility for deleting your files. Use this script at your own risk)
1 2 3 | while (app.documents.length > 0) {activeDocument.close(SaveOptions.DONOTSAVECHANGES);} |
Traverse Layers
While I like Photoshop’s API a lot, there isn’t a great way to “walk” through all the layers and groups. The next script accomplishes that. Right now, it just highlights the active layer, but the code could easily be modified to do anything to that layer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | var docRef = app.activeDocument; function recurseLayers(currLayers) { for(var i = 0; i < currLayers.layers.length; i++) { docRef.activeLayer = currLayers.layers[i]; if(isLayerSet(currLayers.layers[i])) {recurseLayers(currLayers.layers[i]);} } } function isLayerSet(layer) { try{ if(layer.layers.length > 0) return true;} catch(err) {return false;} } recurseLayers(docRef) |
As you will notice for large documents with many layers, this is a very sloooooooooooooooooooooooooooooooooooow process. In the next post, we’ll explore speedups in Photoshop.
Wrap-It-Up
While the scripts I posted here are mostly elementary, I do strongly believe that these types of scripts can save a lot of headache and time. My object was to introduce you to how Photoshop works and give you a few examples of how these practices can be put into action. In my next blog post, I will introduce you to some more advanced scripting including GUI creation and Speedups via the ActionManager. Let me know if you have any questions/thoughts!