Hello!
I’ve written a script in FileMaker to copy to my clipboard the screenshot, edited and annotated in Preview and, also close the picture selected. After that I manually paste pictures into my database from the clipboard.
I’m not fine with GUI scripting, but the script works most of the time. I don’t know why, but the script sometimes mixes keystrokes (for example, instead of pressing “c” using {command down} – presses “c” using {alt, command down}) and stops. (???)
Could somebody help me with more elegant (and workable ;)) solution, please?
The script:
tell application "Preview"
activate
end tell
tell application "System Events"
tell application process "Preview"
set frontmost to true
-- Select All, Copy, Close with Save
keystroke "a" using {command down}
delay 0.2
keystroke "c" using {command down}
delay 0.2
keystroke "w" using {command down, shift down}
delay 0.2
keystroke return
end tell
end tell
tell application "Preview"
activate
set myImage to ((path of document 1) as POSIX file) as alias -- select the file
close document 1 saving yes
quit
end tell
set the clipboard to myImage -- copy to the clipboard
To get the image itself to the clipboard:
tell application "Preview"
activate
tell application "System Events" to tell application process "Preview"
keystroke "a" using command down -- select all
delay 0.5
keystroke "c" using command down -- copy to the clipboard
delay 0.5
end tell
close document 1 saving yes
quit
end tell
This is quite interesting, although rather limited as it stands. Tested with JPEGs, GIFs, and PNGs in 10.14.6:
-- This assumes that the front Preview document is an unedited image opened from a file.
tell application "Preview" to set myImage to ((path of document 1) as POSIX file)
tell application "Image Events"
launch
tell (open myImage) to set fileType to its file type
-- Get the clipboard class equivalent to the Image Events file type.
if (fileType is JPEG) then
set pictureType to JPEG picture
else if (fileType is GIF) then
set pictureType to GIF picture
else if (fileType is TIFF) then
set pictureType to TIFF picture
else if (fileType is PNG) then
set pictureType to «class PNGf»
else
-- More types can be added, but I don't have any to test.
set pictureType to missing value
end if
quit
end tell
if (pictureType is not missing value) then set the clipboard to (read myImage as pictureType)
Since the clipboard reserves all image classes, no image type checks are necessary. It’s enough to take one of these classes and that’s it.
Therefore, here it is the most elegant solution:
tell application "Preview"
activate
set myImage to path of document 1 -- select the file
close document 1 saving yes
quit
end tell
set the clipboard to (read myImage as JPEG picture) -- copy to the clipboard
But thank you for the tip. Without your script, I would not have figured out how to finish it all. Now I know.
That’s true when actually copying from an application. But I was thinking of the read command, which has to be told what kind of data to expect from a file in order to be able add the appropriate class tag. However, your shortcut seems to work regardless of whether the data’s actually JPEG, TIFF, or PNG. Interesting ….
But I’m not sure it’s a great idea. Taking, say, PNG data and simply labelling it jpeg – which is what the read command is doing there – just means that if some client tries to use it as jpeg, they’ll get nonsense.
Fortunately the clipboard seems to ignore the type and successfully convert it to a tiff format, to supply as a standard image format version, and most client are likely to ask for that. But if one asks for jpeg, that’s not what they’re going to get.
Mmm. I was going to look into it further later today. I noticed yesterday that if the file was read as data, the resulting clipboard contents wouldn’t open in Preview. It didn’t make immediate sense that the clipboard or Preview would be able to recognise data incorrectly labelled in one way, but not in another.
Looking more closely at the OP’s post, it says the selected image should be closed, so quitting Preview altogether afterwards isn’t necessary appropriate. It also says the images are screenshots, so they’d be PNGs nowadays, which simplifies things still further. I don’t recall what type they were back in February 2011 or when Preview became “scriptable”.
tell application "Preview"
set imagePath to path of document 1
close document 1 saving yes
end tell
set the clipboard to (read (imagePath as POSIX file) as «class PNGf»)
More flexibly:
use AppleScript version "2.4" -- Maybe a later version needed. I don't remember when Preview became "scriptable".
use framework "Foundation"
use scripting additions
tell application "Preview"
set imagePath to path of document 1
close document 1 saving yes
end tell
set extn to (current application's class "NSString"'s stringWithString:(imagePath))'s pathExtension()'s lowercaseString()
set lookup to (current application's class "NSDictionary"'s dictionaryWithDictionary:({jpeg:"JPEG", jpg:"JPEG", gif:"GIFf", tiff:"TIFF", png:"PNGf"})) -- Add more extension:enumCode entries if required.
set pictureType to lookup's valueForKey:(extn)
if (pictureType is not missing value) then set the clipboard to (read (imagePath as POSIX file) as (pictureType as text))
I would not rely upon the fact that screenshots are PNG by default.
Many tools give the ability to change that and I know a lot of users who made such change.
What need for read (imagePath as POSIX file) when read (imagePath) does the job flawlessly ?
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 9 aout 2019 16:14:11
Other options are to set the Filemaker container field to the graphic file as a reference to the file on disk, or embedded directly into the Filemaker file. Both can be done via Applescript.