Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better macOS scripting documentation #24

Merged
merged 1 commit into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions mac_scripting/ActiveLayer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Set the active layer to the last art layer of the active document, or the
# first if the last is already active.

from appscript import app, k
ps = app(id="com.adobe.Photoshop", terms="sdef")

# We could also use "ps.count(None, k.documents)" here, if
# we expect many documents to be open and speed was of concern.
if len(ps.documents()) < 1:
docRef = ps.make(new=k.document)
else:
docRef = ps.current_document

if len(docRef.layers()) < 2:
docRef.make(new=k.art_layer)

if docRef.current_layer() != docRef.layers[-1]():
docRef.current_layer.set(docRef.layers[-1])
else:
docRef.current_layer.set(docRef.layers[1])
32 changes: 32 additions & 0 deletions mac_scripting/ApplyCrystallizeFilterAction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This script demonstrates how you can use the action manager
# to execute the Crystallize filter.

from os.path import abspath
from appscript import app, mactypes

# Start up Photoshop application
ps = app(id="com.adobe.Photoshop", terms="sdef")

# This must be an absolute path.
fileName = abspath("../PS_Samples_Files/Layer Comps.psd")
ps.open(fileName)
docRef = ps.current_document()

nLayerSets = docRef.layer_sets
nArtLayers = docRef.layer_sets[-1].art_layers

# get the last layer in LayerSets
docRef.current_layer.set(docRef.layer_sets[-1].art_layers[-1])

# custom actions like this must be done as Javascript, unfortunately
def applyCrystallize(cellSize):
script = """
cellSizeID = charIDToTypeID("ClSz");
eventCrystallizeID = charIDToTypeID("Crst");
filterDescriptor = new ActionDescriptor();
filterDescriptor.putInteger(cellSizeID, arguments[0]);
executeAction(eventCrystallizeID, filterDescriptor);
"""
ps.do_javascript(script, with_arguments=[cellSize])

applyCrystallize(25)
61 changes: 61 additions & 0 deletions mac_scripting/ApplyFilters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# This sample script shows how to apply 3 different filters to
# selections in the open document.

from os.path import abspath
from appscript import app, k, mactypes

# Start up Photoshop application
ps = app(id="com.adobe.Photoshop", terms="sdef")

# We don't want any Photoshop dialogs displayed during automated execution
ps.display_dialogs.set(k.never)

start_rulers = ps.settings.ruler_units.get()
ps.settings.ruler_units.set(k.pixel_units)

# This needs to be an absolute path
fileName = abspath("../PS_Samples_Files/Layer Comps.psd")
ps.open(fileName)
docRef = ps.current_document()

docRef.current_layer.set(docRef.layer_sets[-1].art_layers[-1])
active_layer = docRef.current_layer()

sel_area = ((0, 212), (300, 212), (300, 300), (0, 300))
ps.select(
docRef, region=sel_area, combination_type=k.replaced, feather_amount=20, antialiasing=True
)

active_layer.filter(
using=k.add_noise,
with_options={k.amount: 15, k.distribution: k.Gaussian, k.monochromatic: False}
)

ps.background_color.set({k.class_: k.HSB_color, k.hue: 0, k.saturation: 0, k.brightness: 100})


sel_area2 = ((120, 20), (210, 20), (210, 110), (120, 110))
ps.select(
docRef, region=sel_area2, combination_type=k.replaced, feather_amount=25, antialiasing=False
)

active_layer.filter(
using=k.diffuse_glow,
with_options={k.graininess: 9, k.glow_amount: 12, k.clear_amount: 15}
)

active_layer.filter(
using=k.glass_filter,
with_options={
k.distortion: 7,
k.smoothness: 3,
k.scaling: 7,
k.invert_texture: False,
k.texture_kind: k.tiny_lens
}
)

docRef.deselect()

# Set ruler units back the way we found it
ps.settings.ruler_units.set(start_rulers)
12 changes: 12 additions & 0 deletions mac_scripting/CompareColors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This script compares the app.foregroundColor
# to the app.backgroundColor.

from appscript import app

# Start up Photoshop application
ps = app(id="com.adobe.Photoshop", terms="sdef")

if ps.foreground_color() == ps.background_color():
print("They're Equal")
else:
print("NOT Equal")
11 changes: 11 additions & 0 deletions mac_scripting/ConvertColor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Convert the foreground color to RGB.

from appscript import app, k

ps = app(id="com.adobe.Photoshop", terms="sdef")

fgColor = ps.foreground_color

