Creating a new photoshop doc with Python

In the spirit of saving time (and also because I think its cool) I wrote a quick little script to create a new Photoshop document, set up with groups and layers. It ties quite nicely in with Texture monkey, as it uses the same group names etc when it creates the doc, and it just saves a lot of clicking.

When you run the script, which only takes a couple of seconds, you end up with a neat little document ready to edit:


I added a part at the end of the script to make sure the diffuse
layer was active. It's a little touch, but makes it nice to know the
script leaves off somewhere useful rather than some random layer.


The script is pretty straightforward, but has a couple of interesting little bits, like how it moves groups. I had to trawl around for a while to get that one working. I'm also becoming a big fan of minimizing console feedback. As long as it's all working I don't think it should spit too many "I'm doing this!" messages out at you. It's annoying. 

##############################################################################
#
# ps_newdoc.py
#
# Photoshop doc setup
# (C) Pete Hanshaw, 2012
# http://peterhanshawart.blogspot.com.au/
#
##############################################################################
#
# Creates a new PSD document and sets up placeholder groups and layers 
# ready for texture work.
#
# Creates:
# -'n' group for normal map
# -'s' group for specular map
# -'d' group for diffuse map
#
#
# Requires the Win32 Extensions:
# http://python.net/crew/mhammond/win32/
#
##############################################################################

#Import required modules
from win32com.client.dynamic import Dispatch
from sys import exit
import pythoncom

#Set up the document. More groups can be added easily by creating more dict keys
group_names = {}
group_names['d'] = 'dif_base'
group_names['s'] = 'spec_base'
group_names['n'] = 'nrm_base'

#Begin the script            
if (__name__ == '__main__'):
    #COM dispatch for Photoshop
    try:
        psApp = Dispatch('Photoshop.Application')

    except:
        os.system("color 0c")
        print "The dispatch to Photoshop did not work"
        os.system("PAUSE")
        exit(0)

    #Define the fill colors
    #Normal base
    nrm_SolidColor = Dispatch('Photoshop.SolidColor')
    nrm_SolidColor.rgb.red = 128
    nrm_SolidColor.rgb.green = 128
    nrm_SolidColor.rgb.blue = 255

    #Define the fill colors
    #Spec base
    spec_SolidColor = Dispatch('Photoshop.SolidColor')
    spec_SolidColor.rgb.red = 0
    spec_SolidColor.rgb.green = 0
    spec_SolidColor.rgb.blue = 0
    
    #Define the fill colors
    #Diffuse base
    dif_SolidColor = Dispatch('Photoshop.SolidColor')
    dif_SolidColor.rgb.red = 128
    dif_SolidColor.rgb.green = 128
    dif_SolidColor.rgb.blue = 128
    

    #w, h, res, name, mode, initial-fill, asp-ratio, Bits-P/Ch, ColProfile
    new_doc = psApp.Documents.Add(1024, 1024, 72, "new_source_texture", 2, 1, 1)

    print "Setting up a", new_doc.name
    
    for group, layer in group_names.items():
        new_layerSet = new_doc.LayerSets.Add()
        new_layerSet.name = group

        if group == 'n':
            new_art_layer = new_layerSet.ArtLayers.Add()
            new_art_layer.name = layer

            #Fill the layer with appropriate color
            psApp.activeDocument.selection.selectAll
            psApp.activeDocument.selection.Fill(nrm_SolidColor)
            new_layerSet.Visible = False

        elif group == 's':
            new_art_layer = new_layerSet.ArtLayers.Add()
            new_art_layer.name = layer

            #Fill the layer with appropriate color
            psApp.activeDocument.selection.selectAll
            psApp.activeDocument.selection.Fill(spec_SolidColor)
            new_layerSet.Visible = False

        elif group == 'd':
            new_art_layer = new_layerSet.ArtLayers.Add()
            new_art_layer.name = layer
            #Fill the layer with appropriate color
            psApp.activeDocument.selection.selectAll
            psApp.activeDocument.selection.Fill(dif_SolidColor)

        else:
            new_art_layer = new_layerSet.ArtLayers.Add()
            new_art_layer.name = layer
   
            #Fill the layer with appropriate color
            psApp.activeDocument.selection.selectAll
            psApp.activeDocument.selection.Fill(dif_SolidColor)

    #Reorder the photoshop layers so that it reads from top down:
    #normal, spec, diffuse
    dGroup = psApp.activeDocument.layerSets['d']

    #See Adobe's photoshop_cs4_vbscript_ref.pdf to make sense of this-
    dGroup.Move(new_doc, 2)

    #Deselect the fill area
    psApp.activeDocument.selection.deselect

    #Set the active layer to the diffuse
    psApp.activeDocument.activeLayer = (psApp.activeDocument.layerSets['d'].
                                        artLayers['dif_base'])
    
    print "All done!"
    exit(1)