[Tutorial] Advanced automation and scripting with AppleScript

Discuss Pixelmator Pro tutorials and share useful resources.
User avatar

2020-09-28 08:45:14

by James Dempsey 2020-09-26 12:34:53 Thank you for adding AppleScript support in Pixelmator Pro!

Is there a way to turn fill off completely for a shape layer? I have a shape that only needs a stroke, not a fill.

I have been able to set 'fill opacity' to 0, but would really like to do the equivalent of unchecking the Fill checkbox in the interface.

Thank you!
Because of the way we've approached layer styles and color adjustments in our AppleScript support, it isn't possible to do this. Just out of interest, is this to make exported SVGs cleaner or for some other reason?
by Ducky This should be easy, but how would you paste at a specific position?
You should set the position of the layer after pasting it — that's probably the most basic way to achieve this. If you find yourself doing this often and would like your scripts to look cleaner, you could also create a handler for it. Something like this should work (you'd put this at the end of your script after all your application tells, etc.):
using terms from application "Pixelmator Pro"
	on pasteAtPosition(myLayer, myPosition)
		duplicate myLayer
		set position of myLayer to myPosition
	end pasteAtPosition
end using terms from
Then, in your application tells, whenever you want to copy and paste at a specific position, here's how you would call the handler:
my pasteAtPosition(layer 3, {0, 0})
User avatar

2020-09-28 10:47:28

by fly 2020-09-25 16:50:54 @Andrius Glory Glory.. It Works! i wish you and the Pixelmator team all get many times in hours of joy, the thousand hours you saved me. Can't recommend Pixelmator enough, since the very first versions it has been special and unique, but with this kind of support really nothing compares. Cheers!
Yay, I'm glad we were able to find a fix for this in the end!
User avatar

2020-09-28 19:38:57

I am new to Apple Script, but I am curious and interested to learn. I red some of the examples and then I wanted to try something myself but I am always told that document 1 could not be loaded.

I would like to use an Automator finder extension to "resize canvas" of a selected picture in the Finder. What I don't know is, how I tell Pixelmator Pro to use the selected file. I think this error with the „document 1“ will be resolved once Pixelmator gets a file. Any help is appreciated.

Thx in advance
User avatar

2020-09-29 07:54:06

Hey Alexander, first of all, welcome to the community! Second of all, would you be able to share the script you currently have and, if you're combining it with an Automator workflow, a screenshot of the workflow as well?
User avatar

2020-09-29 13:56:54

@Andrius: Well I tried different things. It was a very basic script. Like so
on run {input, parameters}
	
	tell application "Pixelmator Pro"
		tell the front document to resize canvas width 1280 height 720 anchor position middle center
	end tell
	
	return input
end run
But I also tried to understand what the "input" and "parameters" are and as I use the "selected finder objects"-add-on in the Automator as well I red how this works with Apple Script. And as I understood the object selected is forwarded to the next action, which is the Apple Script then. So I thought it will somehow be behind the input variable. And if I try to log/display out the input variable or its name I can see that the correct file is in it somehow. ^^

Image

I tried to use some variable and make document become what the input is. But this did not work out well, and always resulted in errors.

Thanks for your help, Andrius.
User avatar

2020-09-29 15:57:29

No problem, whenever you're scripting stuff with AppleScript and you're not sure about what value a certain variable has, you can use the return keyword to return those values at that point in the script. So, for example, I've passed three images into a Get Specified Finder Items action, and using this:
on run {input, parameters}
	return input
