Photosで選択中の写真をKeynoteで現在オープン中の書類の現在のスライド(ページ)以降に配置していくAppleScriptの改良版です。
作業の過程をiPhoneで写真撮影。撮影した写真を写真.app(Photos.app)経由でKeynote書類にまとめる作業を行なっていました。作業工程を時間こみで表示できないとわかりにくかったので、Keynoteの各スライドに時刻を入れるようにAppleScriptを書いておきました。
初版では写真.app(Photos)上の選択項目を一切ソートなどしなかったため、exifから取得した撮影日付で昇順ソートしています。
▲写真.app(Photos)上でKeynoteに配置したい写真を選択
▲あらかじめKeynote上でマスタースライド「画像(横長)」上のアイテムを編集しておくといいかも
▲AppleScriptによって写真.app上の写真をKeynote書類上に順次割り付け。タイトル部分にexifに記録されていた撮影時刻が入る
▲実行結果。写真.appから割り付けた写真は撮影日時でソートされている
AppleScript名:Photosで選択中の写真をKeynoteの現在の書類の現在のスライド以降に配置 v2 |
— – Created by: Takaaki Naganoya – Created on: 2019/05/26 — – Copyright © 2019 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" use BPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html use mdLib : script "Metadata Lib" version "2.0.0" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#Metadata_Lib property NSUUID : a reference to current application’s NSUUID property NSString : a reference to current application’s NSString property SMSForder : a reference to current application’s SMSForder property NSFileManager : a reference to current application’s NSFileManager tell application "Keynote" if (count every document) = 0 then return end tell –Photosで選択中の写真をすべて書き出してalias listを取得する set aList to exportSelectedPhotoOnPhotos() of me if aList = {} or aList = false then return set aLen to length of aList –書き出した画像の親フォルダを求めておく(あとで削除するため) tell application "Finder" set parentFol to parent of (item 1 of aList) end tell –exifから撮影日時を取得して2D List化 set aaList to {} repeat with i in aList set j to contents of i set exifDate to readExifDateTimeOriginal(j) of me set the end of aaList to {j, exifDate, (time string of exifDate)} end repeat –撮影日時で昇順ソート set aaaList to sortList2DAscending(aaList, {2}) of me tell application "Keynote" tell front document tell current slide set curNum to slide number –現在表示中のスライドの番号(ページ数)を取得する end tell –Photosから取得した写真のアイテム数でループ repeat with i from 1 to aLen copy (item i of aaaList) to {aPhoto, aDateObj, creTime} set newSlide to make new slide at slide (curNum + i) with properties {base slide:master slide "画像(横長)"} –This item is localized!! Maybe a "Photo" tell newSlide set object text of default title item to creTime set file name of image 1 to aPhoto –place an image to image placeholder end tell –配置画像を削除 tell application "Finder" delete aPhoto –配置した写真を削除 end tell end repeat end tell end tell –あとしまつ tell application "Finder" delete parentFol –画像のダウンロードフォルダを削除 end tell –Photosで選択中のファイルをtmporaryフォルダに書き出してalias listで返す on exportSelectedPhotoOnPhotos() set dtPath to (path to temporary items) as text set aUUID to NSUUID’s UUID()’s UUIDString() as text set dirPath to ((POSIX path of dtPath) & aUUID) set fileManager to NSFileManager’s defaultManager() set aRes to (fileManager’s createDirectoryAtPath:dirPath withIntermediateDirectories:true attributes:(missing value) |error|:(reference)) set dtPath to dtPath & aUUID tell application "Photos" set a to selection if a = {} then return {} set aRes to (export a to file dtPath) end tell tell application "Finder" tell folder dtPath set fList to (every file) as alias list end tell end tell if fList = {} then return false return fList end exportSelectedPhotoOnPhotos –指定JPEG画像のExif情報からDateTimeOriginalを取得してAS dateオブジェクトに変換して返す on readExifDateTimeOriginal(aTargFileAlias) set theMetadata to readMetadataFrom(aTargFileAlias) of me if theMetadata = false then return false set keysList to theMetadata’s allKeys() if "{Exif}" is not in (keysList as list) then return false set exifDate to theMetadata’s valueForKeyPath:"{Exif}.DateTimeOriginal" if exifDate = missing value then return false set a to NSString’s stringWithString:exifDate set {aDateStr, aTimeStr} to (a’s componentsSeparatedByString:" ") as list set bDateStr to repChar(aDateStr, ":", "/") of me set fullDate to date (bDateStr & " " & aTimeStr) return fullDate end readExifDateTimeOriginal –指定のファイルからメタデータを取得する on readMetadataFrom(imageFile) load framework set {theRecord, theError} to SMSForder’s metadataFromImage:imageFile |error|:(reference) if theRecord = missing value then — there was a problem, so extract the error description error false else return theRecord end if end readMetadataFrom –文字置換 on repChar(origText as string, targChar as string, repChar as string) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to targChar set tmpList to text items of origText set AppleScript’s text item delimiters to repChar set retText to tmpList as string set AppleScript’s text item delimiters to curDelim return retText end repChar –入れ子のリストを昇順ソート on sortList2DAscending(a, keyItem) return sort2DList(a, keyItem, {true}) of me end sortList2DAscending –入れ子のリストを降順ソート on sortList2DDecending(a, keyItem) return sort2DList(a, keyItem, {false}) of me end sortList2DDecending –2D Listをソート on sort2DList(aList as list, sortIndexes as list, sortOrders as list) load framework –index値をAS流(アイテムが1はじまり)からCocoa流(アイテムが0はじまり)に変換 set newIndex to {} repeat with i in sortIndexes set j to contents of i set j to j – 1 set the end of newIndex to j end repeat set sortTypes to {} repeat (length of sortIndexes) times set the end of sortTypes to "compare:" end repeat set resList to (SMSForder’s subarraysIn:(aList) sortedByIndexes:newIndex ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as {missing value, list} return resList end sort2DList |