# Unlike JavaScript and COM, we have to use a function to convert colors
fgRGBColor = fgColor.convert_color(to=k.RGB)
print(f"Red: {fgRGBColor[k.red]} Green: {fgRGBColor[k.green]} Blue: {fgRGBColor[k.blue]}")
57 changes: 57 additions & 0 deletions mac_scripting/CopyAndPaste.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# This example makes a creates a selection in the activeDocument, copies the selection,
# to the clipboard, creates a new document of the same dimensions
# and pastes the contents of the clipboard into it.
# It ensures that rulerUnits are set before creating the new document.
# It checks the kind of the layer before making the selection to be
# sure not to copy a text layer.

from appscript import app, k

ps = app(id="com.adobe.Photoshop", terms="sdef")

strtRulerUnits = ps.settings.ruler_units()
ps.settings.ruler_units.set(k.inch_units)

srcDoc = ps.make(
new=k.document,
with_properties={k.width: 7, k.height: 5, k.resolution: 72, k.mode: k.RGB, k.initial_fill: k.white}
)

# Make sure the active layer is not a text layer, which cannot be copied to the clipboard
if srcDoc.current_layer.kind() != k.text_layer:
# Select the left half of the document. Selections are always expressed
# in pixels regardless of the current ruler unit type, so we're computing
# the selection corner points based on the inch unit width and height
# of the document
x2 = (srcDoc.width() * srcDoc.height()) / 2
y2 = srcDoc.height() * srcDoc.resolution()

sel_area = ((0, 0), (x2, 0), (x2, y2), (0, y2))
srcDoc.select(
region=sel_area,
combination_type=k.replaced,
feather_amount=0,
antialiasing=False
)

# AppleScript implementation of this function
# can only copy and paste from the current_document
# and only if it is the frontmost application
ps.activate()
ps.copy()

# The new doc is created
# need to change ruler units to pixels because x2 and y2 are pixel units.
ps.settings.ruler_units = k.pixel_units
pasteDoc = ps.make(
new=k.document,
with_properties={
k.width: x2, k.height: y2, k.resolution: srcDoc.resolution(), k.name: "Paste Target"
}
)
ps.paste()
else:
print("You cannot copy from a text layer")


ps.settings.ruler_units.set(strtRulerUnits)
25 changes: 25 additions & 0 deletions mac_scripting/CopyAndRotate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Crop and rotate the active document.

from os.path import abspath
from appscript import app, k, mactypes

# Start up Photoshop application
# Or get Reference to already running Photoshop application instance

ps = app(id="com.adobe.Photoshop", terms="sdef")

# This must be an absolute path
fileName = abspath("../PS_Samples_Files/Layer Comps.psd")
ps.open(fileName)
srcDoc = ps.current_document()

strtRulerUnits = ps.settings.ruler_units()
ps.settings.ruler_units.set(k.pixel_units)

# crop a 10 pixel border from the image
bounds = [10, 10, srcDoc.width() - 10, srcDoc.height() - 10]
srcDoc.rotate_canvas(angle=45)
srcDoc.crop(bounds=bounds)

# set ruler back to where it was
ps.settings.ruler_units.set(strtRulerUnits)
31 changes: 31 additions & 0 deletions mac_scripting/EmbossAction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This script demonstrates how you can use the action manager
# to execute the Emboss filter.
# Inorder to find all the IDs, see https://helpx.adobe.com/photoshop/kb/downloadable-plugins-and-content.html#ScriptingListenerplugin
# This blog here exlains what a script listener is http:https://blogs.adobe.com/crawlspace/2006/05/installing_and_1.html

from os.path import abspath
from appscript import app, k, mactypes

# Start up Photoshop application
ps = app(id="com.adobe.Photoshop", terms="sdef")

fileName = abspath("../PS_Samples_Files/Layer Comps.psd")
ps.open(fileName)
docRef = ps.current_document()

docRef.current_layer.set(docRef.layer_sets[-1].art_layers[-1])

# Unfortunately, since there is no way to send raw Photoshop actions
# via AppleScript, we must use JavaScript for this
# Note: ScriptListener generated code looks awful, but you can tidy it up quite a lot ;)
def emboss(angle, height, amount):
ps.do_javascript("""
var desc = new ActionDescriptor()
var c = charIDToTypeID
desc.putInteger(c("Angl"), arguments[0])
desc.putInteger(c("Hght"), arguments[1])
desc.putInteger(c("Amnt"), arguments[2])
executeAction(c("Embs"), desc)
""", with_arguments=[angle, height, amount])

