Photoshop Scripting with JavaScript

I started having a look at java script for photoshop, as there’s a couple of repetitive tasks in there that frustrate me, such as saving non-psds and channel swizzling.

I chose js rather than apple script or visual basic as it can be applied to other platforms, such as web and is a more useful general skill.

To get started, I did the first “hello world” exercise from Adobe’s scripting guide. This was pretty fun to do, and js reminds me of a python/c# hybrid, so its not too unfamiliar. This gave me a new layer with “hello world” written on it.

//set units to inches
var originalUnit = preferences.rulerUnits //remebering this so we can set it back
preferences.rulerUnits = Units.INCHES

//create new doc
var docRef = app.documents.add(2,4) //2,4 = size

//new layer with text
var artLayerRef = docRef.artLayers.add()
artLayerRef.kind = LayerKind.TEXT

//set text value
var textItemRef = artLayerRef.textItem
textItemRef.contents = “Hello World”

//release references – why do I need to do this?
docRef = null
artLayerRef = null
textItemRef = null

//restore units
app.preferences.rulerUnits = originalUnit

Next, I used what I’d learned in that script, along with the methods listed in Adobe’s javascript reference document to write a script that creates three layers, named R, G, and B. This is the start of a channel swizzle script – one that will take the contents of each of these layers, then move them onto one layer as composite channels.  This will allow for far easier creation, editing and saving of channel packed textures – something I use ALL THE TIME for shaders and VFX.

var artLayerRefR = docRef.artLayers.add()
artLayerRefR.kind = LayerKind.NORMAL
//new layer with text
var artLayerRefG = docRef.artLayers.add()
artLayerRefG.kind = LayerKind.NORMAL
//new layer with text
var artLayerRefB = docRef.artLayers.add()
artLayerRefB.kind = LayerKind.NORMAL

artLayerRefR.name = “R”
artLayerRefG.name = “G”
artLayerRefB.name = “B”

Once I’d done this, I tidied it up a bit, the syntax for for loops in js (not as nice as python! ) and making the script a bit more readable.

var layerNames = [“R”, “G”, “B”]
var i
for (i = 0; i < layerNames.length; i++)
{
var artLayerRef = docRef.artLayers.add()
artLayerRef.kind = LayerKind.NORMAL
artLayerRef.name = layerNames[i]
}

I then used the reference doc again to try making a save script. This was broken for ages despite looking correct, until I realised I’d named my file path variable “path”. I really should have known from python that this is a bad idea! (Going to blame the fact that normally PyCharm picks this up for me – I need to get a nice javascript IDE.) It echoes the inbuilt path var and therefor was either returning an error, or saving where photoshop is installed, depending on admin permissions.

function savePNG()
{
//get current doc
currentDoc = app.activeDocument

//set png settings and file path
var pngSettings = new PNGSaveOptions()
pngSettings.compression = 0
pngSettings.interlaced = false

//set file path – careful not to echo anything in built here!
filePath = new File(currentDoc.path + ‘/’ + currentDoc.name.replace(/\.[^\.]+$/, ‘.png’))

//make duplicate to fuck about with
fname = currentDoc.name.split(“.”)[0]
newDoc = currentDoc.duplicate(fname)

//save new doc
newDoc.saveAs(filePath, pngSettings, true, Extension.LOWERCASE)

//close new doc and return focus to original
newDoc.close(SaveOptions.DONOTSAVECHANGES)
app.activeDocument = currentDoc

}

savePNG()

I combined the last two scripts to make the output part of the channel swizzle script, learning how javascript does try catch in the process. Photoshop’s alert function is very nice – allowing me to provide the user an error without having to write up any ui!

function scanLayers()
{
//get all layers
var allLayers = copyDoc.artLayers

//loop through layers
var r
var g
var b

//g = allLayers.getByName(“G”)

try
{
r = allLayers.getByName(“R”)
g = allLayers.getByName(“G”)
b = allLayers.getByName(“B”)
}

catch(e)
{
var errorMsg = “Please make sure your document has layers named R, G and B”
alert(errorMsg)
CloseAndReturn(copyDoc, docRef)
}

saveAsPSD()
CloseAndReturn(copyDoc, docRef)

}

Next step isto get this copying the layer contents into channels.

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