スクリプトエディタでオープンして実行するだけ
必要なライブラリはバンドル内にすべて格納
掲載リストはグラフィックス描画にかかわる箇所のみ
How to use/ダイアログ表示AppleScript
How to use/ファイル出力AppleScript
How to use/ファイル出力+AirDrop AppleScript
How to use/クリップボード転送AppleScript
How to use/各種GUIアプリ操作AppleScript
OS標準搭載の13の実行環境およびサードパーティの数十の実行環境
tell front document set aWidth to width set aHeight to height
if {aWidth, aHeight} is not equal to {1024.0, 1024.0} then display dialog "Wrong Image Size (1024×1024 required)" buttons {"OK"} default button 1 with icon 2 with title "Size Error" return end if
repeat with i in resolList resize image width i height i resolution 72 algorithm bilinear export to file (aTargFileBase & "_" & (i as string) & "x" & (i as string) & ".png") as PNG undo end repeat end tell end tell
解決策は、tellブロックでdocumentを指定するのをやめて、コマンドのパラメータとしてfront documentといったオブジェクトを表記することです。または、「属性値 of it」のようにdocumentへの参照を記述しておくことです(他の言語のユーザーが腰を抜かすので、なるべくitは使わないで記述していますが……)。
tell the front document set aWidth to width set aHeight to height end tell
if {aWidth, aHeight} is not equal to {1024.0, 1024.0} then display dialog "Wrong Image Size (1024×1024 required)" buttons {"OK"} default button 1 with icon 2 with title "Size Error" return end if
repeat with i in resolList resize image front document width i height i resolution 72 algorithm bilinear export front document to file (aTargFileBase & "_" & (i as string) & "x" & (i as string) & ".png") as PNG undo end repeat
set dList to name of every document –> {"ゆっくり素材れいむ.pxd", "ゆっくり素材まりさ.pxd"}
tell front document set d1Name to name of it if d1Name contains "れいむ" then set d2Name to retAnItemByCond(dList, "れいむ") of me else set d2Name to retAnItemByCond(dList, "まりさ") of me end if
tell layer "root" tell layer "顔" set dList to every layer repeat with i in dList set j to contents of i tell j set ddList to (name of every layer whose visible is true) if ddList is not equal to {} then set aCon to contents of first item of ddList set the end of allD to {"root", "顔", name of j, aCon} end if end tell end repeat end tell end tell end tell
tell document d2Name repeat with i in allD copy i to {L1, L2, L3, L4} tell layer L3 of layer L2 of layer L1 set tmpL to name of every layer repeat with ii in tmpL set jj to contents of ii tell layer jj if jj = L4 then set visible to true else set visible to false end if end tell end repeat end tell end repeat end tell end tell
on retAnItemByCond(aList, aParam) repeat with i in aList set j to contents of i
if j does not contain aParam then return j end if end repeat end retAnItemByCond
tell front document with timeout of 3000 seconds super resolution end timeout end tell end tell
tell application "Pixelmator Pro" tell front document select all copy close without saving end tell end tell
on getUTIFromFile(aFile) set aPath to POSIX path of aFile
set aWS to current application’s NSWorkspace’s sharedWorkspace() set pRes to (aWS’s isFilePackageAtPath:aPath) as boolean if pRes = false then set superType to (current application’s UTTypeData) else set superType to (current application’s UTTypePackage) end if
set pathString to current application’s NSString’s stringWithString:aPath set aExt to (pathString’s pathExtension()) as string
set aUTType to current application’s UTType’s typeWithFilenameExtension:aExt conformingToType:(superType)
set aUTIstr to aUTType’s identifier() as string return aUTIstr end getUTIFromFile
–UTIリストが指定UTIに含まれているかどうか演算を行う on filterUTIList(aUTIList, aUTIstr) set anArray to NSArray’s arrayWithArray:aUTIList set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr) set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list return bRes end filterUTIList
–ファイルパスの加工処理 set newImgName to ((current application’s NSString’s stringWithString:(POSIX path of aLut))’s lastPathComponent()’s stringByDeletingPathExtension()’s stringByAppendingString:".jpg") as string set newImgFullPath to (imgParent as string) & "/" & newImgName set newImgFile to POSIX file newImgFullPath
tell application "Pixelmator Pro" activate tell front document tell color adjustments of first layer –ここだけ、ネスティングを分割するとエラーになる set its custom lut to aLut end tell
export to newImgFullPath as JPEG with properties {compression factor:0.5, bits per channel:8} undo end tell end tell end repeat
–後片付け tell application "Pixelmator Pro" tell front document close without saving end tell end tell
on getParentPathFromAlias(aliasPath) set aPath to POSIX path of aliasPath set pathString to current application’s NSString’s stringWithString:aPath set newPath to pathString’s stringByDeletingLastPathComponent() return newPath end getParentPathFromAlias
on getFilesWithUTI(acceptUTI, aliasList) set aList to {}
repeat with i in aliasList set anAlias to i as alias set aUTI to getUTIfromPath(anAlias) of me if aUTI is not equal to missing value then set uRes to filterUTIList({aUTI}, acceptUTI) of me
if uRes is not equal to {} then set the end of aList to contents of i end if end if end repeat
return aList end getFilesWithUTI
–AliasからUTIを求める on getUTIfromPath(anAlias) set aPOSIXpath to POSIX path of anAlias set aURL to current application’s |NSURL|’s fileURLWithPath:aPOSIXpath if aURL = missing value then return missing value set aRes to aURL’s resourceValuesForKeys:{current application’s NSURLTypeIdentifierKey} |error|:(missing value) if aRes = missing value then return missing value return (aRes’s NSURLTypeIdentifierKey) as string end getUTIfromPath
–UTIリストが指定UTIに含まれているかどうか演算を行う on filterUTIList(aUTIList, aUTIstr) set anArray to NSArray’s arrayWithArray:aUTIList set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr) set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list return bRes end filterUTIList
AppleScript用語辞書的には、「export as lut」コマンドを新設したことと、「color adjustments」コマンドに「custom lut」を指定するオプションを追加しています。
AppleScript名:現在オープン中の写真に指定のLUTを反映させる.scpt
–Pixelmator Pro用語辞書内に掲載されているサンプルを、読みやすいように書き換えた set lutFile to choose file with prompt "Choose the LUT you’d like to apply to the layer:" of type {"com.blackmagicdesign.cube"}
tell application "Pixelmator Pro" tell front document tell color adjustments of first layer –ここだけ、ネスティングを分割するとエラーになる set its custom lut to lutFile end tell end tell end tell
–新規保存ファイルパスの作成 set pathStr to POSIX path of i set filenameStr to (current application’s NSString’s stringWithString:(pathStr))’s lastPathComponent() as string set savePath to outFolStr & filenameStr
tell application "Pixelmator Pro" save front document in file savePath as PNG
tell front document close without saving end tell end tell end repeat
set aFile to choose file of type {"public.svg-image"} set outPath to choose file name with prompt "select output file name"
tell application "Gapplin" open aFile
tell front document export to outPath as PNG with options {class:export options, scale:1.0} close without saving end tell end tell
Pixelmator Pro v2.0.1から2.0.2のバージョンアップ時にAppleScript用語辞書が変更されました。
・select color rangeコマンドにmodeを追加
new selection : Create a new selection.
add selection : Add to the existing selection.
subtract selection : Subtract from the existing selection.
intersect selection : Intersect with the existing selection.
Pixelmator Pro v2.0.2から2.0.3へのバージョンアップ時にはとくに変更はありません。
select color range v : Select all areas of a specified color. This command can be executed on the document (in which case every layer is sampled) or on a layer, in which case the selection is created based on the layer's content.
select color range document
color list of integer : The color of the areas that should be selected.
[range integer] : The range of the colors that should be selected. With a range of 1, only areas that are exactly of the specified color will be selected. As the range is increased, increasingly more similarly-colored areas will be selected.
[smooth edges boolean] : Whether the edges of the selection should be smoothed.
もともと、対話的に値を模索するような値なので、画像で使われている色数の分布などの情報をあらかじめ取得して分析しておき、その中でどの程度の色をピックアップするのか知っておく必要があるでしょう。そこまで徹底的に分析してからでないと、このselect color rangeコマンドをバッチ処理的な世界観の中で有効利用することは難しいと思います。
tell the front document set aWidth to width set aHeight to height
if {aWidth, aHeight} is not equal to {1024.0, 1024.0} then display dialog "Wrong Image Size (1024×1024 required)" buttons {"OK"} default button 1 with icon 2 with title "Size Error" return end if
repeat with i in resolList resize image width i height i resolution 72 algorithm bilinear export to file (aTargFileBase & "_" & (i as string) & "x" & (i as string) & ".png") as PNG undo end repeat end tell end tell
tell document "Piyomaru Whack-3-moles Game" set visible of layer "Mole1" to false set visible of layer "Mole2" to false set visible of layer "Mole3" to false set visible of layer "Mole3Hit" to false set visible of layer "Mole3Miss" to false
repeat 10 times tell layer "Title" set its visible to true set keyRes to keyscanWait(delayCount, true) of me set its visible to false set keyRes to keyscanWait(delayCount, true) of me if keyRes = true then exit repeat end tell end repeat
delay 1
set moleList to {{"Mole1", false, 20}, {"Mole2", false, 10}, {"Mole3", true, 20}} repeat maxMole times repeat with i in moleList copy i to {layerName, hitLogic, delayTime} set visible of layer layerName to true set keyRes to keyscanWait((random number from 1 to delayTime) * delayCount, hitLogic) of me set visible of layer layerName to false
if keyRes = true then set hitF to true set aScore to aScore + 1 beep set visible of layer "Mole3Hit" to true delay 1 set visible of layer "Mole3Hit" to false exit repeat else if keyRes = false then set aMiss to aMiss + 1 repeat 3 times set visible of layer "Mole3Miss" to true delay 0.5 set visible of layer "Mole3Miss" to false delay 0.5 end repeat set keyRes to true –To Skip See off action exit repeat end if end repeat
if keyRes is not equal to true then set aMiss to aMiss + 1 repeat 3 times set visible of layer "Mole3Miss" to true delay 0.5 set visible of layer "Mole3Miss" to false delay 0.5 end repeat end if end repeat
display dialog "Score:" & (aScore as string) & return & "Miss:" & (aMiss as string) with title "GAME OVER" buttons {"OK"} default button 1 with icon 1
end tell end tell
on keyscanWait(delayLoop, hitLogic) repeat delayLoop times set commandStatus to not ((((current application’s NSEvent’s modifierFlags() as integer) div (current application’s NSShiftKeyMask as integer)) mod 2) = 0) if commandStatus = true then return hitLogic end repeat return missing value end keyscanWait
さて、コンテストに話を戻します。Pixelmator Pro v1.8の試用版を使うことで、同アプリケーションのScriptを書いて試せるとのこと(やっています)。辞書内容は事前に確認していましたが、ツッコミどころがあまりないぐらい、さまざまな機能が載っていました。「え、こんな機能まで乗せてるの?」という謎の充実度を見せており(Pixelmator Pro本体に搭載されていないQRコードの検出機能とか)、AS機能の開発に元AppleのSal Soghoianが協力したという話もうなづけます。
……巨大Scriptで一部のScripterがコンテストを蹂躙することを避けつつ、「このあたり、穴場だよね?」という箇所を埋めてあります。あっと驚く参加者(たぶん、最年少参加者)が優勝をもぎ取って、真の実力者(Edama2さんみたいな)が投稿したScriptが全力でスルーされつつPixelmator Pro Scriptingの肥やしになりそうな、よく考えられたレギュレーションです(コンテストってそういうもんなんで)。