emboss(120, 10, 100)
29 changes: 29 additions & 0 deletions mac_scripting/FillSelection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Fill the current selection with an RGB color.

from appscript import app, k

# Start up Photoshop application
ps = app(id="com.adobe.Photoshop", terms="sdef")

strtRulerUnits = ps.settings.ruler_units()

if len(ps.documents()) < 1:
ps.settings.ruler_units.set(k.pixel_units)
docRef = ps.make(
new=k.document,
with_properties={
k.width: 320, k.height: 240, k.resolution: 72, k.mode: k.RGB, k.initial_fill: k.white
}
)
docRef.make(new=k.art_layer)
ps.settings.ruler_units.set(strtRulerUnits)

if ps.current_document.current_layer.background_layer() == False:
selRef = ps.current_document.selection
# Note the "_" here in both RGB_color_ and class_
fillcolor = {k.class_: k.RGB_color_, k.red: 255, k.green: 0, k.blue: 0}
selRef.fill(
with_contents=fillcolor, blend_mode=k.normal, opacity=25, preserving_transparency=False
)
else:
print("Can't perform operation on background layer")
12 changes: 12 additions & 0 deletions mac_scripting/HelloWorld.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Hello World!

from appscript import app, k

ps = app(id="com.adobe.Photoshop", terms="sdef")
doc = ps.make(new=k.document, with_properties={k.width: 320, k.height: 240})
layer_ref = doc.make(new=k.art_layer, with_properties={k.kind: k.text_layer})


text_item = layer_ref.text_object
text_item.contents.set("HELLO WORLD")
text_item.position.set([120, 120])
24 changes: 24 additions & 0 deletions mac_scripting/LayerKind.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This script demonstrates how to create a new layer and set its kind.

from appscript import app, k

# Start up Photoshop application
ps = app(id="com.adobe.Photoshop", terms="sdef")

strtRulerUnits = ps.settings.ruler_units()

if len(ps.documents()) < 1:
ps.settings.ruler_units.set(k.pixel_units)
docRef = ps.make(
new=k.document,
with_properties={
k.width: 320, k.height: 240, k.resolution: 72, k.mode: k.RGB, k.initial_fill: k.white
}
)
else:
docRef = ps.current_document()

layerRef = docRef.make(new=k.art_layer)
layerRef.kind.set(k.text_layer)
# Set the ruler back to where it was
ps.settings.ruler_units.set(strtRulerUnits)
24 changes: 24 additions & 0 deletions mac_scripting/LinkLayer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This scripts demonstrates how to link two layers.

from appscript import app, k

# Start up Photoshop application
ps = app(id="com.adobe.Photoshop", terms="sdef")

strtRulerUnits = ps.settings.ruler_units()

if len(ps.documents()) < 1:
ps.settings.ruler_units.set(k.pixel_units)
docRef = ps.make(new=k.document, with_properties={
k.width: 320, k.height: 240, k.resolution: 72, k.mode: k.RGB, k.initial_fill: k.white
}
)
else:
docRef = ps.current_document()

layerRef = docRef.make(new=k.art_layer)
layerRef2 = docRef.make(new=k.art_layer)
layerRef.link(with_=layerRef2)

# Set the ruler back to where it was
ps.settings.ruler_units.set(strtRulerUnits)
31 changes: 31 additions & 0 deletions mac_scripting/LoadSelection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This script will demonstrate how to load a selection from a saved alpha channel.

from appscript import app, k

ps = app(id="com.adobe.Photoshop", terms="sdef")

strtRulerUnits = ps.settings.ruler_units()
ps.settings.ruler_units.set(k.pixel_units)

docRef = ps.make(new=k.document, with_properties={k.width: 320, k.height: 240})

# To save querying Photoshop for every width/height
# reference, it's faster to just store the values here
width, height = docRef.width(), docRef.height()

# Save a rectangular selection area offset by 50 pixels from the image border into an alpha channel
offset = 50
selBounds1 = ((offset, offset), (width - offset, offset), (width - offset, height - offset), (offset, height - offset))
docRef.select(region=selBounds1)
selAlpha = docRef.make(new=k.channel)
docRef.selection.store(into=selAlpha)

# Now create a second wider but less tall selection
selBounds2 = ((0, 75), (width, 75), (width, 150), (0, 150))
docRef.select(region=selBounds2)

# Load the selection from the just saved alpha channel, combining it with the active selection
docRef.selection.load(from_=selAlpha, combination_type=k.extended, inverting=False)

# Set ruler back to where it was
ps.settings.ruler_units.set(strtRulerUnits)
Loading