| 001 | #!/usr/bin/env osascript |
| 002 | #coding: utf-8 |
| 003 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7-- |
| 004 | (* |
| 005 |
|
| 006 |
|
| 007 | 画像ファイルを収集 |
| 008 | URLにして |
| 009 | パス毎でソート |
| 010 |
|
| 011 | フォルダ名(親フォルダ名)をベースファイル名にするパターン |
| 012 |
|
| 013 |
|
| 014 | クラッシック記法 |
| 015 | Image Eventで画像解像度 ピクセルサイズを取得してポイントサイズを計算して求める |
| 016 |
|
| 017 |
|
| 018 |
|
| 019 | com.cocolog-nifty.quicktimer.icefloe *) |
| 020 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7-- |
| 021 | use AppleScript version "2.8" |
| 022 | use scripting additions |
| 023 |
|
| 024 | ######################## |
| 025 | # RUN=Wクリックの始まり |
| 026 | # on run {listAliasFilePath} |
| 027 |
|
| 028 |
|
| 029 | (* |
| 030 | ######################## |
| 031 | #ダイアログ |
| 032 | *) |
| 033 |
|
| 034 |
|
| 035 | ######################## |
| 036 | #ダイアログ |
| 037 | set strMsg to ("画像ファイルを 選択") as text |
| 038 | set strPrompt to ("画像ファイルを を選択してください" & return & "複数選択可") as text |
| 039 | set aliasDesktopDirPath to (path to desktop from user domain) as alias |
| 040 | set listUTI to {"public.image"} as list |
| 041 | try |
| 042 | tell application "SystemUIServer" |
| 043 | activate |
| 044 | set listAliasFilePath to (choose file strMsg with prompt strPrompt default location aliasDesktopDirPath of type listUTI with invisibles and multiple selections allowed without showing package contents) as list |
| 045 | end tell |
| 046 | on error strErrMes number numErrNo |
| 047 | log strErrMes & numErrNo |
| 048 | return false |
| 049 | end try |
| 050 | if listAliasFilePath is {} then |
| 051 | return false |
| 052 | end if |
| 053 |
|
| 054 |
|
| 055 | set boolDone to (open listAliasFilePath) |
| 056 | set boolDone to doQuit4Process() |
| 057 | return boolDone |
| 058 | end run |
| 059 |
|
| 060 | ######################## |
| 061 | # OPEN =ドロップの始まり |
| 062 | on open listAliasFilePath |
| 063 | |
| 064 | #処理対象のUTIリスト=このUTIのファイルだけを次工程に回す |
| 065 | set listUTI to {"public.image", "public.tiff", "public.jpeg", "public.png", "org.webmproject.webp", "public.heic", "public.avif"} as list |
| 066 | #次工程に回すリスト |
| 067 | set listAliasImagePath to {} as list |
| 068 | #OPENに渡されたエイリアスのリストを順番に処理 |
| 069 | repeat with itemAliasFilePath in listAliasFilePath |
| 070 | #エイリアス確定 |
| 071 | set aliasItemFilePath to itemAliasFilePath as alias |
| 072 | #INFO FORで主要な値をレコード格納して |
| 073 | set recordInfoFor to (info for aliasItemFilePath) as record |
| 074 | #フォルダは |
| 075 | set boolIsDir to (folder of recordInfoFor) as boolean |
| 076 | #次工程に回さない |
| 077 | if boolIsDir is false then |
| 078 | #エイリアスだったら |
| 079 | set boolIsAlias to (alias of recordInfoFor) as boolean |
| 080 | #次工程に間沢ない |
| 081 | if boolIsAlias is false then |
| 082 | #UTIを取得して |
| 083 | set strUTI to (type identifier of recordInfoFor) as text |
| 084 | #対象リストに含まれていれば |
| 085 | set boolContain to (listUTI contains strUTI) as boolean |
| 086 | if boolContain is true then |
| 087 | #次工程に回すリストに加える |
| 088 | set end of listAliasImagePath to aliasItemFilePath |
| 089 | end if |
| 090 | end if |
| 091 | end if |
| 092 | end repeat |
| 093 | #ここの時点で『listAliasImagePath』にが対象のUTIのファイルエイリアスがリストで入ってる |
| 094 | |
| 095 | tell application "Finder" |
| 096 | set listSortedFilePath to (sort (every item of listAliasImagePath) by name) as alias list |
| 097 | end tell |
| 098 | #リストのアイテム数 |
| 099 | set numCntList to (count of listSortedFilePath) as integer |
| 100 | |
| 101 | #リストの数だけリピート |
| 102 | repeat with iteNO from 1 to numCntList by 1 |
| 103 | #カウンターのゼロサプレス |
| 104 | set strZeroPadd to ("000" & iteNO & "") as text |
| 105 | set strItemNO to (text -3 through -1 of strZeroPadd) as text |
| 106 | ############################## |
| 107 | #【1】元ファイル名 拡張子 ベースファイル名 |
| 108 | set aliasFilePath to (item iteNO of listSortedFilePath) as alias |
| 109 | #ファイル情報 |
| 110 | set recordInfoFor to (info for aliasFilePath) as record |
| 111 | #ファイル名 |
| 112 | set strFileName to (name of recordInfoFor) as text |
| 113 | #拡張子でも良いのですが『大文字』『小文字』判定が面倒なので |
| 114 | set strExt to (name extension of recordInfoFor) as text |
| 115 | #ファイル名から拡張子抜いてベースファイル名を作成 |
| 116 | #ファイル名の文字数 |
| 117 | set numCntCharName to (count of every character of strFileName) as integer |
| 118 | #拡張子の文字数 |
| 119 | set numCntCharExt to (count of every character of strExt) as integer |
| 120 | #拡張子の文字数を除いたファイル名がベースファイル名(ドット分を忘れずに取る) |
| 121 | set strBaseFileName to (text 1 through (numCntCharName - (numCntCharExt + 1)) of strFileName) as text |
| 122 | #親フォルダのパスと親フォルダ名の取得 |
| 123 | tell application "Finder" |
| 124 | set aliasContainerDirPath to (container of aliasFilePath) as alias |
| 125 | set strDirName to (name of aliasContainerDirPath) as text |
| 126 | end tell |
| 127 | |
| 128 | ############################## |
| 129 | #【2】縦横PXサイズ 解像度 |
| 130 | #UTIを使う方がいい場合が多いです |
| 131 | set strUTI to (type identifier of recordInfoFor) as text |
| 132 | #次工程に回すUTI |
| 133 | set listUTI to {"public.image", "public.tiff", "public.jpeg", "public.png", "org.webmproject.webp", "public.heic"} as list |
| 134 | #ファイルのUTIが上記のリストに含まれていれば次工程に回す |
| 135 | if listUTI contains strUTI then |
| 136 | #WpxとHpxをレコードで戻す |
| 137 | #ここでサブルーチン・ファンクションにファイルのエイリアスを渡して |
| 138 | #画像のピクセルサイズを取得してもらいます |
| 139 | set listResponse to doGetImageSizePx(aliasFilePath) as list |
| 140 | #エラーが戻り値だったら アラート出して終了 |
| 141 | if (first item of listResponse) is false then |
| 142 | tell application "SystemUIServer" |
| 143 | activate |
| 144 | display alert "画像のサイズの取得に失敗しました" |
| 145 | end tell |
| 146 | return false |
| 147 | end if |
| 148 | end if |
| 149 | #戻り値を分けて |
| 150 | set recordImageSize to (first item of listResponse) as record |
| 151 | set listResolution to (last item of listResponse) as list |
| 152 | #画像ピクセルサイズの取得 |
| 153 | set numWpx to (recordImageSize's width) as integer |
| 154 | set numHpx to (recordImageSize's Height) as integer |
| 155 | #この書き方でもOK |
| 156 | set numWpx to (width of recordImageSize) as integer |
| 157 | set numHpx to (Height of recordImageSize) as integer |
| 158 | #画像解像度の取得 |
| 159 | set numResolution to (first item of listResolution) as integer |
| 160 | #アイコンサイズで使う@2x用だけどここでは使わない |
| 161 | set strResIndex to (numResolution / 72) as integer |
| 162 | #ポイントサイズ取得(アイコンサイズ用:ここでは使わない) |
| 163 | set numWpt to (numWpx * (72 / numResolution)) as integer |
| 164 | set numHpt to (numHpx * (72 / numResolution)) as integer |
| 165 | |
| 166 | ############################## |
| 167 | #【3】変更後のファイル名を組み立てる |
| 168 | # 縦px X 横px @ 解像度 を付与する |
| 169 | set strAddSufix to ("" & numWpx & "x" & numHpt & "@" & numResolution & "") as text |
| 170 | # ベースファイル名 ハイフン 付加情報 |
| 171 | set strSetBaseFileName to ("" & strDirName & "-" & strAddSufix & "") as text |
| 172 | # アンダースコアよりハイフンの方がFinderでファイル名選択時に便利(ここでは使わない) |
| 173 | set strSetNewFileName to ("" & strItemNO & "-" & strSetBaseFileName & "." & strExt & "") as text |
| 174 | ####### |
| 175 | #元ファイルエイリアス 変更後のベースファイル名 拡張子を渡して変更してもらう |
| 176 | #変更後のファイルの同名ファイルがないか?チェック |
| 177 | tell application "Finder" |
| 178 | set boolExist to (exists of (file strSetNewFileName of folder aliasContainerDirPath)) as boolean |
| 179 | end tell |
| 180 | #同名のファイルがある場合は |
| 181 | if boolExist is true then |
| 182 | #重複回避のファイル番号カウント |
| 183 | set numCntIndexNo to 1 as integer |
| 184 | #ループ 無限ループよけで 100回に制限 |
| 185 | repeat 100 times |
| 186 | #ファイル番号カウンターを1つ増やして |
| 187 | set numCntIndexNo to (numCntIndexNo + 1) as integer |
| 188 | #ファイル名を組み立てて FINDER式の スペース 番号 で重複回避 |
| 189 | set strSetNewFileName to ("" & strItemNO & "-" & strSetBaseFileName & " " & numCntIndexNo & "." & strExt & "") as text |
| 190 | #変更後のファイル名で重複がないか確認して |
| 191 | tell application "Finder" |
| 192 | set boolExist to (exists of (file strSetNewFileName of folder aliasContainerDirPath)) as boolean |
| 193 | end tell |
| 194 | #重複していないなら、変更後のファイル名確定なのでループを抜ける |
| 195 | if boolExist is false then |
| 196 | exit repeat |
| 197 | end if |
| 198 | end repeat |
| 199 | end if |
| 200 | |
| 201 | ##ファイル名を変更する |
| 202 | try |
| 203 | tell application "Finder" |
| 204 | tell file aliasFilePath |
| 205 | set name to strSetNewFileName |
| 206 | end tell |
| 207 | end tell |
| 208 | on error strErrMsg number numErrNo |
| 209 | log "No: " & numErrNo & linefeed & "Error:" & strErrMsg |
| 210 | #失敗したならfalseを戻す |
| 211 | return false |
| 212 | end try |
| 213 | #成功したんらTRUEを戻す |
| 214 | end repeat |
| 215 | |
| 216 | return true |
| 217 | end open |
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 | ########################################## |
| 223 | #Image Eventのファンクション |
| 224 | to doGetImageSizePx(aliasFilePath) |
| 225 | #入力がエイリアスの場合リストにしておくと、うまくいく |
| 226 | set listFilePath to {aliasFilePath} as list |
| 227 | #イメージイベントの起動・開始 |
| 228 | tell application "Image Events" |
| 229 | launch |
| 230 | #リストからエイリアスを取り出す方式 |
| 231 | set readImage to open (first item of listFilePath) |
| 232 | try |
| 233 | tell readImage |
| 234 | #解像度 |
| 235 | set listResolution to resolution as list |
| 236 | set numResolution to (first item of listResolution) as integer |
| 237 | #縦横PXサイズ |
| 238 | set listDimensions to dimensions as list |
| 239 | set numWpx to (first item of listDimensions) as integer |
| 240 | set numHpx to (last item of listDimensions) as integer |
| 241 | #レコードに組み直す |
| 242 | set recordImageSize to {width:numWpx, Height:numHpx} as record |
| 243 | end tell |
| 244 | #処理が終わったら閉じる |
| 245 | close readImage |
| 246 | #処理が成功したか?判定 |
| 247 | set boolDone to true as boolean |
| 248 | on error strErrMes number numErrNo |
| 249 | #エラーした場合も画像を閉じるのを忘れずに |
| 250 | close readImage |
| 251 | #処理が成功したか?判定 |
| 252 | set boolDone to false as boolean |
| 253 | end try |
| 254 | end tell |
| 255 | #ImageEventの終了 |
| 256 | try |
| 257 | tell application "Image Events" to quit |
| 258 | end try |
| 259 | #取得した値を戻す |
| 260 | if boolDone is true then |
| 261 | return {recordImageSize, listResolution} as list |
| 262 | else if boolDone is false then |
| 263 | #取得が失敗している場合はfalseを戻す |
| 264 | return {false, false} as list |
| 265 | end if |
| 266 | #ファンクションの終了 |
| 267 | |
| 268 | end doGetImageSizePx |
| 269 |
|
| 270 |
|
| 271 | ########################################## |
| 272 | #終了時のプロセスクリーニング |
| 273 | to doQuit4Process() |
| 274 | set listBinName to {"PlugInLibraryService", "WorkflowServiceRunner", "XprotectService", "com.apple.automator.runner"} as list |
| 275 | #SIGINT |
| 276 | repeat with itemBinName in listBinName |
| 277 | set boolDone to doBinName2SIGINT(itemBinName) |
| 278 | end repeat |
| 279 | return boolDone |
| 280 | end doQuit4Process |
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 | ################################ |
| 286 | #SIGINT |
| 287 | to doBinName2SIGINT(argBinName) |
| 288 | set strBinName to argBinName as text |
| 289 | set listPID to doGetProcessID(strBinName) as list |
| 290 | repeat with itemPID in listPID |
| 291 | set strCmd to ("/bin/kill -SIGINT " & itemPID & "") as text |
| 292 | try |
| 293 | do shell script strCmd |
| 294 | on error strErrMsg number numErrNo |
| 295 | log "No: " & numErrNo & linefeed & "Error:" & strErrMsg |
| 296 | return false |
| 297 | end try |
| 298 | end repeat |
| 299 | |
| 300 | return true |
| 301 | end doBinName2SIGINT |
| 302 |
|
| 303 |
|
| 304 | ################################ |
| 305 | #doGetProcessID |
| 306 | to doGetProcessID(argProcessName) |
| 307 | #テキストで確定させて |
| 308 | set strProcessName to argProcessName as text |
| 309 | #ユーザーIDを取得 |
| 310 | set ocidUserShotName to (short user name of ((system info) as record)) as text |
| 311 | #ユーザーIDでコマンドを整形して |
| 312 | set strCmd to ("/usr/bin/pgrep -u " & ocidUserShotName & " " & strProcessName & " || true") as text |
| 313 | #実行 |
| 314 | set strStdOut to (do shell script strCmd) as text |
| 315 | if strStdOut is "" then |
| 316 | set listProcessID to {} as list |
| 317 | return listProcessID |
| 318 | end if |
| 319 | #戻り値をリストにする |
| 320 | set strDelim to AppleScript's text item delimiters |
| 321 | set AppleScript's text item delimiters to return |
| 322 | set listProcessID to every text item of strStdOut |
| 323 | set AppleScript's text item delimiters to strDelim |
| 324 | |
| 325 | return listProcessID |
| 326 | end doGetProcessID |