end run
I can find out that I'm getting this:
{alias "Macintosh HD:Users:andriusgailiunas:Desktop:Process This:IMG_1512.tiff", alias "Macintosh HD:Users:andriusgailiunas:Desktop:Process This:IMG_1513.tiff", alias "Macintosh HD:Users:andriusgailiunas:Desktop:Process This:IMG_2060.tiff"}
And that is a list of aliases. An alias is a reference to a file, so you can easily open that in Pixelmator Pro, you just have to know how to tell it to open a particular item in a list. As input is a list of aliases, the basic format would be:
tell application "Pixelmator Pro" to open item 1 of input
To open each file in sequence, just like in some of the example scripts above, you can loop over the them. Here's one way to do that (I've added some comments to try and make the script easier to understand):
on run {input, parameters}
	tell application "Pixelmator Pro"
		-- Starts a repeat loop that will loop from 1 to the number of items in the input list, at the end of each repeat loop, it will increment the 'a' variable by 1 
		repeat with a from 1 to number of input
			-- Open item a (the first time, it will be item 1, i.e. the first document in the list, the second time it will be item 2, etc.) and assign the document to the currentImage variable
			set currentImage to open item a of input
			-- Tell the currentImage to resize the canvas to 1280 by 720
			tell currentImage to resize canvas width 1280 height 720 anchor position middle center
			-- Save the currentImage
			save currentImage
			close without saving
		end repeat
	end tell
	return input
end run
At the end, return input returns those same aliases (i.e. files) and passes it on to the next action in the workflow.

There are a few things to note about all that: there's a bug with the resize canvas command, right now it ignores the height property, so your images will always end up square. We've fixed it internally and if you'd like a version with a fix, email me at andriusg@pixelmator.com and I'll share it with you.

Another thing, I've made the script quite basic and changes are saved to the original file. Because, by default, whenever you open a non-PXD file, Pixelmator Pro imports it in PXD, you'd need to go to Pixelmator Pro preferences and turn off that option to save changes to the original files.

Hope that helps!
User avatar

2020-09-29 17:10:37

Thanks a lot Andrius,

I will try this out. There is a lot to learn and I also did not know I could deactivate that standard behavior from the beginning. It will save me a lot of time, when I am editing screenshots for the web.

I really like the idea of being able to program some of the parts of images via AppleScript.
User avatar

2020-10-01 05:18:13

Hi All,

Does anyone know if you can automate the Repair tool? I've searched through the Applescript dictionary as well as the provided online examples but I'm unable to find any sample code or references. Additionally, can actions be automated to edit pictures wtihin Photos? You can open photos and manually select to use Pixelmator to edit photos but can these actions be automated as well? Thanks in advance for any information that anyone can provide.
User avatar

2020-10-01 07:30:30

by cbrnadt.px 2020-10-01 02:18:13 Hi All,

Does anyone know if you can automate the Repair tool? I've searched through the Applescript dictionary as well as the provided online examples but I'm unable to find any sample code or references. Additionally, can actions be automated to edit pictures wtihin Photos? You can open photos and manually select to use Pixelmator to edit photos but can these actions be automated as well? Thanks in advance for any information that anyone can provide.
The Photos AppleScript dictionary has a way to get photos according to a variety of properties and you can export/import as well, so you should be able to create a script to edit the photos in Pixelmator Pro and import the edited versions back to your library as new images. However, if you're looking to save your changes back to the same images in your library, that doesn't appear to be possible at first glance.

As for automating repairing areas, this isn't currently possible. I think we could potentially make the Repair Selection command scriptable. Do you need to repair exactly the same area in a number of different photos? I guess my question is — how do you plan to script the areas to be repaired?
User avatar

2020-10-01 19:10:04

Will you port an equivalent API to a JSContext on iOS (as Omni have done with OmniGraffle and their other products) ?

The osascript interface you have created on macOS, can of course be used with JavaScript for Automation, and it would be good to aim for some degree of cross-platform scripting.
User avatar

2020-10-02 02:11:54

I would like to express my most sincere and heartfelt thanks to the Development team for going above and beyond to add AppleScript support to Pixelmator Pro! There is an enormous amount of power and endless integration possibilities (osascript, anyone? For those of you who like to do a bit of shell scripting in Bash, do a man on "osascript" and get ready to pick your jaw up off the floor) that the quirky and lovable little language we call AppleScript makes available to each of us as users, but only if developers care enough to implement support for it. Thank you for your outstanding technical leadership and for doing right by your users by empowering us! You've made my month, and it's only 10/1 😀!

To whet your appetite in terms of a micro-framework to leverage AppleScript in a Bash script integration, consider the following:

Starting with Andrius' example code, above, from 9/25 (Thanks, Andrius!), we create a Bash wrapper script that encapsulates his verbatim AppleScript within a so-called "here document" by using the syntax "cat <<- EOF" on a line which will read every line below that line until a line with the token EOF is encountered. All of that data in between, the raw AppleScript, is then piped into the osascript binary which will interpret the AppleScript and drive Finder and Pixelmator Pro. Finally, to be visually clean, we dispose of both output and error messages normally destined for the controlling terminal by redirecting output (standard output, file descriptor 1) to /dev/null (the bit bucket that comes with every Mac - and every Unix or Linux system for that matter) with the syntax "> /dev/null", and telling errors (standard error, file descriptor 2) to "follow" standard output with the syntax "2>&1" (literally file descriptor "2" follows ">&" file descriptor "1"). Save the script as something like "pmHelper", and set read and execute permissions for all users on the system via the chmod (Change Mode - aka, permission) command "chmod a+rx pmHelpder", and then run the script with a "./pmHelper<RETURN>" from the Bash shell. Voila! Want to take it a step further? Implement it as a function in your ~/.bashrc file - the fun never ends!

#!/usr/bin/env bash

cat <<- EOF | /usr/bin/osascript > /dev/null 2>&1

set desktopPath to (path to desktop as text)
set folderPath to desktopPath & "Exports"
set exportFolder to ""

tell application "Finder"
if exists folder folderPath is false then
make new folder at desktopPath with properties {name:"exports"}
end if

set exportFolder to folder folderPath
end tell

tell application "Pixelmator Pro"
set imageBaseName to (exportFolder as text) & name of the front document

# 1024 x 1024
export the front document to file (imageBaseName & ".png") as PNG with properties {compression factor:100}

set sizes to {180, 167, 152, 120, 76}
repeat with size in sizes
tell the front document to resize image width size height size resolution 72 algorithm ml super resolution
export the front document to file (imageBaseName & "@" & (size as text) & ".png") as PNG with properties {compression factor:100}
tell the front document to undo
end repeat
end tell
EOF
User avatar

2020-10-02 20:16:17

by frank72 Will you port an equivalent API to a JSContext on iOS (as Omni have done with OmniGraffle and their other products) ?

The osascript interface you have created on macOS, can of course be used with JavaScript for Automation, and it would be good to aim for some degree of cross-platform scripting.
I second this. As many users work only on iOS, it would make sense to have cross-platform scripting. AppleScript is not available on that platform.
User avatar

2020-10-06 04:34:20

by Andrius 2020-10-01 11:30:30
The Photos AppleScript dictionary has a way to get photos according to a variety of properties and you can export/import as well, so you should be able to create a script to edit the photos in Pixelmator Pro and import the edited versions back to your library as new images. However, if you're looking to save your changes back to the same images in your library, that doesn't appear to be possible at first glance.

As for automating repairing areas, this isn't currently possible. I think we could potentially make the Repair Selection command scriptable. Do you need to repair exactly the same area in a number of different photos? I guess my question is — how do you plan to script the areas to be repaired?
Hi Andrius,

Thank you so much for the reply, that's extremely helpful and appreciated.

In terms of the repair tool, it would be for the same area in a large number of photos. The attempt was to write a script to apply the tool to the same area, location or coordinates of the photos since they're all the same dimensions. Thanks again!
User avatar

2020-10-06 10:07:23

by frank72 2020-10-01 16:10:04 Will you port an equivalent API to a JSContext on iOS (as Omni have done with OmniGraffle and their other products) ?

The osascript interface you have created on macOS, can of course be used with JavaScript for Automation, and it would be good to aim for some degree of cross-platform scripting.
We don't have any immediate plans for this, but we can certainly keep it in mind!
by D_ave_G 2020-10-01 23:11:54 I would like to express my most sincere and heartfelt thanks to the Development team for going above and beyond to add AppleScript support to Pixelmator Pro! There is an enormous amount of power and endless integration possibilities (osascript, anyone? For those of you who like to do a bit of shell scripting in Bash, do a man on "osascript" and get ready to pick your jaw up off the floor) that the quirky and lovable little language we call AppleScript makes available to each of us as users, but only if developers care enough to implement support for it. Thank you for your outstanding technical leadership and for doing right by your users by empowering us! You've made my month, and it's only 10/1 😀!
I'll admit I haven't had the time to try this out just yet but I love the ingenuity — and your kinds words are also very much appreciated.
by cbrnadt.px 2020-10-06 01:34:20
Hi Andrius,

