Photoshop natively supports scripting with AppleScript, JavaScript and VBScript. While Python is notably absent from that list, it can still be used to automate nearly anything in Photoshop. This is thanks to the extensive COM interface Photoshop provides.
The methods here are similar to those used in my GDC 2008 Python lecture, about driving 3ds Max via Python. You start by dispatching the Photoshop COM server, using Python as the client:
import win32com.client
psApp = win32com.client.Dispatch("Photoshop.Application")
This connects to your already-opened Photoshop session, or opens one if none are running. The root COM object is then assigned to
psApp, and you're ready to do some cool stuff. Here's a quick example:
psApp.Open(r"D:\temp\blah.psd") # Opens a PSD file
doc = psApp.Application.ActiveDocument # Get active document object
layer = doc.ArtLayers[0] # Get the bottom-most layer
layer.AdjustBrightnessContrast(20,-15) # Bright +20, Contrast -15
doc.Save() # Save the modified PSD
Here's a more complex example. This script recursively scans a folder for PSD files, exporting various textures contained inside. One PSD can have specifically-named Layer Groups, each of which is written to a separate PNG file with a specific suffix. If a Group contains several layers, they're flattened when exported, allowing you to keep all your layered effects intact in the PSD.
In the example below, a group named "diffuse" is exported as "psdname_D.png", the "normal" group as "psdname_N.png", and so on. The
exportType dictionary determines the name/suffix pairs.
# Recursively scans a folder (psdRoot) for Photoshop PSD files.
# For each, exports various 24-bit PNG textures based on layer
# groups found in the PSD.
# Requires the Win32 Extensions:
# http://python.net/crew/mhammond/win32/
import win32com.client
import os
# Change to match your root folder
psdRoot = r'C:\ArtFiles\PSD'
# Map of layer group names and the suffixes to use when exporting
exportTypes = {'diffuse':'_D', 'normal':'_N', 'specular':'_S'}
if (__name__ == '__main__'):
# COM dispatch for Photoshop
psApp = win32com.client.Dispatch('Photoshop.Application')
# Photoshop actually exposes several different COM interfaces,
# including one specifically for classes defining export options.
options = win32com.client.Dispatch('Photoshop.ExportOptionsSaveForWeb')
options.Format = 13 # PNG
options.PNG8 = False # Sets it to PNG-24 bit
# Get all PSDs under root dir
psdFiles = []
for root, dir, files in os.walk(psdRoot):
for thisFile in files:
if (thisFile.lower().endswith('.psd')):
fullFilename = os.path.join(root, thisFile)
psdFiles.append(fullFilename)
# Loop through PSDs we found
for psdFile in psdFiles:
doc = psApp.Open(psdFile)
layerSets = doc.LayerSets
if (len(layerSets) > 0):
# First hide all root-level layers
for layer in doc.Layers:
layer.Visible = False
# ... and layerSets
for layerSet in layerSets:
layerSet.Visible = False
# Loop through each LayerSet (aka Group)
for layerSet in layerSets:
lsName = layerSet.Name.lower()
if (lsName in exportTypes):
layerSet.Visible = True # make visible again
# Make our export filename
pngFile = os.path.splitext(psdFile)[0] + exportTypes[lsName] + '.png'
# If PNG exists but older than PSD, delete it.
if (os.path.exists(pngFile)):
psdTime = os.stat(psdFile)[8]
pngTime = os.stat(pngFile)[8]
if (psdTime > pngTime):
os.remove(pngFile)
# Export PNG for this layer Group
if (not os.path.exists(pngFile)):
doc = psApp.Open(psdFile)
doc.Export(ExportIn=pngFile, ExportAs=2, Options=options)
print 'exporting:', pngFile
else:
print 'skipping newer file:', psdFile
# Make LayerSet invisible again
layerSet.Visible = False
# Close PSD without saving
doc.Close(2)
It only exports when the PNG is missing or older than the PSD. This makes it good for running a batch texture export on your project's entire texture tree.
Here is a ZIP containing the above script and a sample PSD file to try it on:
exportTextureLayers.zip (143 KB)
I imagine you can do all of the above with the native Photoshop scripting. I just think it's cool being able to use Python instead of rooting through a language I'm less familiar with. Dinosaurs were roaming the earth the last time I tried anything in VB.
If you dig this, I'd recommend reading the
Photoshop CS5 Scripting Guide and
Photoshop CS5 VBScript Reference found in the
Adobe Photoshop Developer Center. While the above wasn't VBScript, the COM interface we used is nearly identical.