Export Layers as Images to Keynote Slides
This macOS-only example details the use of an Omni Automation plug-in to export images to file and then call a shortcut to add those exported images to new slides in the frontmost Keynote presentation.
Export Layers to Keynote Slides |
A macOS-only shortcut that adds a row for each of the chosen images to the current outline. |
|
↓ Downloads:
DOWNLOAD PLUG-IN • DOWNLOAD SHORTCUT
The OmniGraffle Omni Automation Plug-In
This plug-in exports the layers of the current OmniGraffle canvas as a series of PNG files, either one for each layer, or as a set of images composited from the bottom to the topmost layer. During execution of the plug-in, the user will be prompted to choose a name and location for the folder containing the exported images.
Here is the initial interface presented by the plug-in:
If the option to execute an installed shortcut is chosen, a file URL to the created folder will be passed to the installed shortcut whose name has been entered in the plug-in interface. The passed file URL is in a form similar to this:
file:///Users/Otto/Pictures/Export Folder/
which will be percent encoded and appended to the URL that calls the Shortcuts application: (see line 118 shown below)
file%3A%2F%2F%2FUsers%2FOtto%2FPictures%2FExport%20Folder%2F
The provided shortcut is designed to receive text input and contains actions for decoding and processing the URL of the created folder.
NOTE: the plug-in uses the Preferences class to store and retrieve used settings.
IMPORTANT: for best results, set the dimensions of the current canvas to match those of the Keynote slides. For example, if the Keynote presentation dimensions is set to “wide” (1920x1080), then set the dimensions of the canvas to match (1920x1080). Also note that the alpha transparency of the PNG images uses the current OmniGraffle export settings (see below).
Plug-In: Export Current Canvas Layers
/*{
"type": "action",
"targets": ["omnigraffle"],
"author": "Otto Automator",
"identifier": "com.omni-automation.og.export-layers-current-vanvas",
"version": "1.0",
"description": "Exports the layers of the current canvas as either individual PNG files, or as images composited from the bottom to the topmost layer.",
"label": "Export Current Canvas Layers",
"shortLabel": "Export Layers",
"paletteLabel": "Export Layers",
"image": "gearshape"
}*/
(() => {
let preferences = new Preferences()
var action = new PlugIn.Action(async function(selection, sender){
// defaults
var defaultShouldRunShortcut = false
var defaultExportOptionIndex = 0
var defaultShortcutTilte = "Title of Shortcut"
var shouldRunShortcut = preferences.readBoolean("shouldRunShortcut")
console.log("shouldRunShortcut-stored", shouldRunShortcut)
if(!shouldRunShortcut){
shouldRunShortcut = defaultShouldRunShortcut
}
var exportOptionIndex = preferences.readNumber("exportOptionIndex")
console.log("exportOptionIndex-stored", exportOptionIndex)
if(!exportOptionIndex){
exportOptionIndex = defaultExportOptionIndex
}
var shortcutTitle = preferences.readString("shortcutTitle")
console.log("shortcutTitle-stored", shortcutTitle)
if(!shortcutTitle){
shortcutTitle = defaultShortcutTilte
}
var exportOptions = ["Individual Images","Composited Images"]
var exportOptionsMenu = new Form.Field.Option(
"exportOption",
"Image Style",
[0,1],
exportOptions,
exportOptionIndex
)
var checkSwitchField = new Form.Field.Checkbox(
"shouldRunShortcut",
"Run associated shortcut",
shouldRunShortcut
)
var textInputField = new Form.Field.String(
"shortcutTitle",
"Shortcut",
shortcutTitle,
null
)
var inputForm = new Form()
inputForm.addField(exportOptionsMenu)
inputForm.addField(checkSwitchField)
inputForm.addField(textInputField)
inputForm.validate = function(formObject){
var shouldRunShortcut = formObject.values["shouldRunShortcut"]
if (shouldRunShortcut){
var textValue = formObject.values['shortcutTitle']
if(!textValue){return false}
}
return true
}
var formPrompt = "Export Parameters:"
var buttonTitle = "Continue"
var formObject = await inputForm.show(formPrompt,buttonTitle)
var exportOptionIndex = formObject.values["exportOption"]
preferences.write("exportOptionIndex", exportOptionIndex)
var shouldRunShortcut = formObject.values["shouldRunShortcut"]
preferences.write("shouldRunShortcut", shouldRunShortcut)
var shortcutTitle = formObject.values["shortcutTitle"]
preferences.write("shortcutTitle", shortcutTitle)
var cnvs = document.windows[0].selection.canvas
cnvs.layers.forEach(layer => layer.visible = false)
var wrapperPromises = new Array()
cnvs.layers.slice().reverse().forEach((layer, index) => {
layer.visible = true
var exportName = encodeURIComponent(index + "-" + layer.name)
var fileTypeID = "public.png"
var wrapperPromise = document.makeFileWrapper(exportName, fileTypeID)
wrapperPromises.push(wrapperPromise)
if (exportOptionIndex === 0){layer.visible = false}
})
cnvs.layers.forEach(layer => layer.visible = true)
Promise.all(wrapperPromises).then(wrappers => {
// Create and Show File Saver
var filesaver = new FileSaver()
filesaver.message = "Name and Location for export folder:"
var folderType = new FileType("public.folder")
filesaver.types = [folderType, FileType.png, FileType.pdf]
//var docName = document.name
var fldrwrapper = FileWrapper.withChildren("Export Folder", wrappers)
var fileSaverPromise = filesaver.show(fldrwrapper)
// Process File Saver Result
fileSaverPromise.then(urlObj => {
if(shouldRunShortcut === true){
// remove any percent encoding
var decodedURL = decodeURIComponent(urlObj.string)
// encode entire URL
var encodedURL = encodeURIComponent(decodedURL)
// construct and execute Shortcuts URL
shortcutTitle = encodeURIComponent(shortcutTitle)
var urlStr = "shortcuts://run-shortcut?name=" + shortcutTitle + "&input=text&text=" + encodedURL
URL.fromString(urlStr).open()
}
})
})
});
action.validate = function(selection, sender){
return true
};
return action;
})();
Shortcut for Processing Exported Images
Here is the shortcut (DOWNLOAD) designed to accept the passed file URL to the export folder, and to create new slides in the frontmost Keynote presentation, for each of the exported images.
Here is the code of the AppleScript script for processing the images.
AppleScript: Keynote Slides from Image Files
on run {input, parameters}
set sourceFolder to input as POSIX file
set fileNames to list folder sourceFolder
set theseImageFiles to {}
repeat with i from 1 to count of fileNames
set thisImageFile to (sourceFolder as string) & (item i of fileNames)
set thisImageFile to thisImageFile as alias
set the end of theseImageFiles to thisImageFile
end repeat
tell application "Keynote"
activate
if playing is true then tell the front document to stop
if not (exists document 1) then
set thisDocument to make new document
set thisSlide to the first slide of thisDocument
end if
repeat with i from 1 to the count of theseImageFiles
set thisImageFile to (item i of theseImageFiles)
tell front document
set thisSlide to make new slide with properties {base layout:slide layout "Blank"}
tell thisSlide
set thisImage to make new image with properties {file:thisImageFile}
end tell
end tell
end repeat
end tell
return input
end run