Thank you so much for the reply, that's extremely helpful and appreciated.

In terms of the repair tool, it would be for the same area in a large number of photos. The attempt was to write a script to apply the tool to the same area, location or coordinates of the photos since they're all the same dimensions. Thanks again!
Got it, in your case, a repair selection feature should cover this workflow quite nicely. I'll pass the suggestion on to the rest of the team!
User avatar

2020-11-02 18:56:48

Thank you again for the AppleScript support. I use the 2 scripts you created for me every day and it's really sped up my workflow. Can I ask for 1 more script? The two scripts you provided work with pixelmator files, but I would like a script that would open jpeg and tiff files, convert to pixelmator files and then apply the pixelmator adjustments and save them to another folder. Here's the script you created that works with pixelmator files. Thanks again for all your help.
tell application "Pixelmator Pro"
	-- Open a prompt that lets you pick multiple Pixelmator Pro files to process 
	-- and save references to all those images in the originalImages variable
	set originalImages to choose file with prompt ¬
		"Please select the images to process:" with multiple selections allowed
	-- Open a prompt to choose the location where the files should be exported 
	set exportLocation to choose folder with prompt ¬
		"Please select where you'd like export the images:"
	-- Start a repeat loop that loops over each image
	repeat with a from 1 to number of originalImages
		-- Open the current image in the loop
		set currentImage to open item a of originalImages
		-- Apply the auto white balance adjustments
		auto white balance currentImage
		-- Apply the auto lightness adjustments
		auto light currentImage
		-- Export the images to the location chosen previously as Pixelmator Pro files
		export currentImage to file ((exportLocation as text) & ¬
			name of currentImage & "-edited" & ".pxd") as Pixelmator Pro
		-- Close the current image without saving
		close currentImage without saving
	end repeat
	display notification (number of originalImages as text) & ¬
		" images have been successfully edited." with title "Auto WB and Auto Lightness"
end tell
User avatar

2020-11-03 09:07:40

Hey Max, that script should work for JPEG and TIFF files too — to recap, the current script opens images and, in fact, no file type is disabled, so you could try to open any kind of file, Pixelmator Pro would just refuse to open the file and script would stop running. Anyway, the script does three things:

1. Opens a number of images in any compatible format (JPEG and TIFF included)
2. Applies auto white balance and auto lightness
3. Exports to PXD, leaving the original untouched

Am I right in thinking you'd also like to modify the originals? Or am I getting something wrong?
User avatar

2020-11-05 04:21:35

That's exactly what I want to do, but it doesn't work for me. When I try to select a folder of tiff images it opens the first file and returns the error: "Can't make missing value into type document". What I've been doing instead is to use automator to convert all the files into pxd files (in another folder) and then use the first script you gave me to apply auto white and auto lightness to those files. Am I doing something wrong?
User avatar

2020-11-09 15:08:27

Ohhh, I just realized this will be the same issue as fly had before with large TIFFs. We've fixed this for the next Pixelmator Pro update, but for now, here's a script that should work for you:
tell application "Pixelmator Pro"
	set originalImages to choose file with prompt ¬
		"Please select the images to process:" with multiple selections allowed
	set exportLocation to choose folder with prompt ¬
		"Please select where you'd like export the images:"
	repeat with a from 1 to number of originalImages
		set currentImage to open item a of originalImages
		if currentImage = missing value then
			repeat with repeatCounter from 1 to 10
				try
					set currentImage to the front document
					if currentImage ≠ missing value then
						exit repeat
					end if
				on error
					delay 0.5
					if repeatCounter = 10 then
						activate
						display alert "Unable to set currentImage to the front document. Failed at image " & a & " of " & number of originalImages & "."
						return
					end if
				end try
			end repeat
		end if
		auto white balance currentImage
		auto light currentImage
		export currentImage to file ((exportLocation as text) & ¬
			name of currentImage & "-edited" & ".pxd") as Pixelmator Pro
		close currentImage without saving
	end repeat
	display notification (number of originalImages as text) & ¬
		" images have been successfully edited." with title "Auto WB and Auto Lightness"
