Finder上で選択中の画像ファイルを指定ファイルサイズを下回るよう圧縮率を調整してJPEGに変換するAppleScriptです。
指定画像を指定のファイルサイズ(1K=1024で計算)以内になるよう、非圧縮の状態から段階的に圧縮率を高くして仕上がりファイルサイズを下回るかどうか演算を行います。ファイルに書き込まずに仕上がりサイズの計算を行うところが新機軸です。
macOS標準搭載のスクリプトメニューから呼び出して使うことを想定しています。実行すると、ダイアログ表示して指定ファイルサイズをKB単位で数値入力する必要があります。
巨大な画像ファイルを処理してしまった場合への対処として、最初に最高圧縮率で圧縮してみて、指定ファイルサイズ以内になるかどうかを計算します。
最初は圧縮率100%から25%まで1%きざみで仕上がり画像ファイルサイズを計算してみたのですが、数十Mバイトの巨大な画像を処理させたら、途中でマウスカーソルが反応しないほどOSが無反応になったので(暴走状態?)、それを避けるために、このような処理を行なってみました。
JPEGにファイル変換した画像はデスクトップに
UUID_JPEG画質.jpg
の形式で出力されます。JPEG画質は1.0から0.01までの数値です。
AppleScript名:指定ファイルサイズのJPEGに変換(圧縮率可変)_1K=1024で計算 |
— Created 2014-02-21 Shane Stanley — Modified 2019-02-11 Takaaki Naganoya use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "AppKit" property |NSURL| : a reference to current application’s |NSURL| property NSUUID : a reference to current application’s NSUUID property NSArray : a reference to current application’s NSArray property NSString : a reference to current application’s NSString property NSImage : a reference to current application’s NSImage property NSPredicate : a reference to current application’s NSPredicate property NSJPEGFileType : a reference to current application’s NSJPEGFileType property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey property compressList : {100, 99, 98, 97, 96, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 40, 30, 20, 25} –大→小 へと並んでいる必要がある property kbBase : 1024 tell application "Finder" set inFiles to selection as alias list end tell –指定のAlias listのうち画像ファイルのみ抽出 set filRes1 to filterAliasListByUTI(inFiles, "public.image") of me if filRes1 = {} then return –ターゲットサイズを指定 set aMessage to "Input Target size in KB ( " & (kbBase as string) & " based )" set aRes to text returned of (display dialog aMessage default answer "300" buttons {"OK"} default button 1) if aRes = false or aRes = "" then return set targLimit to (aRes as number) * kbBase –選択中のファイルのうちの1つから親フォルダを求め、出力先ファイルパスを組み立てる set outPathTarg to (contents of first item of filRes1) set pathString to NSString’s stringWithString:outPathTarg set newPath to (pathString’s stringByDeletingLastPathComponent()) as string –Main Loop repeat with i in filRes1 set aNSImage to (NSImage’s alloc()’s initWithContentsOfFile:(i)) –巨大すぎる画像のリサイズ時への保険で、最小サイズで投機的に圧縮して結果を確認する set minSize to calcSavedJPEGSizeFromNSIMage(aNSImage, (last item of compressList) / 100) of me if minSize < targLimit then –Simulate Suitable JPEG Compression Ratio to target file size repeat with ii in compressList set jj to ii / 100 set fileSize to calcSavedJPEGSizeFromNSIMage(aNSImage, jj) of me if fileSize < targLimit then exit repeat end if end repeat else set jj to 0.01 –エラー時にはやけくそで1%まで圧縮指定 end if set outPOSIXpath to (newPath & "/" & (NSUUID’s UUID()’s UUIDString()) as string) & "_" & (jj as string) set savePath to outPOSIXpath & ".jpg" saveNSImageAtPathAsJPG(aNSImage, savePath, jj) of me end repeat –Alias listから指定UTIに含まれるものをPOSIX pathのリストで返す on filterAliasListByUTI(aList, targUTI) set newList to {} repeat with i in aList set j to POSIX path of i set tmpUTI to my retUTIfromPath(j) set utiRes to my filterUTIList({tmpUTI}, targUTI) if utiRes is not equal to {} then set the end of newList to j end if end repeat return newList end filterAliasListByUTI –指定のPOSIX pathのファイルのUTIを求める on retUTIfromPath(aPOSIXPath) set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value) if theResult = true then return theValue as string else return theResult end if end retUTIfromPath –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 –NSImageを指定パスにJPEG形式で保存、qulityNumは0.0〜1.0。1.0は無圧縮 on saveNSImageAtPathAsJPG(anImage, outPath, qulityNum as real) set imageRep to anImage’s TIFFRepresentation() set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep set pathString to NSString’s stringWithString:outPath set newPath to pathString’s stringByExpandingTildeInPath() set myNewImageData to (aRawimg’s representationUsingType:(NSJPEGFileType) |properties|:{NSImageCompressionFactor:qulityNum}) set aLength to (myNewImageData’s |length|()) as number set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean return aRes –true/false end saveNSImageAtPathAsJPG –NSImageをJPEG形式で保存したときのファイルサイズを計算 on calcSavedJPEGSizeFromNSIMage(anImage, qulityNum as real) set imageRep to anImage’s TIFFRepresentation() set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep set myNewImageData to (aRawimg’s representationUsingType:(NSJPEGFileType) |properties|:{NSImageCompressionFactor:qulityNum}) set aLength to (myNewImageData’s |length|()) as number return aLength end calcSavedJPEGSizeFromNSIMage |
More from my site
(Visited 461 times, 2 visits today)