Some small differences are that I had to add a couple of flags to the comtypes object creation (which may have just been a quirk of my machine, see the stackoverflow link for details) and I've added some details about manipulating smart layers at the bottom of the snippet.
Happy coding!
##############################################################################
#
# Eight years later, here is my 2020 version of how to use Comtypes to drive photoshop
#
# Here is a quick code sample showing how to manage different layers and groups
# in a photoshop document using Python.
#
# Pete Hanshaw, 2020
# http://peterhanshawart.blogspot.com.au/
#
##############################################################################
#
# How to make a layerSet (aka, 'group') artLayer (aka 'layer'), how to make them
# active and how to move them.
#
# These examples use the comtypes module. Grab it here:
# http://sourceforge.net/projects/comtypes/
#
##############################################################################
#Create the application reference
import comtypes.client as ct
# https://stackoverflow.com/questions/42794530/error-pointeriunknown-when-trying-to-access-com-object-properties/42823644
psApp = ct.CreateObject('Photoshop.Application', dynamic=True)
psApp.Visible = True
#Create a new document to play with
doc = psApp.Documents.Add(256, 256, 72, 'test_bed', 2, 1, 1)
#When scripting 'groups' are called 'layerSets'.
new_layerSet = doc.LayerSets.Add()
#Once you create a layerSet object reference, you can access it's
#'name' attribute. The same goes for other objects you can normally
#name within Photoshop.
new_layerSet.name = "I'm a layerSet"
#regular, paintable layers are called 'ArtLayers'
new_art_layer = doc.ArtLayers.Add()
new_art_layer.name = "I'm an ArtLayer"
#To add a nested art layer into a LayerSet, use our layerSet object as a reference
nested_art_layer = new_layerSet.ArtLayers.Add()
nested_art_layer.name = "I'm a nested ArtLayer"
#The same goes for adding a nested LayerSet!
nested_layerSet = new_layerSet.LayerSets.Add()
nested_layerSet.name = "I'm a nested LayerSet"
#and so on!
deep_art = nested_layerSet.ArtLayers.Add()
deep_art.name = "Deep man, deep."
#Every time a new object is made, it will become the active layer.
#To make other layers active, you can refer to them either by their name, or
#their index location.
#For example:
#Making an art layer active using the layer's name:
doc.activeLayer = (doc.artLayers["I'm an ArtLayer"])
#Making an art layer active using the layer's index location:
doc.activeLayer = (doc.artLayers[-1]) #This will select the background!
#Selecting a nested art layer is a little more difficult, as you have to
#'drill down' through the hierachy in order to select it.
doc.activeLayer = (doc.layerSets["I'm a layerSet"].
layerSets["I'm a nested LayerSet"].
artLayers["Deep man, deep."])
#Moving a layer in the hierachy is done using the move command.
#The arguments specify which hierachy to move in, and where to put it.
#For example, this will move the first layerSet we made just above the background
#layer.
#Make a new layer set
mobile_layerSet = doc.LayerSets.Add()
mobile_layerSet.name = "move me"
#Move the 'mobile' layerSet to just after the 'background' layer
mobile_layerSet.Move(doc, 2)
# Smart Layer Manipulation Examples adapted from:
# https://www.photopea.com/tuts/edit-smart-objects-with-a-script/
# Create a smart object layer.
# CREATING A SMART LAYER
# select a layer that you want to work with
smart_layer = doc.ArtLayers.Add()
smart_layer.name = "Smarty pants Layer."
doc.activeLayer = smart_layer
# Convert the active layer into a smart object
psApp.executeAction(psApp.stringIDToTypeID("newPlacedLayer"));
# EDITING A SMART LAYER
# Now we can edit the smart object
psApp.executeAction(psApp.stringIDToTypeID("placedLayerEditContents"))
# now, the Smart Object is an active document, we can work with it. Rename the layer...
smartDoc = psApp.activeDocument
super_smart_layer = smartDoc.ArtLayers[0]
super_smart_layer.name = "Amazingly smart layer."
# save the smart object and close it
psApp.activeDocument.save()
psApp.activeDocument.close()
# We are now back in the root object
# QUERYING A SMART LAYER
# If we want to check if a layer is smart, we can query it...
doc = psApp.activeDocument
for layer in doc.ArtLayers:
# 17 is a psSmartObjectLayer - see the Adobe Scripting API 'PsLayerKind' to see what each value means.
if layer.Kind == 17:
print "We found a smart layer named {}".format(layer.name)
Yes! Thank you.
ReplyDeleteQuick quesiton - What if we're not creating the layers, but accessing existing smart layers? Is it as simple as setting the:
psApp.Application.ActiveDocument.activeLayer = layer/.name?
and then:
psApp.executeAction(self.psApp.stringIDToTypeID("placedLayerEditContents"))
Cheers mate!
Figured it out :D
DeleteThanks!
I am doing everything in a class. the self.psdDict has all the different layers of the master psd stored.
for layer in self.psdDict['smartObjects']:
try:
self.psdDoc.activeLayer = layer
self.psApp.executeAction(self.psApp.stringIDToTypeID("placedLayerEditContents"))
print layer.name, '<-'
smartDoc = self.psApp.activeDocument
self.psApp.activeDocument.close()
doc = psApp.activeDocument
except:
print 'passed on something here.'
pass
Thank you so much for your notes, they are very helpful! I have a question about Photoshop visible mode. Will the scripts run faster if you disable it? And how can I optimize script execution as much as possible, can I run multiple instances of Photoshop?
ReplyDeleteThis post provides useful insights into Photoshop tools and scripting techniques, especially for users interested in improving workflow automation and layer management. Understanding Photoshop’s advanced features becomes much easier when combined with practical design knowledge. For designers who also want to enhance their typography and visual presentation skills, learning text effects is equally important. I recently found a detailed guide on
ReplyDeleteHow To Outline Text In Photoshop
that explains step-by-step methods for creating clean and professional text outlines. Combining scripting knowledge with creative text styling can significantly improve overall design efficiency and help both beginners and professionals achieve better results in Photoshop projects.