end tell
User avatar

2020-11-11 07:50:15

This works perfectly! Thank you!
User avatar

2020-11-29 14:10:52

How Can I work with document property name?
Pixelmator = Application('Pixelmator Pro')
Pixelmator.includeStandardAdditions = true
	
const docs = Pixelmator.open(diskItems) // return array with documents
	
docs.map(doc => {
	console.log(doc.name) // Error: -1700
})
EDIT:
I got it:
To send the get event to the external entity and return its value, call the property as a function
doc.name()
User avatar

2021-01-14 06:54:36

Wow!! not a Script writer but - This would be a "Nice to Have" -- Cartoon Animator 4 Pipeline allows me to export into Pixelmator to edit or change a Character or create a background etc... but unlike photo shop and clip-studio once I edit it -it will not auto update in Cartoon animator - I have to drag each sprite one by one into the CA4 folders which is an all day affair (or at least it seems like it) anyhow - it would be a nice to have feature. Thanks Guys!
User avatar

2021-01-14 08:06:43

by Dremond 2021-01-14 04:54:36 Wow!! not a Script writer but - This would be a "Nice to Have" -- Cartoon Animator 4 Pipeline allows me to export into Pixelmator to edit or change a Character or create a background etc... but unlike photo shop and clip-studio once I edit it -it will not auto update in Cartoon animator - I have to drag each sprite one by one into the CA4 folders which is an all day affair (or at least it seems like it) anyhow - it would be a nice to have feature. Thanks Guys!
It sounds like this should work if you were to go into Pixelmator Pro preferences and turn off "Import JPEG, PNG, and TIFF images". It would be great if you could try that and let me know if it helps!
User avatar

2021-02-03 00:50:39

Thanks again for changing the sharpening range to 0-200. How would I modify the script a few comments above to include sharpening? For example a radius of 1 and an amount of 150? Thanks!
User avatar

2021-02-03 08:53:15

by Max McCarty 2021-02-02 22:50:39 Thanks again for changing the sharpening range to 0-200. How would I modify the script a few comments above to include sharpening? For example a radius of 1 and an amount of 150? Thanks!
The Sharpen adjustment is scriptable, but its Intensity value currently isn’t – only the radius is. It shouldn’t be too tricky to add, though, and I’ll pass this on to the devs too.

In the meantime, as a workaround, you could create a preset named “Sharpen150” (or whatever name you like) with the values you need, then use the “apply color adjustments preset” command to apply it.
User avatar

2021-02-03 11:47:34

My apologies, the above is incorrect! The 'sharpen' property is, in fact, intensity, I thought it was a boolean that turned the adjustment on or off. Here's the modified script:
tell application "Pixelmator Pro"
	set originalImages to choose file with prompt ¬
		"Please select the images to process:" with multiple selections allowed
	set exportLocation to choose folder with prompt ¬
		"Please select where you'd like export the images:"
	repeat with a from 1 to number of originalImages
		set currentImage to open item a of originalImages
		if currentImage = missing value then
			repeat with repeatCounter from 1 to 10
				try
					set currentImage to the front document
					if currentImage ≠ missing value then
						exit repeat
					end if
				on error
					delay 0.5
					if repeatCounter = 10 then
						activate
						display alert "Unable to set currentImage to the front document. Failed at image " & a & " of " & number of originalImages & "."
						return
					end if
				end try
			end repeat
		end if
		auto white balance currentImage
		auto light currentImage
		tell the color adjustments of layer 1 of currentImage
			set its sharpen to 150
			set its sharpen radius to 1
		end tell
		export currentImage to file ((exportLocation as text) & ¬
			name of currentImage & "-edited" & ".pxd") as Pixelmator Pro
		close currentImage without saving
	end repeat
	display notification (number of originalImages as text) & ¬
		" images have been successfully edited." with title "Auto WB and Auto Lightness"
end tell