Archive for the 'NSImage' Category

2017/12/08 指定文字の花文字を取得してRTFで書き出す

指定文字の花文字を取得して、収録グリフ数が10,000以上のフォントから30をデスクトップにRTFで書き出すAppleScriptです。

注意:ただし、本ScriptはRetina Display未対応です

hanamoji1.png

前のバージョンからの改良点は、

 〇慊衒源が指定フォント中にグリフを持っているかどうかチェックしてから処理
 ▲ぅ鵐好函璽襪気譴討い襯侫ント数が少ない場合への対処

といったところです。

花文字作成部分の処理内容は、

 ”漸荵慊衒源を収録しているフォントの一覧を取得
 ↓,納萋世靴織侫ントのうち、グリフ数が10,000以上のものをピックアップ
 スタイル付きテキストを作成。仕上がり(描画)サイズを取得
 せ転紊りサイズでRaw画像を作成
 ズ鄒したRaw画像を塗りつぶす(White)
 ε匹蠅弔屬靴Raw画像にスタイル付きテキストを描画
 Raw画像の各座標から色情報をピックアップ、指定スレッショルド値以上であればドットが存在していると判定
 ┘疋奪箸存在している場合には描画文字列を、存在していない場合にはスペースを配列に追加
 作成した2次元配列をテキストに変換。フォント名をテキストに含める指定を行なっている場合にはフォントのPostScript名を文字列に出力

というところです。

これまでは(macOS 10.10より前)AppleScriptで画像処理を行おうとすると、Photoshopあたりで処理するのが定番でしたが、Cocoaの機能を利用することで、カラープロファイル処理が厳密に求められるような内容でなければPhotoshopなしでけっこうな処理が行えるようになってきました。

テキスト処理において(文字コード自動判別が可能になったため)テキストエディタが要らなくなってきたように、データベース処理で(小規模データであれば)FileMaker Proが要らなくなってきて、同様に画像処理でもPhotoshopなしで処理できるものが増えてきた今日このごろです。

AppleScript名:指定文字の花文字を取得してRTFで書き出す
– Created 2017-11-19 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/5012

property NSArray : a reference to current application’s NSArray
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSBezierPath : a reference to current application’s NSBezierPath
property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName
property NSFont : a reference to current application’s NSFont
property NSUUID : a reference to current application’s NSUUID
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName
property NSImage : a reference to current application’s NSImage
property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName
property NSString : a reference to current application’s NSString
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSColor : a reference to current application’s NSColor
property NSColorSpace : a reference to current application’s NSColorSpace
property NSFontManager : a reference to current application’s NSFontManager
property NSPredicate : a reference to current application’s NSPredicate
property NSDictionary : a reference to current application’s NSDictionary

set aString to “あ”
set hanaMax to 30
set hanaSize to 36
set targFontName to “Osaka-Mono” –”Courier New”–結果を出力するRTFのフォント名(PostScript名)

set fRes to getEveryFontPSNameANdGlyphsNum() of me
set theArray to NSArray’s arrayWithArray:fRes
set thePred to NSPredicate’s predicateWithFormat:“fontNum > 10000″
set bArray to (theArray’s filteredArrayUsingPredicate:thePred) as list

if hanaMax > (length of bArray) then
  set hanaMax to (length of bArray)
end if

set aCount to 1

repeat hanaMax * 2 times
  set aFontName to contents of item aCount of bArray
  
  
–花文字文字列を作成
  
set fRes to getHanamojiStr(hanaSize, fontName of aFontName, aString, 0.7, true) of me
  
if fResfalse then
    –StyledStringで結果出力(RTFとしてファイル保存)
    
set aStyledStr to makeRTFfromParameters(fRes, targFontName, 11, 0.0, 0.0) of me
    
set aRange to current application’s NSMakeRange(0, aStyledStr’s |length|())
    
set aVal1 to NSFont’s fontWithName:targFontName |size|:11
    
    
aStyledStr’s beginEditing()
    (
aStyledStr’s addAttribute:(NSFontAttributeName) value:aVal1 range:aRange)
    
aStyledStr’s endEditing()
    
    
set targFol to POSIX path of (path to desktop)
    
set aUUID to NSUUID’s UUID()’s UUIDString() as text
    
set bRes to my saveStyledTextAsRTF(aUUID, targFol, aStyledStr) –RTFで書き出す
    
    
set aCount to aCount + 1
    
if aCount > hanaMax then exit repeat
  end if
end repeat

–花文字文字列を計算して返す
on getHanamojiStr(aFontSize as real, aFontName as string, aString as string, aThread as real, incFontName as boolean)
  if length of aString is not equal to 1 then return false
  
  
–指定文字コードが指定フォント中に存在するかチェック
  
set fRes to retGlyphsInFont(aFontName, id of aString) of me
  
if fRes = false then return false
  
  
set aThreadShould to 768 * aThread
  
if (chkMultiByteChar(aString) of me) = false then
    set spaceChar to string id 12288 –全角スペース(UTF-16)
  else
    set spaceChar to string id 32 –半角スペース
  end if
  
  
set fillColor to NSColor’s whiteColor –塗り色
  
set bString to aString & ” “ –処理内容の帳尻合わせ(そのままだと右端が欠けるのでスペースを入れた)
  
set anAssrStr to makeRTFfromParameters(bString, aFontName, aFontSize, -2, (aFontSize * 1.2)) of me
  
set aSize to anAssrStr’s |size|()
  
  
if class of aSize = record then
    set attrStrWidth to width of aSize
    
set attrStrHeight to height of aSize
  else if class of aSize = list then –macOS 10.13.xのバグ回避
    copy aSize to {attrStrWidth, attrStrHeight}
  end if
  
  
set {xPos, yPos} to {0, 0}
  
  
set tmpImg1 to makeImageWithFilledColor(attrStrWidth, attrStrHeight, fillColor) of me
  
set tmpImg2 to drawAttributedStringsOnImage(tmpImg1, anAssrStr, xPos, yPos) of me
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:(tmpImg2’s TIFFRepresentation())
  
  
–画像から順次指定座標の色データを拾って花文字listに反映
  
set strList to {}
  
repeat with y from 1 to attrStrHeight - 1
    
    
set strListX to {}
    
repeat with x from 0 to attrStrWidth - 1
      set tmpCol to getColorFromRawImage(aRawimg, x, y) of me
      
      
if tmpCol is not equal to false then
        if tmpCol is not equal to {255, 255, 255} then
          copy tmpCol to {tmpR, tmpG, tmpB}
          
if (tmpR + tmpG + tmpB) < aThreadShould then
            set the end of strListX to aString
          else
            set the end of strListX to spaceChar
          end if
        else
          set the end of strListX to spaceChar
        end if
      end if
      
    end repeat
    
set the end of strList to strListX
  end repeat
  
  
–2D List→Text
  
set aRes to list2dToStringByUsingDelimiters(strList, “”, return) of me
  
  
if incFontName = true then
    set fName to getDisplayedNameOfFont(aFontName) of me
    
set aRes to “■” & fName & return & return & aRes
  end if
  
  
return aRes
end getHanamojiStr

–指定Raw画像中の指定座標のピクセルの色をRGBで取り出す
on getColorFromRawImage(aRawimg, x as real, y as real)
  set origColor to (aRawimg’s colorAtX:x y:y)
  
set srgbColSpace to NSColorSpace’s deviceRGBColorSpace
  
if srgbColSpace = missing value then return false
  
  
set aColor to (origColor’s colorUsingColorSpace:srgbColSpace)
  
  
set aRed to (aColor’s redComponent()) * 255
  
set aGreen to (aColor’s greenComponent()) * 255
  
set aBlue to (aColor’s blueComponent()) * 255
  
  
return {aRed as integer, aGreen as integer, aBlue as integer}
end getColorFromRawImage

–画像のうえに指定のスタイル付きテキストを描画して画像を返す
on drawAttributedStringsOnImage(anImage, anAssrStr, xPos as real, yPos as real)
  anImage’s lockFocus()
  
anAssrStr’s drawAtPoint:(current application’s NSMakePoint(xPos, yPos))
  
anImage’s unlockFocus()
  
return anImage
end drawAttributedStringsOnImage

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real)
  set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
  
set aKey1 to (NSFontAttributeName)
  
  
set aVal2 to NSColor’s blackColor()
  
set aKey2 to (NSForegroundColorAttributeName)
  
  
set aVal3 to aKerning
  
set akey3 to (NSKernAttributeName)
  
  
set aVal4 to 0
  
set akey4 to (NSUnderlineStyleAttributeName)
  
  
set aVal5 to 2 –all ligature ON
  
set akey5 to (NSLigatureAttributeName)
  
  
set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init()
  
aParagraphStyle’s setMinimumLineHeight:(aLineSpacing)
  
aParagraphStyle’s setMaximumLineHeight:(aLineSpacing)
  
set akey7 to (NSParagraphStyleAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey7}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aParagraphStyle}
  
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
end makeRTFfromParameters

–指定サイズの画像を作成し、背景を指定色で塗る
on makeImageWithFilledColor(aWidth as real, aHeight as real, fillColor)
  set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
  
anImage’s lockFocus()
  
set theRect to {{x:0, y:0}, {width:aWidth, height:aHeight}}
  
set theNSBezierPath to NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
fillColor’s |set|()
  
theNSBezierPath’s fill()
  
anImage’s unlockFocus()
  
  
return anImage
end makeImageWithFilledColor

–2D Listをアイテム間および行間のデリミタを個別に指定してテキスト変換
on list2dToStringByUsingDelimiters(aList as list, itemDelimiter, lineDelimiter)
  set outList to {}
  
repeat with i in aList
    set aStr to listToStringUsingTextItemDelimiter(i, itemDelimiter) of me
    
set the end of outList to aStr
  end repeat
  
  
set bStr to listToStringUsingTextItemDelimiter(outList, lineDelimiter) of me
  
return bStr
end list2dToStringByUsingDelimiters

on listToStringUsingTextItemDelimiter(sourceList as list, textItemDelimiter)
  set CocoaArray to NSArray’s arrayWithArray:sourceList
  
set CocoaString to CocoaArray’s componentsJoinedByString:textItemDelimiter
  
return (CocoaString as string)
end listToStringUsingTextItemDelimiter

–ユーザー環境にインストールされているすべてのフォントのPostScript名とグリフ数を返す
on getEveryFontPSNameANdGlyphsNum()
  set aFontList to NSFontManager’s sharedFontManager()’s availableFonts()
  
set thePred to NSPredicate’s predicateWithFormat:“NOT SELF BEGINSWITH ’.’”
  
set aFontList to (aFontList’s filteredArrayUsingPredicate:thePred) as list
  
  
set aList to {}
  
repeat with i in aFontList
    set aName to contents of i
    
set aNum to countNumberOfGlyphsInFont(aName) of me
    
set the end of aList to {fontName:aName, fontNum:aNum}
  end repeat
  
  
return aList
end getEveryFontPSNameANdGlyphsNum

–指定Postscript名称のフォントに定義されている文字数を数えて返す
on countNumberOfGlyphsInFont(fontName as string)
  set aFont to NSFont’s fontWithName:fontName |size|:9.0
  
if aFont = missing value then return false
  
set aProp to aFont’s numberOfGlyphs()
  
return aProp as number
end countNumberOfGlyphsInFont

–フォントのPostScript NameからDisplayed Nameを取得
on getDisplayedNameOfFont(aName as string)
  set aFont to NSFont’s fontWithName:aName |size|:9.0
  
set aDispName to (aFont’s displayName()) as string
  
return aDispName
end getDisplayedNameOfFont

–全角文字が存在するか
on chkMultiByteChar(checkString as string)
  set aStr to NSString’s stringWithString:checkString
  
set aRes to aStr’s canBeConvertedToEncoding:(current application’s NSASCIIStringEncoding)
  
return (aRes as boolean)
end chkMultiByteChar

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName as string, targFol as string, aStyledString)
  set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
set theName to NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“rtf”
  
  
return (bRTF’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsRTF

–指定名称のフォントに指定の文字コードが含まれているかチェック
on retGlyphsInFont(fontName as string, strCode as integer)
  set aFont to NSFont’s fontWithName:fontName |size|:24.0
  
if aFont = missing value then return false
  
set aSet to aFont’s coveredCharacterSet()
  
set aRes to (aSet’s characterIsMember:strCode) as boolean
  
return aRes as list of string or string –as anything
end retGlyphsInFont

★Click Here to Open This Script 

2017/11/22 Finder上で選択中の画像を横方向に連結

Finder上で選択中の画像ファイルを横方向に連結してデスクトップにPNG形式で書き出すAppleScriptです。

Finder上で選択中の画像ファイルに対して、

finder_selection.png

それらが画像ファイルかどうかを確認し、画像ファイルであれば横方向に(10pointの隙間を作って)連結してデスクトップ上にPNG形式で書き出します。

c524ba57-f107-4605-92c9-dfb95720cf31_resized.png

こんなふうに(↑)。

Retina解像度対策(x2)は行なっていないので、解像度の異なる画像同士を連結しようとすると問題が(解像度の不一致による極端なサイズの違い)出る可能性があります。

なお、指定パスからのUTIツリーの取得にオープンソースのフレームワーク「MagicKit」を使用しています。本Scriptの実行にはGithub上のプロジェクトをダウンロードして各自でXcode上でFrameworkをビルドし、MagicKit.frameworkを~/Library/Frameworksフォルダ以下にインストールする必要があります。

AppleScript名:Finder上で選択中の画像を横方向に連結
– Created 2017-11-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”
use framework “AppKit”
use framework “MagicKit” –https://github.com/aidansteele/magickit
–http://piyocast.com/as/archives/4995

property NSMutableArray : a reference to current application’s NSMutableArray
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSUUID : a reference to current application’s NSUUID
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSImage : a reference to current application’s NSImage
property |NSURL| : a reference to current application’s |NSURL|
property GEMagicKit : a reference to current application’s GEMagicKit

property xGap : 10 –連結時の画像間のアキ(横方向)

tell application “Finder”
  set aSel to selection as alias list
  
if aSel = {} or aSel = “” then return
end tell

–選択した画像をArrayに入れる
set imgList to NSMutableArray’s new()
repeat with i in aSel
  set aPath to POSIX path of i
  
  
–指定ファイルのUTIを取得して、画像(public.image)があれば処理を行う
  
set aRes to (GEMagicKit’s magicForFileAtPath:aPath)
  
set utiList to (aRes’s uniformTypeHierarchy()) as list
  
if “public.image” is in utiList then
    set aNSImage to (NSImage’s alloc()’s initWithContentsOfFile:aPath)
    (
imgList’s addObject:aNSImage)
  end if
end repeat

–KVCで画像の各種情報をまとめて取得
set sizeList to (imgList’s valueForKeyPath:“size”) as list –NSSize to list of record conversion
set maxHeight to ((NSArray’s arrayWithArray:sizeList)’s valueForKeyPath:“@max.height”) as real
set totalWidth to ((NSArray’s arrayWithArray:sizeList)’s valueForKeyPath:“@sum.width”) as real
set totalCount to ((NSArray’s arrayWithArray:sizeList)’s valueForKeyPath:“@count”) as integer

–出力画像作成
set tSize to current application’s NSMakeSize((totalWidth + (xGap * totalCount)), maxHeight)
set newImage to NSImage’s alloc()’s initWithSize:tSize

–順次画像を新規画像に上書き
set xOrig to 0
repeat with i in (imgList as list)
  set j to contents of i
  
set curSize to j’s |size|()
  
set aRect to {xOrig, (maxHeight - (curSize’s height())), (curSize’s width()), (curSize’s height())}
  
set newImage to composeImage(newImage, j, aRect) of me
  
set xOrig to (curSize’s width()) + xGap
end repeat

–デスクトップにPNG形式でNSImageをファイル保存
set aDesktopPath to current application’s NSHomeDirectory()’s stringByAppendingString:“/Desktop/”
set savePath to aDesktopPath’s stringByAppendingString:((NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.png”)
set fRes to saveNSImageAtPathAsPNG(newImage, savePath) of me

–2つのNSImageを重ね合わせ合成してNSImageで返す
on composeImage(backImage, composeImage, aTargerRect)
  set newImage to NSImage’s alloc()’s initWithSize:(backImage’s |size|())
  
  
copy aTargerRect to {x1, y1, x2, y2}
  
set bRect to current application’s NSMakeRect(x1, y1, x2, y2)
  
  
newImage’s lockFocus()
  
  
set newImageRect to current application’s CGRectZero
  
set newImageRect’s |size| to (newImage’s |size|)
  
  
backImage’s drawInRect:newImageRect
  
composeImage’s drawInRect:bRect
  
  
newImage’s unlockFocus()
  
return newImage
end composeImage

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  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:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –成功ならtrue、失敗ならfalseが返る
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/11/18 指定文字の花文字を取得 v1.2

OS内にインストールされているフォントのうち収録グリフ数が8,000以上のフォントから50個をリストアップして、各フォントで花文字を作成してCotEditor上に花文字で新規ドキュメントを作成するAppleScriptです。

注意:ただし、本ScriptはRetina Display未対応です

flowerchar3_resized.png

フォント50個に限定しているのは、大量にCotEditorでドキュメントを作成するとCotEditorのパフォーマンスが大幅に低下するためです(メモリの都合? 常識的な挙動なので問題ではありません。ドキュメントの開きすぎで)。

なお、OS内にインストールされているフォントの数が極端に少ない環境(条件に合致するフォントが50個ないとか)ではエラーになる可能性があります。

flowerchar2_resized.png

CotEditor上に50個の未保存のドキュメントができてしまうので、一括で破棄するAppleScriptを掲載しておきます。

2017-11-18-22_12_04.gif

tell application “CotEditor”
  tell every document
    close without saving
  end tell
end tell

★Click Here to Open This Script 

AppleScript名:指定文字の花文字を取得 v1.2
– Created 2017-11-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4984

property NSArray : a reference to current application’s NSArray
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSBezierPath : a reference to current application’s NSBezierPath
property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName
property NSFont : a reference to current application’s NSFont
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName
property NSImage : a reference to current application’s NSImage
property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName
property NSString : a reference to current application’s NSString
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSColor : a reference to current application’s NSColor
property NSColorSpace : a reference to current application’s NSColorSpace
property NSFontManager : a reference to current application’s NSFontManager
property NSPredicate : a reference to current application’s NSPredicate

set aString to “ぴ”

set fRes to getEveryFontPSNameANdGlyphsNum() of me
set theArray to current application’s NSArray’s arrayWithArray:fRes
set thePred to current application’s NSPredicate’s predicateWithFormat:“fontNum > 8000″
set bArray to (theArray’s filteredArrayUsingPredicate:thePred) as list
set cArray to items 1 thru 50 of bArray

repeat with i in cArray
  set aFontName to contents of i
  
set fRes to getHanamojiStr(18, fontName of aFontName, aString, 0.7, true) of me
  
makeNewCotEditorDoc(fRes) of me
end repeat

–花文字文字列を計算して返す
on getHanamojiStr(aFontSize, aFontName, aString, aThread, incFontName)
  if length of aString is not equal to 1 then return false
  
  
set aThreadShould to 768 * aThread
  
  
set fillColor to NSColor’s whiteColor –塗り色
  
set bString to aString & ” “
  
set anAssrStr to makeRTFfromParameters(bString, aFontName, aFontSize, -2, (aFontSize * 1.2)) of me
  
set aSize to anAssrStr’s |size|()
  
  
if class of aSize = record then
    set attrStrWidth to width of aSize
    
set attrStrHeight to height of aSize
  else if class of aSize = list then –macOS 10.13.xのバグ回避
    copy aSize to {attrStrWidth, attrStrHeight}
  end if
  
  
set {xPos, yPos} to {0, 0}
  
  
–下地の画像を作成
  
set tmpImg1 to makeImageWithFilledColor(attrStrWidth, attrStrHeight, fillColor) of me
  
  
–下地の画像の上にAttributed Stringを描画
  
set tmpImg2 to drawAttributedStringsOnImage(tmpImg1, anAssrStr, xPos, yPos) of me
  
  
–NSImageからRaw画像を作成
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:(tmpImg2’s TIFFRepresentation())
  
  
–画像から順次指定座標の色データを拾って花文字listに反映
  
set strList to {}
  
repeat with y from 1 to attrStrHeight - 1
    
    
set strListX to {}
    
repeat with x from 0 to attrStrWidth - 1
      set tmpCol to getColorFromRawImage(aRawimg, x, y) of me
      
      
if tmpCol is not equal to false then
        if tmpCol is not equal to {255, 255, 255} then
          copy tmpCol to {tmpR, tmpG, tmpB}
          
if (tmpR + tmpG + tmpB) < aThreadShould then
            set the end of strListX to aString
          else
            set the end of strListX to “ ”
          end if
        else
          set the end of strListX to “ ”
        end if
      end if
      
    end repeat
    
set the end of strList to strListX
  end repeat
  
  
–2D List→Text
  
set aRes to list2dToStringByUsingDelimiters(strList, “ ”, return) of me
  
  
if incFontName = true then
    set fName to getDisplayedNameOfFont(aFontName) of me
    
set aRes to “■” & fName & return & return & aRes
  end if
  
  
return aRes
end getHanamojiStr

–指定Raw画像中の指定座標のピクセルの色をRGBで取り出す
on getColorFromRawImage(aRawimg, x, y)
  set origColor to (aRawimg’s colorAtX:x y:y)
  
set srgbColSpace to NSColorSpace’s deviceRGBColorSpace
  
if srgbColSpace = missing value then return false
  
  
set aColor to (origColor’s colorUsingColorSpace:srgbColSpace)
  
  
set aRed to (aColor’s redComponent()) * 255
  
set aGreen to (aColor’s greenComponent()) * 255
  
set aBlue to (aColor’s blueComponent()) * 255
  
  
return {aRed as integer, aGreen as integer, aBlue as integer}
end getColorFromRawImage

–画像のうえに指定のスタイル付きテキストを描画して画像を返す
on drawAttributedStringsOnImage(anImage, anAssrStr, xPos, yPos)
  anImage’s lockFocus()
  
anAssrStr’s drawAtPoint:(current application’s NSMakePoint(xPos, yPos))
  
anImage’s unlockFocus()
  
return anImage
end drawAttributedStringsOnImage

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real)
  set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
  
set aKey1 to (NSFontAttributeName)
  
  
set aVal2 to NSColor’s blackColor()
  
set aKey2 to (NSForegroundColorAttributeName)
  
  
set aVal3 to aKerning
  
set akey3 to (NSKernAttributeName)
  
  
set aVal4 to 0
  
set akey4 to (NSUnderlineStyleAttributeName)
  
  
set aVal5 to 2 –all ligature ON
  
set akey5 to (NSLigatureAttributeName)
  
  
set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init()
  
aParagraphStyle’s setMinimumLineHeight:(aLineSpacing)
  
aParagraphStyle’s setMaximumLineHeight:(aLineSpacing)
  
set akey7 to (NSParagraphStyleAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey7}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aParagraphStyle}
  
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
end makeRTFfromParameters

–指定サイズの画像を作成し、背景を指定色で塗る
on makeImageWithFilledColor(aWidth, aHeight, fillColor)
  set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
  
anImage’s lockFocus()
  
set theRect to {{x:0, y:0}, {width:aWidth, height:aHeight}}
  
set theNSBezierPath to NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
fillColor’s |set|()
  
theNSBezierPath’s fill()
  
anImage’s unlockFocus()
  
  
return anImage
end makeImageWithFilledColor

–2D Listをアイテム間および行間のデリミタを個別に指定してテキスト変換
on list2dToStringByUsingDelimiters(aList, itemDelimiter, lineDelimiter)
  set outList to {}
  
repeat with i in aList
    set aStr to listToStringUsingTextItemDelimiter(i, itemDelimiter) of me
    
set the end of outList to aStr
  end repeat
  
  
set bStr to listToStringUsingTextItemDelimiter(outList, lineDelimiter) of me
  
return bStr
end list2dToStringByUsingDelimiters

on listToStringUsingTextItemDelimiter(sourceList, textItemDelimiter)
  set CocoaArray to NSArray’s arrayWithArray:sourceList
  
set CocoaString to CocoaArray’s componentsJoinedByString:textItemDelimiter
  
return (CocoaString as string)
end listToStringUsingTextItemDelimiter

on getEveryFontPSNameANdGlyphsNum()
  set aFontList to NSFontManager’s sharedFontManager()’s availableFonts()
  
set thePred to NSPredicate’s predicateWithFormat:“NOT SELF BEGINSWITH ’.’”
  
set aFontList to (aFontList’s filteredArrayUsingPredicate:thePred) as list
  
  
set aList to {}
  
repeat with i in aFontList
    set aName to contents of i
    
set aNum to countNumberOfGlyphsInFont(aName) of me
    
set the end of aList to {fontName:aName, fontNum:aNum}
  end repeat
  
  
return aList
end getEveryFontPSNameANdGlyphsNum

–指定Postscript名称のフォントに定義されている文字数を数えて返す
on countNumberOfGlyphsInFont(fontName)
  set aFont to current application’s NSFont’s fontWithName:fontName |size|:9.0
  
if aFont = missing value then return false
  
set aProp to aFont’s numberOfGlyphs()
  
return aProp
end countNumberOfGlyphsInFont

–フォントのPostScript NameからDisplayed Nameを取得
on getDisplayedNameOfFont(aName)
  set aFont to current application’s NSFont’s fontWithName:aName |size|:9.0
  
set aDispName to (aFont’s displayName()) as string
  
return aDispName
end getDisplayedNameOfFont

on makeNewCotEditorDoc(aCon)
  tell application “CotEditor”
    set newDoc to make new document
    
tell newDoc
      set contents to aCon
    end tell
  end tell
end makeNewCotEditorDoc

★Click Here to Open This Script 

2017/11/17 指定文字の花文字を取得 v1

指定文字の花文字を取得するAppleScriptです。

注意:ただし、本ScriptはRetina Display未対応です

hanamoji1.png

指定文字のStyledStringを作成して画像に描画し、各座標の色データを取得して判定しています。こんな処理がAppleScriptだけで記述できるようになったことは、素直に驚きです。

ブランクのNSImageにスタイル付きテキストで描画し、Raw画像の各座標からカラーデータを抽出して2D Listに反映させ、最終テキストに変換して0.1秒(MacBook Pro Retina 2012 Core i7 2.66GHz)ぐらいです。色ピックアップ部分がオーバーヘッドになっていると思います。

AppleScript名:指定文字の花文字を取得 v1.1.1
– Created 2017-11-16 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4843

property NSArray : a reference to current application’s NSArray
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSBezierPath : a reference to current application’s NSBezierPath
property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName
property NSFont : a reference to current application’s NSFont
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName
property NSImage : a reference to current application’s NSImage
property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName
property NSString : a reference to current application’s NSString
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSColor : a reference to current application’s NSColor
property NSColorSpace : a reference to current application’s NSColorSpace

set aString to “長”
set fRes to getHanamojiStr(24, “HiraginoSans-W0″, aString) of me

–花文字文字列を計算して返す
on getHanamojiStr(aFontSize, aFontName, aString)
  if length of aString is not equal to 1 then return false
  
  
set fillColor to NSColor’s whiteColor –塗り色
  
set bString to aString & ” “
  
set anAssrStr to makeRTFfromParameters(bString, aFontName, aFontSize, -2, (aFontSize * 1.2)) of me
  
set aSize to anAssrStr’s |size|()
  
  
if class of aSize = record then
    set attrStrWidth to width of aSize
    
set attrStrHeight to height of aSize
  else if class of aSize = list then –macOS 10.13.xのバグ回避
    copy aSize to {attrStrWidth, attrStrHeight}
  end if
  
  
set {xPos, yPos} to {0, 0}
  
  
–下地の画像を作成
  
set tmpImg1 to makeImageWithFilledColor(attrStrWidth, attrStrHeight, fillColor) of me
  
  
–下地の画像の上にAttributed Stringを描画
  
set tmpImg2 to drawAttributedStringsOnImage(tmpImg1, anAssrStr, xPos, yPos) of me
  
  
–NSImageからRaw画像を作成
  
set aRawimg to NSBitmapImageRep’s imageRepWithData:(tmpImg2’s TIFFRepresentation())
  
  
–画像から順次指定座標の色データを拾って花文字listに反映
  
set strList to {}
  
repeat with y from 2 to attrStrHeight - 2
    set strListX to {}
    
repeat with x from 0 to attrStrWidth - 1
      set tmpCol to getColorFromRawImage(aRawimg, x, y) of me
      
      
if tmpCol is not equal to false then
        if tmpCol is not equal to {255, 255, 255} then
          copy tmpCol to {tmpR, tmpG, tmpB}
          
if (tmpR + tmpG + tmpB) < 500 then
            set the end of strListX to aString
          else
            set the end of strListX to “ ”
          end if
        else
          set the end of strListX to “ ”
        end if
      end if
      
    end repeat
    
set the end of strList to strListX
  end repeat
  
  
–2D List→Text
  
set aRes to list2dToStringByUsingDelimiters(strList, “ ”, return) of me
  
return aRes
end getHanamojiStr

–指定Raw画像中の指定座標のピクセルの色をRGBで取り出す
on getColorFromRawImage(aRawimg, x, y)
  set origColor to (aRawimg’s colorAtX:x y:y)
  
set srgbColSpace to NSColorSpace’s deviceRGBColorSpace
  
if srgbColSpace = missing value then return false
  
  
set aColor to (origColor’s colorUsingColorSpace:srgbColSpace)
  
  
set aRed to (aColor’s redComponent()) * 255
  
set aGreen to (aColor’s greenComponent()) * 255
  
set aBlue to (aColor’s blueComponent()) * 255
  
  
return {aRed as integer, aGreen as integer, aBlue as integer}
end getColorFromRawImage

–画像のうえに指定のスタイル付きテキストを描画して画像を返す
on drawAttributedStringsOnImage(anImage, anAssrStr, xPos, yPos)
  anImage’s lockFocus()
  
anAssrStr’s drawAtPoint:(current application’s NSMakePoint(xPos, yPos))
  
anImage’s unlockFocus()
  
return anImage
end drawAttributedStringsOnImage

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real)
  set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
  
set aKey1 to (NSFontAttributeName)
  
  
set aVal2 to NSColor’s blackColor()
  
set aKey2 to (NSForegroundColorAttributeName)
  
  
set aVal3 to aKerning
  
set akey3 to (NSKernAttributeName)
  
  
set aVal4 to 0
  
set akey4 to (NSUnderlineStyleAttributeName)
  
  
set aVal5 to 2 –all ligature ON
  
set akey5 to (NSLigatureAttributeName)
  
  
set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init()
  
aParagraphStyle’s setMinimumLineHeight:(aLineSpacing)
  
aParagraphStyle’s setMaximumLineHeight:(aLineSpacing)
  
set akey7 to (NSParagraphStyleAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey7}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aParagraphStyle}
  
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
end makeRTFfromParameters

–指定サイズの画像を作成し、背景を指定色で塗る
on makeImageWithFilledColor(aWidth, aHeight, fillColor)
  set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
  
anImage’s lockFocus()
  
set theRect to {{x:0, y:0}, {width:aWidth, height:aHeight}}
  
set theNSBezierPath to NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
fillColor’s |set|()
  
theNSBezierPath’s fill()
  
anImage’s unlockFocus()
  
  
return anImage
end makeImageWithFilledColor

–2D Listをアイテム間および行間のデリミタを個別に指定してテキスト変換
on list2dToStringByUsingDelimiters(aList, itemDelimiter, lineDelimiter)
  set outList to {}
  
repeat with i in aList
    set aStr to listToStringUsingTextItemDelimiter(i, itemDelimiter) of me
    
set the end of outList to aStr
  end repeat
  
  
set bStr to listToStringUsingTextItemDelimiter(outList, lineDelimiter) of me
  
return bStr
end list2dToStringByUsingDelimiters

on listToStringUsingTextItemDelimiter(sourceList, textItemDelimiter)
  set CocoaArray to NSArray’s arrayWithArray:sourceList
  
set CocoaString to CocoaArray’s componentsJoinedByString:textItemDelimiter
  
return (CocoaString as string)
end listToStringUsingTextItemDelimiter

★Click Here to Open This Script 

2017/09/27 macOS 10.13であらたにサポートされたHEIF画像をJPEGに変換

macOS 10.13であらたにサポートされたHEIF形式の画像をJPEGに変換するAppleScriptです。

HEIF(High Efficiency Image Format)は高品質の画像を少ないファイル容量で保持できる画像フォーマット。macOS 10.13およびiOS 11からサポートされるようになりました。拡張子は「heif」あるいは「heic」とのこと。

実際にHEIFのサンプル画像をJPEGに圧縮率を変更しつつ書き出してみたところ、60%ぐらいの圧縮率のJPEGファイルとHEIF画像が同程度のファイルサイズ(素材によるんでしょうけれど)。非圧縮のJPEG(1.6Mバイト)に対してHEIFは340Kバイト。見た目は非圧縮のJPEGと区別できませんでした。

heif_preview.png

HEIF形式の画像ファイルをFinder上でダブルクリックすると、Preview.appでなにごともなく表示されます。ただし、JPEGなどの画像をHEIFで書き出す機能はPreview.appにはついておらず、他の環境でサポートしていないHEIF画像をそのまま外に出してほしくない、といったところでしょうか。

heif_preview2.png

とりあえず、Cocoaを経由してHEIF画像をAppleScriptでハンドリングできないかと調べてみたところ、普通に(何も変更なく)NSImageに読み込んで、JPEGで書き出せました。

その逆に、JPEG画像をHEIF形式に変換する方法は、調べてもあまり素直な方法(Cocoaのオブジェクトを呼び出して書き出し)は見つかりません。無理やりBrew経由でコマンドラインツールをインストールして変換という状況。

それもそのはずで、HEIFは画像フォーマットというよりもコンテナであり、その中にはさまざまなデータ(画像、派生画像、イメージシーケンス、補助画像アイテム、メタデータ)を格納できるようになっているとのこと。

一応、AVFoundationに画像形式「AVFileTypeHEIF」の定義があるようです。

macOS 10.14〜10.15ぐらいでOS内にきちんとした仕組みを用意しようというところなんでしょうか。

AppleScript名:指定HEIF画像をJPG形式で保存
– Created 2017-09-27 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.7 –10.13 or later
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4851

set aFile to POSIX path of (choose file of type {“public.heic”} with prompt “Select HEIF image file”)
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile

set fRes to retUUIDfilePath(aFile, “jpg”) of me
set sRes to saveNSImageAtPathAsJPG(aImage, fRes, 0.6) of me

on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (current application’s NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((current application’s NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

–NSImageを指定パスにJPEG形式で保存
on saveNSImageAtPathAsJPG(anImage, outPath, qulityNum as real)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:qulityNum})
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsJPG

★Click Here to Open This Script 

2017/09/25 書式つきテキストを組み立ててサイズを取得して画像書き出し v2

複数行にわたる書式付きテキストを組み立てて、描画サイズを取得して画像書き出しするAppleScriptです。

スタイル付きテキスト(NSAttributedString)を作成し、その描画エリアのサイズを取得。そんなもん、こんな手軽に求められるとは思ってもみませんでした。

描画エリアのサイズをもとに空白画像を作成して、そこにスタイル付きテキストを描画。結果の画像を指定パス名で書き出します。

test9999.png
▲本Scriptの実行結果(macOS 10.12)。出力用の文字列を長くしても、描画サイズを調べて画像化しているので、途中で途切れたりはしません

ただし、意外なところでOSバージョンによる挙動の差が出ました。書式付きテキストの描画サイズの取得ではなく、下地の塗りつぶし(白)についてです(下図参照)。

1013_strange_behavior.png
▲macOS 10.12(上)とmacOS 10.13GM(下)の本Scriptの実行結果。検証のために文字データを変更(途中の改行を減らしている)

macOS 10.13のRelease Build(Build 17A365)でも同様の結果になりました。macOS 10.10で実験したら10.12と同様の結果に。何か(トンでもない場所の)仕様が変わったのだろうか?

→ macOS 10.13のバグでした。対応版を掲載しています

AppleScript名:書式つきテキストを組み立ててサイズを取得して画像書き出し v2
– Created 2017-09-25 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4843

property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSBezierPath : a reference to current application’s NSBezierPath
property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName
property NSFont : a reference to current application’s NSFont
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName
property NSImage : a reference to current application’s NSImage
property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName
property NSString : a reference to current application’s NSString
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSColor : a reference to current application’s NSColor

set outPath to “~/Desktop/test9999.png”
set fillColor to NSColor’s whiteColor –塗り色
set aFontSize to 48
set aString to “Takaaki” & return & “Naganoya” & return & “長野谷” & return & “隆昌”

set anAssrStr to makeRTFfromParameters(aString, “HiraMinProN-W3″, aFontSize, -2, (aFontSize * 1.5)) of me
set aSize to anAssrStr’s |size|()
–>  {width:408.0, height:187.2}

set attrStrWidth to width of aSize
set attrStrHeight to height of aSize

set {xPos, yPos} to {0, 0}

–下地の画像を作成
set tmpImg1 to makeImageWithFilledColor(attrStrWidth, attrStrHeight, fillColor) of me

–下地の画像の上にAttributed Stringを描画
set tmpImg2 to drawAttributedStringsOnImage(tmpImg1, anAssrStr, xPos, yPos) of me

–PNG形式でファイルに保存
set aRes to saveImageRepAtPathAsPNG(tmpImg2, outPath) of me

–画像のうえに指定のスタイル付きテキストを描画して画像を返す
on drawAttributedStringsOnImage(anImage, anAssrStr, xPos, yPos)
  anImage’s lockFocus()
  
anAssrStr’s drawAtPoint:(current application’s NSMakePoint(xPos, yPos))
  
anImage’s unlockFocus()
  
return anImage
end drawAttributedStringsOnImage

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real)
  –Font
  
set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
  
set aKey1 to (NSFontAttributeName)
  
  
–Color
  
set aVal2 to NSColor’s blackColor()
  
set aKey2 to (NSForegroundColorAttributeName)
  
  
–Kerning
  
set aVal3 to aKerning
  
set akey3 to (NSKernAttributeName)
  
  
–Underline
  
set aVal4 to 0
  
set akey4 to (NSUnderlineStyleAttributeName)
  
  
–Ligature
  
set aVal5 to 2 –all ligature ON
  
set akey5 to (NSLigatureAttributeName)
  
  
–Paragraph space
  
set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init()
  
aParagraphStyle’s setMinimumLineHeight:(aLineSpacing)
  
aParagraphStyle’s setMaximumLineHeight:(aLineSpacing)
  
set akey7 to (NSParagraphStyleAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey7}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aParagraphStyle}
  
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
end makeRTFfromParameters

–指定サイズの画像を作成し、背景を指定色で塗る
on makeImageWithFilledColor(aWidth, aHeight, fillColor)
  set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
  
anImage’s lockFocus()
  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  
fillColor’s |set|()
  
theNSBezierPath’s fill()
  
anImage’s unlockFocus()
  
  
return anImage
end makeImageWithFilledColor

–画像を指定パスにPNG形式で保存
on saveImageRepAtPathAsPNG(anImage, outPath)
  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:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes
end saveImageRepAtPathAsPNG

★Click Here to Open This Script 

2017/09/06 ツイ4のページで新規連載マンガの画像を取得してPDF化(新規連載のPDF化)v3

Safariで表示中のWebマンガサイト「ツイ4」(更新情報をTwitterに投稿)のマンガを全エピソードダウンロードしてPDFにまとめるAppleScriptです。

実行にあたってはShane StanleyのAppleScript Libraries「BridgePlus」のインストールを必要とします(~/ibrary/Script Librariesフォルダに入れるだけ)。

実行開始時にはSafariでツイ4の特定のマンガのページをオープンしている必要があります。

tui4.png

Safariの最前面のウィンドウからURLやTitle、リンクされている画像の詳細情報を取得し、条件チェックなどを行なったのちに詳細なデータの抽出を行います。

次に、PDFの保存先を選択するダイアログを表示。このさい、デフォルトの保存先を「ピクチャ」フォルダ、ファイル名をマンガのタイトルに指定。

ページにリンクされていた画像(ツイではファイル名はシーケンシャル番号)から番号の情報だけを抽出して最大値、最小値を計算。この範囲で画像のダウンロード、PDFへの追記を行います。ただし、実運用してみたところ、Safariからすべての画像を取得できないようで(非同期表示しているようなので)、とりあえず1〜9999までの番号の画像を順次ダウンロードし、画像が存在しなければ処理を終了しています。

画像をダウンロードするたびにPDFに追記していますが、このあたりは途中でエラーが出て停止してもそれまでの処理内容が保存されることを意図してのことです。SSD搭載機では問題のない処理ですが、HDD搭載機では若干遅く感じるかもしれません(もはやHDD搭載機が身の回りにないので不明)。

これまでは、マンガの新規連載がはじまるとcurlコマンドで画像をダウンロードしてPDFに連結する作業を手で行なっていたのですが(誰も頼んでねえよ)、新規連載が増えたので自動化してみました。それでもありあわせの部品を組み合わせただけなので、それほど手間はかかっていません。

本Scriptとは別に更新された差分をPDFに連結するAppleScriptを作って日々実行し、大きな画面でブラウズするのに役立てています。割とこういう、ごくごく私的なScriptで野心的な処理を先行してテストしているものです。

AppleScript名:ツイ4のページで新規連載マンガの画像を取得してPDF化(新規連載のPDF化)v3
– Created 2016-09-05 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “QuartzCore”
use BridgePlus : script “BridgePlus”
–http://piyocast.com/as/archives/4808

property SMSForder : a reference to current application’s SMSForder
property |NSURL| : a reference to current application’s |NSURL|
property NSURLRequest : a reference to current application’s NSURLRequest
property NSURLConnection : a reference to current application’s NSURLConnection
property NSArray : a reference to current application’s NSArray
property NSFileManager : a reference to current application’s NSFileManager
property NSNumberFormatter : a reference to current application’s NSNumberFormatter
property NSPredicate : a reference to current application’s NSPredicate
property PDFPage : a reference to current application’s PDFPage
property PDFDocument : a reference to current application’s PDFDocument
property NSURLRequestUseProtocolCachePolicy : a reference to current application’s NSURLRequestUseProtocolCachePolicy
property NSNumberFormatterPadBeforePrefix : a reference to current application’s NSNumberFormatterPadBeforePrefix
property NSImage : a reference to current application’s NSImage
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSNumber : a reference to current application’s NSNumber
property NSRegularExpressionDotMatchesLineSeparators : a reference to current application’s NSRegularExpressionDotMatchesLineSeparators
property NSRegularExpressionAnchorsMatchLines : a reference to current application’s NSRegularExpressionAnchorsMatchLines
property NSRegularExpression : a reference to current application’s NSRegularExpression
property NSString : a reference to current application’s NSString

property theTargetSite : “http://sai-zen-sen.jp/”

tell application “Safari”
  if (count every document) = 0 then
    display notification “Safari does not open web page”
    
return
  end if
  
  
set docTitle to (do JavaScript “document.title” in front document) –Title
  
  
tell front document –URL
    set aURL to URL
  end tell
end tell

if aURL does not start with theTargetSite then
  display notification “This site is not the target”
  
return
end if

–Safariの最前面のウィンドウから画像リンクをすべて取得(Height, Width, URL)
set aList to getImageSizeAndURLOfFrontSafariDocument() of me

–取得した画像情報の2D Listをサイズで降順ソート
load framework –Force loading BridgePlus framework
set sortIndexes to {0, 1} –Key Item id: begin from 0
set sortOrders to {false, false}
set sortTypes to {“compare:”, “compare:”}
set resList to (current application’s SMSForder’s subarraysIn:(aList) sortedByIndexes:sortIndexes ascending:sortOrders sortTypes:sortTypes |error|:(missing value))

–画像が取得できなかったら処理終了
if (resList as list) = {} then
  display notification “There is no images on this page”
  
return –No Result
end if

–最大サイズの画像情報を取得する(おそらくマンガ)
set {maxHeight, maxWidth, maxURL} to contents of first item of (resList as list)

set aNSURL to |NSURL|’s URLWithString:maxURL
set aNSURLfilename to (aNSURL’s lastPathComponent())
set aNSURLpure to aNSURL’s URLByDeletingLastPathComponent()
set aNSURLextension to aNSURLfilename’s pathExtension() as string
set aNSURLfilenameLen to (aNSURLfilename’s stringByDeletingPathExtension())’s |length|() as integer –画像ファイル名から拡張子を除去した部分の文字列長

–画像情報リストを画像サイズで抽出
set maxHeightStr to (maxHeight as integer) as string
set maxWidthStr to (maxWidth as integer) as string
set thePred to NSPredicate’s predicateWithFormat:(“(self[0] == “ & maxHeightStr & “) AND (self[1] == “ & maxWidthStr & “)”)
set bArray to (resList’s filteredArrayUsingPredicate:thePred) as list

–URLからファイル名の数値部分のみ抽出
set imageArray to current application’s NSMutableArray’s new()
repeat with i in bArray
  set j to contents of last item of i –(Image URL)
  
set aTmpURL to (|NSURL|’s URLWithString:j)
  
set aTmpfilename to (aTmpURL’s lastPathComponent()) as string
  
set numStr to first item of (my findPattern:(“^\\d{1,” & (aNSURLfilenameLen as string) & “}”) inString:aTmpfilename)
  
set jj2 to (SMSForder’s transformedFrom:numStr ICUTransform:“Fullwidth-Halfwidth” inverse:false) as integer
  (
imageArray’s addObject:jj2)
end repeat

–ファイル名から抽出した数値の最小値と最大値を求める。ただ、実運用したらWeb側から画像をすべて取得されない(非同期読み込みを行なっているらしい)ケースがあったため、ここの値は参考値程度にしか使えなかった
set maxRes to (imageArray’s valueForKeyPath:“@max.self”)’s intValue() –最大値
set minRes to (imageArray’s valueForKeyPath:“@min.self”)’s intValue() –最小値
log {minRes, maxRes}

–PDFのファイル名と場所をユーザーに確認
set pdfFile to (choose file name with prompt “Select PDF Name & Location” default location (path to pictures folder) default name (docTitle & “.pdf”))
set pdfFilePOSIX to POSIX path of pdfFile
set newFilePath to current application’s NSString’s stringWithString:pdfFilePOSIX

–Make Blank PDF
set aPDFdoc to PDFDocument’s alloc()’s init()

–Download each image and append to blank PDF
set insCount to 1 –画像ダウンロード用のページ数(Loop Counter)とPDF連結用のページ番号(insCount)を分離

–repeat with i from minRes as integer to maxRes as integer
repeat with i from 1 to 9999
  –URL部品の連結
  
set aFILENAME to numToZeroPaddingStr(i, aNSURLfilenameLen, “0″) of me
  
set aFULLURL to (aNSURLpure’s absoluteString() as string) & (aFILENAME as string) & “.” & (aNSURLextension as string)
  
set aURL to (|NSURL|’s URLWithString:aFULLURL)
  
  
–URL(画像)をダウンロード
  
set {uRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me
  
  
if uRes = true then
    display notification “Episode “ & (i as string) & ” exists…”
    
set bImage to (NSImage’s alloc()’s initWithData:aData)
    (
aPDFdoc’s insertPage:(PDFPage’s alloc()’s initWithImage:bImage) atIndex:(insCount - 1))
    (
aPDFdoc’s writeToFile:newFilePath) –1Page更新するたびにファイル保存
    
set changedF to true –PDFにページが追記されたことを検出
  else
    display notification “No more new episode….”
    
exit repeat
  end if
  
  
set insCount to insCount + 1
end repeat

–FinderコメントにURLを記入
tell application “Finder”
  set comment of (pdfFile as alias) to (aNSURLpure’s absoluteString() as string)
end tell

–生成したPDFをオープン。ビューワー経由ではなくFinder経由でopen命令を送って表示
tell application “Finder”
  open (pdfFile as alias)
end tell
–ここで処理終了

—————

on getImageSizeAndURLOfFrontSafariDocument()
  set aList to {}
  
  
tell application “Safari”
    if its running then
      if (count every document) = 0 then return {}
      
set aRes to (do JavaScript “document.images.length” in front document)
      
      
repeat with i from 0 to (aRes - 1)
        set aHeight to do JavaScript ((“document.images[” & i as string) & “].height”) in front document
        
set aWidth to do JavaScript ((“document.images[” & i as string) & “].width”) in front document
        
set aSRC to do JavaScript ((“document.images[” & i as string) & “].src”) in front document
        
set the end of aList to {aHeight, aWidth, aSRC}
      end repeat
    end if
  end tell
  
  
return aList
end getImageSizeAndURLOfFrontSafariDocument

on findPattern:thePattern inString:theString
  set theOptions to ((NSRegularExpressionDotMatchesLineSeparators) as integer) + ((NSRegularExpressionAnchorsMatchLines) as integer)
  
set theRegEx to NSRegularExpression’s regularExpressionWithPattern:thePattern options:theOptions |error|:(missing value)
  
set theFinds to theRegEx’s matchesInString:theString options:0 range:{location:0, |length|:length of theString}
  
set theFinds to theFinds as list
  
set theResult to {}
  
set theNSString to NSString’s stringWithString:theString
  
  
repeat with i in theFinds
    set theRange to (contents of i)’s range()
    
set end of theResult to (theNSString’s substringWithRange:theRange) as string
  end repeat
  
return theResult
end findPattern:inString:

–1D List(文字)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
on sort1DList:theList ascOrder:aBool
  set aDdesc to NSSortDescriptor’s sortDescriptorWithKey:“self” ascending:aBool selector:“localizedCaseInsensitiveCompare:”
  
set theArray to NSArray’s arrayWithArray:theList
  
return (theArray’s sortedArrayUsingDescriptors:{aDdesc}) as list
end sort1DList:ascOrder:

–整数の値に指定桁数ゼロパディングして文字列で返す
on numToZeroPaddingStr(aNum as integer, aDigit as integer, paddingChar as text)
  set aNumForm to NSNumberFormatter’s alloc()’s init()
  
aNumForm’s setPaddingPosition:(NSNumberFormatterPadBeforePrefix)
  
aNumForm’s setPaddingCharacter:paddingChar
  
aNumForm’s setMinimumIntegerDigits:aDigit
  
  
set bNum to NSNumber’s numberWithInt:aNum
  
set aStr to aNumForm’s stringFromNumber:bNum
  
  
return aStr as text
end numToZeroPaddingStr

– 指定URLにファイル(画像など)が存在するかチェック
–> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)}
on checkURLResourceExistence(aURL, timeOutSec as real)
  set aRequest to (NSURLRequest’s requestWithURL:aURL cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec)
  
set aRes to (NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value))
  
set dRes to (first item of (aRes as list))
  
set bRes to (second item of (aRes as list))
  
if bRes is not equal to missing value then
    set hRes to (bRes’s allHeaderFields())
    
set aResCode to (bRes’s statusCode()) as integer
  else
    set hRes to {}
    
set aResCode to 404
  end if
  
return {(aResCode = 200), hRes, dRes}
end checkURLResourceExistence

–指定PDFのページ数をかぞえる(10.9対応。普通にPDFpageから取得)
–返り値:PDFファイルのページ数(整数値)
on pdfPageCount(aFile)
  set aFile to POSIX path of aFile
  
set theURL to |NSURL|’s fileURLWithPath:aFile
  
set aPDFdoc to PDFDocument’s alloc()’s initWithURL:theURL
  
set aRes to aPDFdoc’s pageCount()
  
return aRes as integer
end pdfPageCount

★Click Here to Open This Script 

2017/08/22 CIFilterで画像切り抜き

CIFilterで画像の切り抜きを行うAppleScriptです。指定画像と同一階層のフォルダにUUID.pngの切り抜き画像を作成します。

Cocoaでの画像切り抜きは、

NSBitmapImageRepで切り抜き元画像の指定範囲のBitmapを取得して、新規NSBitmapImageRepに描画して結果を取得

というのが常識的なやり方のようですが、CIFilterの機能を用いて切り抜きできることを知ったので、比較のために実行してみました。

crop100images.png

結局、CIFilterの方が20倍ぐらい遅かったので、NSBitmapImageRepを使うやり方で問題ないことがわかりました。NSImageを100回指定範囲で切り抜くのに、NSBitmapImageRepで0.10950499773秒(1回あたり0.001秒)、このCIFilter経由だと1.957534968853秒(1回あたり0.02秒)でした(@MacBook Pro Retina 2012 Core i7 2.66GHz)。

もしかしたら、最近のGPU性能が向上したマシンだとこの差が小さくなるのかもしれません(CPU性能はたいして向上していない一方で、GPU性能は大きく向上しているはずなので)。

AppleScript名:CIFilterで画像切り抜き
– Created 2017-08-22 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”
–http://piyocast.com/as/archives/4788

property CIFilter : a reference to current application’s CIFilter
property CIVector : a reference to current application’s CIVector
property CIImage : a reference to current application’s CIImage
property NSString : a reference to current application’s NSString
property NSUUID : a reference to current application’s NSUUID
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSImage : a reference to current application’s NSImage
property |NSURL| : a reference to current application’s |NSURL|

–画像を選択
set aPath to POSIX path of (choose file of type {“public.image”})

set aNSImage to NSImage’s alloc()’s initWithContentsOfFile:aPath
set aSize to aNSImage’s |size|()
set aWidth to aSize’s width()
set aHeight to aSize’s height()

–Crop Image by CIFilter
set cropRes to cropNSImageWithCIFilter(aNSImage, 0, (aHeight - 100), 100, 100) of me

–Save as PNG
set fRes to retUUIDfilePath(aPath, “png”) of me
set sRes to saveNSImageAtPathAsPNG(cropRes, fRes) of me

–NSImageをCIImageに変換してCIfilterを実行
on cropNSImageWithCIFilter(aNSImage, x1, y1, xWidth, yHeight)
  set aCIImage to convNSImageToCIimage(aNSImage) of me
  
set aFilter to CIFilter’s filterWithName:“CICrop”
  
set aCIVector to CIVector’s vectorWithX:x1 Y:y1 Z:xWidth W:yHeight
  
  
aFilter’s setDefaults()
  
aFilter’s setValue:aCIImage forKey:“inputImage”
  
aFilter’s setValue:aCIVector forKey:“inputRectangle”
  
  
set filteredImage to (aFilter’s outputImage)
  
set newNSImage to convCIimageToNSImage(filteredImage) of me
  
  
return newNSImage
end cropNSImageWithCIFilter

on convCIimageToNSImage(aCIImage)
  set aRep to NSBitmapImageRep’s alloc()’s initWithCIImage:aCIImage
  
set tmpSize to aRep’s |size|()
  
set newImg to NSImage’s alloc()’s initWithSize:tmpSize
  
newImg’s addRepresentation:aRep
  
return newImg
end convCIimageToNSImage

on convNSImageToCIimage(aNSImage)
  set tiffDat to aNSImage’s TIFFRepresentation()
  
set aRep to NSBitmapImageRep’s imageRepWithData:tiffDat
  
set newImg to CIImage’s alloc()’s initWithBitmapImageRep:aRep
  
return newImg
end convNSImageToCIimage

on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  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:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/08/21 画像の重ね合わせ

背景画像の上に指定画像を重ね合わせるAppleScriptです。

画像の重ね合わせは割と必要な場合が多い処理です。

一番必要なのは、CIFilterで画像の一部にフィルタリング処理を行うとき、特定矩形内にのみフィルタ処理するようになっていないので、処理対象部分の切り抜きを行なっておいて、切り抜いた部分に対してフィルタ処理を行い、元画像に重ね合わせるようなケースでしょうか。

Photoshop上だと造作もない選択範囲へのフィルタ実行ですが、OSの機能を用いてゼロから作ると、やや苦労させられるところです。ただ、Photoshopは並列処理に使えないので、こうした部品でフィルタ処理を行うことになることでしょう。

54519d9c-d338-4327-8703-98c21e8823ff.png
▲背景画像の上に指定画像を重ね合わせた処理結果

AppleScript名:画像の重ね合わせ
– Created 2017-08-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4785

property NSString : a reference to current application’s NSString
property NSUUID : a reference to current application’s NSUUID
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSImage : a reference to current application’s NSImage
property |NSURL| : a reference to current application’s |NSURL|

set aRect to {0, 0, 100, 100} –x1,y1,x-width, y-height

–Background Image
set aFile to POSIX path of (choose file with prompt “Choose background image”)
set aURL to |NSURL|’s fileURLWithPath:aFile
set aImage to NSImage’s alloc()’s initWithContentsOfURL:aURL

–Compose Image
set bFile to POSIX path of (choose file with prompt “Choose Overlay image”)
set bURL to |NSURL|’s fileURLWithPath:bFile
set bImage to NSImage’s alloc()’s initWithContentsOfURL:bURL

–Compose Two Images
set nImage to composeImage(aImage, bImage, aRect) of me

–Save as PNG
set fRes to retUUIDfilePath(aFile, “png”) of me
set sRes to saveNSImageAtPathAsPNG(nImage, fRes) of me

–2つのNSImageを重ね合わせ合成してNSImageで返す
on composeImage(backImage, composeImage, aTargerRect)
  set newImage to NSImage’s alloc()’s initWithSize:(backImage’s |size|())
  
  
copy aTargerRect to {x1, y1, x2, y2}
  
set bRect to current application’s NSMakeRect(x1, y1, x2, y2)
  
  
newImage’s lockFocus()
  
  
set newImageRect to current application’s CGRectZero
  
set newImageRect’s |size| to (newImage’s |size|)
  
  
backImage’s drawInRect:newImageRect
  
composeImage’s drawInRect:bRect
  
  
newImage’s unlockFocus()
  
return newImage
end composeImage

on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  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:(NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/07/30 ASOCで画像の破損チェック

Cocoaの機能を用いて画像の破損チェックを行うAppleScriptです。

これまでにも、OS環境の移り変わりとともに破損画像のチェックを行うサブルーチンを整備してきました。

→ 2014/04/30 破損画像チェック 10.9
→ 2009/03/31 破損画像チェック
→ 2008/04/17 JPEG画像の破損チェック

ただ、昔のものの方がチェック能力が高く、Cocoaの機能を利用したものは破損検出レベルはそれほど高くはありません(並列処理には向いている?)。Image Eventsを利用するものも破損検出的には同程度の機能なので、おしなべてこの程度の検出しかできていないわけですが・・・。

  Type 1:オープンできない
  Type 2:画像書き出し時にエラーになる
  Type 3:ファイルオープン時にアラートが出る

本ルーチンで検出できるのはType 1のオープンできない画像のみです。

サブルーチン中で画像破損のチェックを2回(画像のNSImageへの読み込み、NSImageの内容の妥当性チェック)行なっていますが、それらの呼称と上記のType 1〜3は名前が似ていいるだけで同一のものではありません。

AppleScript名:ASOCで画像の破損チェック
– Created 2016-08-24 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4752

set aPath to (choose file of type {“public.image”})
set aRes to confirmImage(aPath) of me

–画像の破損チェック(can not open画像はチェックOK) 破損時にはfalseを返す
on confirmImage(aPath)
  set aType to type identifier of (info for aPath)
  
set aPOSIX to POSIX path of aPath
  
  
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aPOSIX
  
if aImage = missing value then return {false, aType, 1}
  
  
set aRes to aImage’s isValid()
  
return {aRes, aType, 2}
end confirmImage

★Click Here to Open This Script 

2017/07/25 NSImageの垂直、水平反転

指定の画像を読み込んでNSImageにして、垂直反転、水平反転するAppleScriptです。

NSImageそのものを回転させるのはもんのすごく大変そうなので、反転だけしてみました。

piyowolf.png
▲オリジナル画像

flipimagevertically.png
▲垂直方向に反転した画像(flipImageVertically)

flipimagehorizontally.png
▲水平方向に反転した画像(flipImageHorizontally)

回転させるなら元画像よりひとまわり大きなNSImageViewを作ってNSImageを設定し、回転系のmethodでも呼び出して、透過部分を自動トリミングすればいいんじゃないか、などと思っています。

あるいは、NSAffineTransformで90度回転、270度回転の状態を作って、そのターゲットサイズの空白画像の上に重ね合わせるとか。とりあえず、参考にするObjective-CのプログラムをWeb上で探してはみるものの、NSImageそのものを回転させる記述例にはあまりお目にかかりません。

以上はあくまで「Cocoaの機能を直接利用した場合の話」であり、一般的な画像回転はOS標準装備のImageEventsを呼び出して手軽に行えます。

→ ImageEventsで画像回転(時計回りに90度)
→ ImageEventsで画像回転(反時計回りに90度)

AppleScript名:NSImageの垂直、水平反転
– Created 2017-07-25 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–https://stackoverflow.com/questions/10936590/flip-nsimage-on-both-axes
–http://piyocast.com/as/archives/4748

set aFile to POSIX path of (choose file of type {“public.image”} with prompt “Select an Image”)

set currentImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile
set imgRes to flipImageHorizontally(currentImage) of me
set fRes to retUUIDfilePath(aFile, “png”) of me
set sRes to saveNSImageAtPathAsPNG(imgRes, fRes) of me

–水平方向の画像反転
on flipImageHorizontally(anNSImage)
  set transform to current application’s NSAffineTransform’s transform()
  
set dimList to anNSImage’s |size|()
  
set flipList to {-1.0, 0.0, 0.0, 1.0, dimList’s width, 0.0}
  
set tmpImage to current application’s NSImage’s alloc()’s initWithSize:(dimList)
  
tmpImage’s lockFocus()
  
transform’s setTransformStruct:flipList
  
transform’s concat()
  
anNSImage’s drawAtPoint:(current application’s NSMakePoint(0, 0)) fromRect:(current application’s NSMakeRect(0, 0, dimList’s width, dimList’s height)) operation:(current application’s NSCompositeCopy) fraction:1.0
  
tmpImage’s unlockFocus()
  
return tmpImage
end flipImageHorizontally

–垂直方向の画像反転
on flipImageVertically(anNSImage)
  set transform to current application’s NSAffineTransform’s transform()
  
set dimList to anNSImage’s |size|()
  
set flipList to {1.0, 0.0, 0.0, -1.0, 0.0, dimList’s height}
  
set tmpImage to current application’s NSImage’s alloc()’s initWithSize:(dimList)
  
tmpImage’s lockFocus()
  
transform’s setTransformStruct:flipList
  
transform’s concat()
  
anNSImage’s drawAtPoint:(current application’s NSMakePoint(0, 0)) fromRect:(current application’s NSMakeRect(0, 0, dimList’s width, dimList’s height)) operation:(current application’s NSCompositeCopy) fraction:1.0
  
tmpImage’s unlockFocus()
  
return tmpImage
end flipImageVertically

on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (current application’s NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((current application’s NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/07/23 指定の画像をASCII ART化してTextEditでオープン v3

jp2aを利用して指定の画像を色付きHTML形式のアスキーアート化して出力し、HTMLをRTFに変換してTextEditでオープンしてフォントを変更するAppleScriptの改良版です。

指定のJPEG画像をアスキーアート化するjp2aは、Homebrew経由でインストールしてください。

asciiart_gc1_resized.png

画像種別をとくに問わないように対応してみました。ただし、PNG画像については背景が透過している場合には画像余白トリミングフレームワーク「KGPixelBoundsClipKit」を用いてトリミングし、JPEG画像に変換します。

最大の変更点は、TextEditに対して命令を投げてフォントを指定していたものから、NSMutableAttributedStringに対してCocoaの機能を利用してフォント種別を指定するように変更したところです(意外と翻訳元となるObjective-Cの記述例が見つからない)。

テストする際には、KGPixelBoundsClipKitフレームワークのバイナリを~/Library/Frameworksフォルダに入れてお試しください。

–> Download Framework Binary

AppleScript名:指定の画像をASCII ART化してTextEditでオープン v3
– Created 2017-07-23 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “KGPixelBoundsClipKit” –https://github.com/kgn/KGPixelBoundsClip
–http://piyocast.com/as/archives/4740

set targFontName to “Osaka-Mono” –”Courier New”

set aFile to choose file of type {“public.image”}
tell application “System Events”
  set aType to type identifier of aFile –get UTI
end tell

if aType is equal to “public.png” then
  –PNGの場合、画像の余白をトリミング(背景が透過している場合にかぎる)
  
set anImage to (current application’s NSImage’s alloc()’s initWithContentsOfFile:(POSIX path of aFile))
  
set bImage to anImage’s imageClippedToPixelBounds()
  
  
–トリミング結果をデスクトップにJPEG形式で保存
  
set aDesktopPath to (current application’s NSProcessInfo’s processInfo()’s environment()’s objectForKey:(“HOME”))’s stringByAppendingString:“/Desktop/”
  
set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.jpg”)
  
set fRes to saveNSImageAtPathAsJPG(bImage, savePath, 100) of me
  
set aaFile to (POSIX file (savePath as string)) as alias
  
else if aType is equal to “public.jpeg” then
  –JPEGの場合
  
copy aFile to aaFile
  
else
  –PNGとJPEG以外の場合には読み込んでJPEGに変換
  
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:(POSIX path of aFile)
  
set fRes to retUUIDfilePath(POSIX path of aFile, “jpg”) of me
  
set sRes to saveNSImageAtPathAsJPG(aImage, fRes, 100) of me
  
set aaFile to (POSIX file (fRes as string)) as alias
  
end if

–ASCII ARTに変換してHTMLとして出力
set htmlRes to jpegToAsciiArt(aaFile, 120) of me

–出力されたHTMLデータを評価してスタイル付きテキストに変換
set htmlData to current application’s NSString’s stringWithString:htmlRes
set keyList to {current application’s NSDocumentTypeDocumentAttribute, current application’s NSCharacterEncodingDocumentAttribute}
set valList to {current application’s NSHTMLTextDocumentType, current application’s NSUTF8StringEncoding}
set optDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList

set aStyledStr to current application’s NSMutableAttributedString’s alloc()’s initWithData:(htmlData’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)) options:optDict documentAttributes:(missing value) |error|:(missing value)

–フォント種別およびサイズを指定してみた
set aRange to current application’s NSMakeRange(0, aStyledStr’s |length|())
set aVal1 to current application’s NSFont’s fontWithName:targFontName |size|:11
aStyledStr’s beginEditing()
aStyledStr’s addAttribute:(current application’s NSFontAttributeName) value:aVal1 range:aRange
aStyledStr’s endEditing()

–スタイル付きテキストをRTFとしてデスクトップに保存
set targFol to POSIX path of (path to desktop)
set aUUID to current application’s NSUUID’s UUID()’s UUIDString() as text
set bRes to my saveStyledTextAsRTF(aUUID, targFol, aStyledStr) –PDFで書き出す
set newPath to targFol & aUUID & “.rtf”

–Macの画面(メインスクリーン)の高さを取得する
set dRec to ((current application’s NSScreen’s mainScreen())’s deviceDescription()’s NSDeviceSize) as record
set dHeight to (height of dRec) as integer

–保存したRTFをTextEditでオープンして等幅フォント設定して、Window横幅を変更
tell application “TextEdit”
  activate
  
open (POSIX file newPath) as alias
  
  
tell window 1
    set {x1, y1, x2, y2} to bounds
    
set bounds to {x1, y1, (x1 + 1024), dHeight}
  end tell
  
  
tell document 1
    save
  end tell
end tell

–指定ファイルパスと同一階層にファイル名をUUID、拡張子を指定したものを作成して返す
on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (current application’s NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((current application’s NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

–NSImageを指定パスにJPEG形式で保存
on saveNSImageAtPathAsJPG(anImage, outPath, qulityNum as real)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:qulityNum})
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsJPG

–与えられたファイルパスのJPEG画像をASCII ARTに変換して返す
on jpegToAsciiArt(anImageAlias, digitNum as integer)
  set sText to “/usr/local/bin/jp2a -f –html-raw –colors –width=” & (digitNum as string) & ” -i “ & quoted form of POSIX path of anImageAlias
  
set tRes to do shell script sText
  
return tRes
end jpegToAsciiArt

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName, targFol, aStyledString)
  set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“rtf”
  
  
return (bRTF’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsRTF

★Click Here to Open This Script 

2017/07/21 指定のPNG画像をASCII ART化してTextEditでオープン v2

jp2aを利用して指定のPNG画像を色付きHTML形式のアスキーアート化して出力し、HTMLをRTFに変換してTextEditでオープンしてフォントを変更するAppleScriptです。

指定のJPEG画像をアスキーアート化するjp2aは、Homebrew経由でインストールしてください。

asciiart4_resized.png

asciiart3_resized.png
▲このように縦長で余白の多い画像から、自動で余白部分をトリミングして処理

asciiart_z.png
▲左側はPNG画像の余白トリミング処理を行ったもの、右側はトリミング処理を行わなかったもの

アスキーアート化するにあたって、元画像の余白部分をトリミングできたほうが良好な結果が得られるため、処理対象をJPEG画像からPNG画像(背景透過)に変更し、以前に使った画像余白トリミングフレームワーク「KGPixelBoundsClipKit」を用いてトリミングしてJPEG画像に変換。

トリミングしたJPEG画像をjp2aでHTMLのアスキーアートに変換し、さらにHTMLをスタイル付きテキスト(NSAttributedString)に変換。

スタイル付きテキストをRTF(リッチテキストフォーマット)に変換してファイル出力。RTFになればTextEditで扱えるので、TextEditでオープンして本文のフォントを等幅フォント(Osaka-mono)に指定してウィンドウのサイズを変更しています。

テストする際には、KGPixelBoundsClipKitフレームワークのバイナリを~/Library/Frameworksフォルダに入れてお試しください。

–> Download Framework Binary

AppleScript名:指定のPNG画像をASCII ART化してTextEditでオープン v2
– Created 2017-07-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “KGPixelBoundsClipKit” –https://github.com/kgn/KGPixelBoundsClip
–http://piyocast.com/as/archives/4736

set aFile to choose file of type {“public.png”}

–PNG画像の余白をトリミング
set anImage to (current application’s NSImage’s alloc()’s initWithContentsOfFile:(POSIX path of aFile))
set bImage to anImage’s imageClippedToPixelBounds()

–トリミング結果をデスクトップにJPEG形式で保存
set aDesktopPath to (current application’s NSProcessInfo’s processInfo()’s environment()’s objectForKey:(“HOME”))’s stringByAppendingString:“/Desktop/”
set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.jpg”)
set fRes to saveNSImageAtPathAsJPG(bImage, savePath, 100) of me

–ASCII ARTに変換してHTMLとして出力
set anAlias to (POSIX file (savePath as string)) as alias
set htmlRes to jpegToAsciiArt(anAlias, 120) of me

–出力されたHTMLデータを評価してスタイル付きテキストに変換
set htmlData to current application’s NSString’s stringWithString:htmlRes
set keyList to {current application’s NSDocumentTypeDocumentAttribute, current application’s NSCharacterEncodingDocumentAttribute}
set valList to {current application’s NSHTMLTextDocumentType, current application’s NSUTF8StringEncoding}
set optDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
set aStyledStr to current application’s NSAttributedString’s alloc()’s initWithData:(htmlData’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)) options:optDict documentAttributes:(missing value) |error|:(missing value)

–スタイル付きテキストをRTFとしてデスクトップに保存
set targFol to POSIX path of (path to desktop)
set aUUID to current application’s NSUUID’s UUID()’s UUIDString() as text
set bRes to my saveStyledTextAsRTF(aUUID, targFol, aStyledStr) –PDFで書き出す
set newPath to targFol & aUUID & “.rtf”

–保存したRTFをTextEditでオープンして等幅フォント設定して、Window横幅を変更
tell application “TextEdit”
  activate
  
open (POSIX file newPath) as alias
  
  
tell text of document 1
    set font of every attribute run to “Osaka-Mono”
  end tell
  
  
tell window 1
    set {x1, y1, x2, y2} to bounds
    
set bounds to {x1, y1, (x1 + 800), y2}
  end tell
end tell

–NSImageを指定パスにJPEG形式で保存
on saveNSImageAtPathAsJPG(anImage, outPath, qulityNum as real)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:qulityNum})
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsJPG

–与えられたファイルパスのJPEG画像をASCII ARTに変換して返す
on jpegToAsciiArt(anImageAlias, digitNum as integer)
  set sText to “/usr/local/bin/jp2a -f –html-raw –colors –width=” & (digitNum as string) & ” -i “ & quoted form of POSIX path of anImageAlias
  
set tRes to do shell script sText
  
return tRes
end jpegToAsciiArt

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings to RTF
  
set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“rtf”
  
  
return (bRTF’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsRTF

★Click Here to Open This Script 

2017/07/16 ASOCでcolor popup buttonを作成

動的にWindow+View+popup buttonを作成し、色選択を行うpopup menuを作成するAppleScriptです。

color_popup.png

Script Editor上でControl-Command-Rと操作することで実行できます。アプレットとして保存して実行してもOKです。

color_popup2.png

いくつか候補がある色のうちからどれかを選ぶといった処理は割とあるのですが、色のプレビューを行うインタフェースはAppleScriptのデフォルトのコマンドでは用意されていないので、ちょっと作ってみました。

たとえば、テキストエディット上で資料の文章をチェックを行なっているような場合、見直す必要のある箇所に赤く色をつけておいて、赤くマークした箇所のみAppleScriptで抽出するとかいう処理は便利にやっています(ものすごく効率がいい)。赤以外でもマークした箇所を抽出するとかいったら、本Scriptのような部品を利用して「どの色でマークした箇所を抽出しようか」文章中の色付き部分を全部スキャンしたうえで色選択という処理ができるわけです。

Script EditorおよびASObjC Explorer 4上での実行は確認できていますが、Script Debugger 6.0.5 試用版ではクラッシュします。

1枚のみのWindowを作成する場合にはNSWindowControllerを用いる必要はないようですが、ためしにNSWindowControllerを省いたScriptも作って試してみたところ・・・安定性がやや損なわれるようでした。結局、NSWindowControllerがあったほうがよいのでは???

指定色でNSImageを作成してmenu itemに設定していますが、macOS 10.13ではこれが正方形でないとおもいどおりのサイズでメニューに表示されませんでした。

color_popup1013.png
▲本ScriptをmacOS 10.13で動かしたときのイメージ(10.12上で再現)

color_popup1013b.png
▲macOS 10.13上のpopup menu上で大きくColor部分を表示するときには、imageの縦横サイズを同じに?

→ macOS 10.13.0のバグの影響を受けていたことが判明。heightとwidthの記述順を入れ替えると想定どおりの動作をします

AppleScript名:ASOCでcolor popup buttonを作成
– Created 2017-07-15 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “Carbon” – AEInteractWithUser() is in Carbon
–http://piyocast.com/as/archives/4724

property windisp : false
property wController : false –いらなかったかも?

if current application’s AEInteractWithUser(-1, missing value, missing value) is not equal to 0 then return

set ap1List to {{65535, 0, 65535}, {0, 32896, 16448}, {0, 32896, 65535}, {19702, 31223, 40505}}

set aButtonMSG to “OK”
set aSliderValMSG to “Select Color”
set aVal to getPopupValues(ap1List, 65535, aButtonMSG, aSliderValMSG, 20) of me

on getPopupValues(ap1List, aColMax, aButtonMSG, aSliderValMSG, timeOutSecs)
  
  
set (my windisp) to true
  
  
set aView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 360, 100))
  
  
–Labelをつくる
  
set a1TF to current application’s NSTextField’s alloc()’s initWithFrame:(current application’s NSMakeRect(30, 60, 80, 20))
  
a1TF’s setEditable:false
  
a1TF’s setStringValue:“Color:”
  
a1TF’s setDrawsBackground:false
  
a1TF’s setBordered:false
  
  
–Ppopup Buttonをつくる
  
set a1Button to current application’s NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(80, 60, 200, 20)) pullsDown:false
  
a1Button’s removeAllItems()
  
  
set a1Menu to current application’s NSMenu’s alloc()’s init()
  
  
set iCount to 0
  
repeat with i in ap1List
    copy i to {r1, g1, b1}
    
    
set nsCol to makeNSColorFromRGBAval(r1, g1, b1, aColMax, aColMax) of me
    
set anImage to makeNSImageWithFilledWithColor(64, 16, nsCol) of me
    
    
set aTitle to “col_test_” & (iCount as string)
    
set aMenuItem to (current application’s NSMenuItem’s alloc()’s initWithTitle:aTitle action:“actionHandler:” keyEquivalent:“”)
    (
aMenuItem’s setImage:anImage)
    (
aMenuItem’s setEnabled:true)
    (
a1Menu’s addItem:aMenuItem)
    
    
set iCount to iCount + 1
  end repeat
  
  
a1Button’s setMenu:a1Menu
  
  
  
–Buttonをつくる
  
set bButton to (current application’s NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(80, 10, 140, 40)))
  
bButton’s setButtonType:(current application’s NSMomentaryLightButton)
  
bButton’s setBezelStyle:(current application’s NSRoundedBezelStyle)
  
bButton’s setTitle:aButtonMSG
  
bButton’s setTarget:me
  
bButton’s setAction:(“clicked:”)
  
bButton’s setKeyEquivalent:(return)
  
  
aView’s addSubview:a1TF
  
  
aView’s addSubview:a1Button
  
aView’s addSubview:bButton
  
aView’s setNeedsDisplay:true
  
  
–NSWindowControllerを作ってみた(いらない?)
  
set aWin to (my makeWinWithView(aView, 300, 100, aSliderValMSG))
  
  
set wController to current application’s NSWindowController’s alloc()
  
wController’s initWithWindow:aWin
  
  
wController’s showWindow:me
  
  
set aCount to timeOutSecs * 100
  
  
set hitF to false
  
repeat aCount times
    if (my windisp) = false then
      set hitF to true
      
exit repeat
    end if
    
delay 0.01
    
set aCount to aCount - 1
  end repeat
  
  
my closeWin:aWin
  
  
if hitF = true then
    set s1Val to a1Button’s titleOfSelectedItem() as string
  else
    set s1Val to false
  end if
  
  
return s1Val
  
end getPopupValues

on clicked:aSender
  set (my windisp) to false
end clicked:

–make Window for Display
on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle)
  set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {aWinWidth, aWinHeight}}
  
  
set aBacking to current application’s NSTitledWindowMask
  
  
set aDefer to current application’s NSBackingStoreBuffered
  
  
– Window
  
set aWin to current application’s NSWindow’s alloc()
  (
aWin’s initWithContentRect:aFrame styleMask:aBacking backing:aDefer defer:false screen:aScreen)
  
–aWin’s setBackgroundColor:(current application’s NSColor’s whiteColor())
  
  
aWin’s setTitle:aTitle
  
aWin’s setDelegate:me
  
aWin’s setDisplaysWhenScreenProfileChanges:true
  
aWin’s setHasShadow:true
  
aWin’s setIgnoresMouseEvents:false
  
aWin’s setLevel:(current application’s NSNormalWindowLevel)
  
aWin’s setOpaque:false
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
–aWin’s makeKeyAndOrderFront:(me)
  
  
aWin’s setContentView:aView
  
  
return aWin
  
end makeWinWithView

–close win
on closeWin:aWindow
  repeat with n from 10 to 1 by -1
    (aWindow’s setAlphaValue:n / 10)
    
delay 0.02
  end repeat
  
aWindow’s |close|()
end closeWin:

–Popup Action Handler
on actionHandler:sender
  set aTag to tag of sender as integer
  
set aTitle to title of sender as string
end actionHandler:

on makeNSColorFromRGBAval(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer, aMaxVal as integer)
  set aRedCocoa to (redValue / aMaxVal) as real
  
set aGreenCocoa to (greenValue / aMaxVal) as real
  
set aBlueCocoa to (blueValue / aMaxVal) as real
  
set aAlphaCocoa to (alphaValue / aMaxVal) as real
  
set aColor to current application’s NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
  
return aColor
end makeNSColorFromRGBAval

–指定サイズの画像を作成し、指定色で塗ってファイル書き出し
on makeNSImageWithFilledWithColor(aWidth, aHeight, fillColor)
  set anImage to current application’s NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
anImage’s lockFocus()
  

  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to current application’s NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  

  
fillColor’s |set|() –色設定
  
theNSBezierPath’s fill() –ぬりつぶし
  

  
anImage’s unlockFocus()
  

  
return anImage
end makeNSImageWithFilledWithColor

★Click Here to Open This Script 

2017/04/27 単色画像(アルファ値必要)に色を指定して塗りつぶし

背景を透明(アルファ値指定)にした単色の画像に、指定の色を指定して塗りつぶしを行うAppleScriptです。

input_and_output.png

単色の画像を作成して、指定画像との合成を行い「塗りつぶし」の状態を作り出すものです。Photoshopを使えば、あっという間にできてしまう処理ですが、Photoshopは並列処理に使えないのでこうした部品を作っておいたものです。

AppleScript名:単色画像(アルファ値必要)に色を指定して塗りつぶし
– Created 2017-04-24 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “QuartzCore”
–http://piyocast.com/as/archives/4615

set aFile to POSIX path of (choose file of type “public.image”)
set aColor to makeNSColorFromRGBA255val(0, 0, 255, 255) of me
set aColoredImage to fillColorWithImage(aFile, aColor) of me

set aDesktopPath to ((current application’s NSProcessInfo’s processInfo()’s environment()’s objectForKey:(“HOME”))’s stringByAppendingString:“/Desktop/”)
set savePath to (aDesktopPath’s stringByAppendingString:((current application’s NSString’s stringWithString:“testOverlay”)’s stringByAppendingString:“.png”))
set fRes to saveNSImageAtPathAsPNG(aColoredImage, savePath) of me

on fillColorWithImage(aFile, aColor)
  set anImage to (current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile)
  
set aSize to anImage’s |size|()
  
set aWidth to (aSize’s width)
  
set aHeight to (aSize’s height)
  
set colordImage to makeNSImageWithFilledWithColor(aWidth, aHeight, aColor) of me
  
colordImage’s lockFocus()
  
anImage’s drawAtPoint:{0, 0} fromRect:(current application’s NSZeroRect) operation:(current application’s NSCompositeDestinationIn) fraction:1.0
  
colordImage’s unlockFocus()
  
return colordImage
end fillColorWithImage

–指定サイズの画像を作成し、指定色で塗ってファイル書き出し
on makeNSImageWithFilledWithColor(aWidth, aHeight, fillColor)
  set anImage to current application’s NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
  
anImage’s lockFocus()
  

  
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
  
set theNSBezierPath to current application’s NSBezierPath’s bezierPath
  
theNSBezierPath’s appendBezierPathWithRect:theRect
  

  
fillColor’s |set|() –色設定
  
theNSBezierPath’s fill() –ぬりつぶし
  

  
anImage’s unlockFocus()
  

  
return anImage
end makeNSImageWithFilledWithColor

on makeNSColorFromRGBA255val(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer)
  set aRedCocoa to (redValue / 255) as real
  
set aGreenCocoa to (greenValue / 255) as real
  
set aBlueCocoa to (blueValue / 255) as real
  
set aAlphaCocoa to (alphaValue / 255) as real
  
set aColor to current application’s NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
  
return aColor
end makeNSColorFromRGBA255val

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –成功ならtrue、失敗ならfalseが返る
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/04/26 指定画像の余白の自動トリミング

オープンソースのKGPixelBoundsClip(By David Keegan)をフレームワーク化した「KGPixelBoundsClipKit」を呼び出して指定画像を自動でトリミングするAppleScriptです。

OS X 10.10以降用にビルドしたフレームワークのバイナリを用意しておきました。興味のある方は自己責任で~/Library/Frameworksフォルダに入れてお試しください。

–> Download Framework Binary

指定画像(背景を透明に指定したPNGで実行)を自動トリミングして、デスクトップに結果を書き出します。

Photoshopにも同様の機能があったような記憶がありますが、フレームワーク経由で実行することで並列処理を行いやすい部品を作っておくことが目的です。

original_and_trimed.png

AppleScript名:指定画像の余白の自動トリミング
– Created 2017-04-26 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “KGPixelBoundsClipKit” –https://github.com/kgn/KGPixelBoundsClip
–http://piyocast.com/as/archives/4611

set aFile to POSIX path of (choose file of type {“public.image”})
set anImage to (current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile)

set bImage to anImage’s imageClippedToPixelBounds()

set aDesktopPath to (current application’s NSProcessInfo’s processInfo()’s environment()’s objectForKey:(“HOME”))’s stringByAppendingString:“/Desktop/”
set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.png”)
set fRes to saveNSImageAtPathAsPNG(bImage, savePath) of me

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/04/24 画像中の色の置き換え

オープンソースのNSImage-replace-color(By braginets)をフレームワーク化した「replaceColorKit」を呼び出して指定画像中の指定色を置き換えるAppleScriptです。

OS X 10.10以降用にビルドしたフレームワークのバイナリを用意しておきました。興味のある方は自己責任で~/Library/Frameworksフォルダに入れてお試しください。

–> Download Framework Binary

piyo_wolf.png
▲Original

piyo_gray_02.png
▲Color Replaced Image (Yellow->Gray)

rep_doc.png

R, G, Bのグラデーション画像を作成して、色の置き換えをテストしてみたところ、置き換え色がR:255やB:255の色の場合に置き換え色がやや変わってしまうという傾向があるようです。

specificated_sampledata.png

rep_color_diff.png

AppleScript名:画像中の色の置き換え
– Created 2017-04-23 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "replaceColorKit" –https://github.com/braginets/NSImage-replace-color
use framework "AppKit"
–http://piyocast.com/as/archives/4604

set aThreshold to 0.2

set aFile to POSIX path of (choose file of type {"public.image"})
set anImage to (current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile)

set aColor to makeNSColorFromRGBA255val(246, 253, 0, 255) of me
set bColor to makeNSColorFromRGBA255val(154, 154, 154, 255) of me

set bImage to (anImage’s replaceColor:aColor withColor:bColor withThreshold:aThreshold)

set aDesktopPath to ((current application’s NSProcessInfo’s processInfo()’s environment()’s objectForKey:("HOME"))’s stringByAppendingString:"/Desktop/")
set savePath to (aDesktopPath’s stringByAppendingString:((current application’s NSString’s stringWithString:(aThreshold as string))’s stringByAppendingString:".png"))
set fRes to saveNSImageAtPathAsPNG(bImage, savePath) of me

–0〜255の数値でNSColorを作成する
on makeNSColorFromRGBA255val(redValue as integer, greenValue as integer, blueValue as integer, alphaValue as integer)
  set aRedCocoa to (redValue / 255) as real
  
set aGreenCocoa to (greenValue / 255) as real
  
set aBlueCocoa to (blueValue / 255) as real
  
set aAlphaCocoa to (alphaValue / 255) as real
  
set aColor to current application’s NSColor’s colorWithCalibratedRed:aRedCocoa green:aGreenCocoa blue:aBlueCocoa alpha:aAlphaCocoa
  
return aColor
end makeNSColorFromRGBA255val

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/03/21 CoreImage(CIFilter)で指定画像を2階調ポスタライズ v2

CoreImageのCIFilterを用いて、指定の画像を2階調でポスタライズするAppleScriptです。

CPUImageにも同様のポスタライズ用のフィルタが存在しているのですが、パラメータを指定してもうまく効かなかったので、CIFilterを使ってみました。

6ba2129c-12c5-42bf-b1a6-48dc883a97ec.png
▲実行前

81421d35-72aa-4d9d-9e6b-e2c59f9c9109.png
▲実行後

AppleScript名:CoreImageで指定画像を2階調ポスタライズ v2
– Created 2017-03-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “QuartzCore”
–http://piyocast.com/as/archives/4541

–画像を選択
set aPath to POSIX path of (choose file of type {“public.image”})
set aNSImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aPath

set imgRes to execCIFilterWithNSImage(aNSImage, “CIColorPosterize”) of me

set aDesktopPath to (current application’s NSProcessInfo’s processInfo()’s environment()’s objectForKey:(“HOME”))’s stringByAppendingString:“/Desktop/”
set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.png”)

set fRes to saveNSImageAtPathAsPNG(imgRes, savePath) of me

on convCIimageToNSImage(aCIImage)
  set aRep to current application’s NSBitmapImageRep’s alloc()’s initWithCIImage:aCIImage
  
set tmpSize to aRep’s |size|()
  
set newImg to current application’s NSImage’s alloc()’s initWithSize:tmpSize
  
newImg’s addRepresentation:aRep
  
return newImg
end convCIimageToNSImage

on convNSImageToCIimage(aNSImage)
  set tiffDat to aNSImage’s TIFFRepresentation()
  
set aRep to current application’s NSBitmapImageRep’s imageRepWithData:tiffDat
  
set newImg to current application’s CIImage’s alloc()’s initWithBitmapImageRep:aRep
  
return newImg
end convNSImageToCIimage

–NSImageをCIImageに変換してCIfilterを実行
on execCIFilterWithNSImage(aNSImage, aFilterName)
  set aCIImage to convNSImageToCIimage(aNSImage) of me
  
  
set aFilter to current application’s CIFilter’s filterWithName:aFilterName
  
aFilter’s setDefaults()
  
aFilter’s setValue:aCIImage forKey:“inputImage”
  
aFilter’s setValue:2 forKey:“inputLevels”
  
set aOutImage to aFilter’s valueForKey:“outputImage”
  
  
set newNSImage to convCIimageToNSImage(aOutImage) of me
  
return newNSImage
end execCIFilterWithNSImage

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –成功ならtrue、失敗ならfalseが返る
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/03/21 CIImageとNSImageの相互変換

CIImageとNSImageの相互変換を行うAppleScriptです。

ファイル入出力をはじめ、さまざまな処理を行う場合にはNSImageで指定するように各種ライブラリの入出力を統一するようにしています。そのため、CIFilterを利用するような場合でもNSImageで画像データを渡すようにしています。

CIFilterを実行するサブルーチン内では、CoreImageで画像データを扱うのでCIImageで画像を渡す必要があるためCIImageに変換してFilter処理を行い、その後にNSImageに変換して結果を返すようにしています。

似たような名前のオブジェクトとして「CGImage」(CoreGraphicsの)がありますが、これはAppleScript側からは手が出ないオブジェクトに見えます。少なくとも、自分はCGImageと他フォーマットとの変換についてはやり方はわかりません。

AppleScript名:CIImageとNSImageの相互変換
– Created 2017-03-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "QuartzCore"
–http://piyocast.com/as/archives/4540

–Get Computer Icon (NSImage)
set anImage to current application’s NSImage’s imageNamed:(current application’s NSImageNameComputer)

set aCIImage to convNSImageToCIimage(anImage) of me
–> (CIImage)

set bNSImage to convCIimageToNSImage(aCIImage) of me
–> (NSImage)

on convCIimageToNSImage(aCIImage)
  set aRep to current application’s NSBitmapImageRep’s alloc()’s initWithCIImage:aCIImage
  
set tmpSize to aRep’s |size|()
  
set newImg to current application’s NSImage’s alloc()’s initWithSize:tmpSize
  
newImg’s addRepresentation:aRep
  
return newImg
end convCIimageToNSImage

on convNSImageToCIimage(aNSImage)
  set tiffDat to aNSImage’s TIFFRepresentation()
  
set aRep to current application’s NSBitmapImageRep’s imageRepWithData:tiffDat
  
set newImg to current application’s CIImage’s alloc()’s initWithBitmapImageRep:aRep
  
return newImg
end convNSImageToCIimage

★Click Here to Open This Script 

2017/03/11 256×3のグラフ画像を縦方向に拡大する v2

GPUImage.frameworkの明度ヒストグラムの出力画像を加工するために作成したAppleScriptの改良版です。

256×3ドットの画像から、

6ed48d0a-5718-4562-9ad3-b7a63269678f.png

明度ヒストグラムのデータ部分である中央の256×1ドットのパターンを切り抜いて取得。そのパターンで256×90の空白の画像を塗りつぶして保存します。

53da8086-f585-4d45-9d4b-e5b9ceee7f03.png

最初のバージョンでは、バカていねいに元の画像の色情報を読み取って、その通りに新規画像に点で描画していました。そのため、処理に数秒(4秒ぐらい?)かかっていました。

本バージョンは、MacBook Pro Retina 2012(Core i7 2.66GHz)で0.008秒ぐらいでファイル書き込みも含めて終了します。

AppleScript名:256×3のグラフ画像を縦方向に拡大する v2
– Created 2017-03-11 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4522

set aHeight to 90
set aWidth to 256

set aPath to POSIX path of (choose file of type {“public.image”})
set anImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aPath

–256×1で切り抜き
set bImage to my cropNSImageBy:{0, 1, 256, 1} fromImage:anImage
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:(anImage’s TIFFRepresentation())

–256×90の画像を作成
set cImage to current application’s NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))

–256×1のパターンでぬりつぶし
set theRect to {{x:0, y:0}, {height:aHeight, width:aWidth}}
cImage’s lockFocus()
(
current application’s NSColor’s colorWithPatternImage:bImage)’s |set|()
current application’s NSBezierPath’s fillRect:theRect
cImage’s unlockFocus()

–PNG形式で保存
set aPath to (POSIX path of (path to desktop) & (current application’s NSUUID’s UUID())’s UUIDString() as string) & “.png”
saveNSImageAtPathAsPNG(cImage, aPath)

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –true/false
end saveNSImageAtPathAsPNG

–NSImageを指定の大きさでトリミング
on cropNSImageBy:{x1, y1, newWidth, newHeight} fromImage:theImage
  set theSize to (theImage’s |size|()) as record
  
set oldHeight to height of theSize
  
  
– transpose y value for Cocoa coordintates
  
set y1 to oldHeight - newHeight - y1
  
set newRect to {{x:x1, y:y1}, {width:newWidth, height:newHeight}}
  
theImage’s lockFocus()
  
set theRep to current application’s NSBitmapImageRep’s alloc()’s initWithFocusedViewRect:newRect
  
theImage’s unlockFocus()
  
  
set outImage to current application’s NSImage’s alloc()’s initWithSize:(theRep’s |size|())
  
outImage’s addRepresentation:theRep
  
  
return outImage
end cropNSImageBy:fromImage:

★Click Here to Open This Script 

2017/03/09 ASCIImageでPNG画像をデスクトップに作成する

オープンソースのプログラム「ASCIImage」(By Charles Parnot)を用いて、ASCII ARTからPNG画像を作成するAppleScriptです。AppleScriptからの呼び出しは、同プログラムをフレームワーク化した「asciiImageKit」を経由しています。

本AppleScriptのテストのためには、asciiImageKit.frameworkを~/Library/Frameworksフォルダに入れておく必要があります。バイナリを用意しておきましたので、自己責任でおためしください。

Download Binary (30KB)

ASCIImageは(どうして作者がこれを作ったのかが)とても不思議なプログラムで、画像描画を文字で(ASCII ARTっぽく)指定するとNSImageが得られます。NSImageが得られれば、あとはPNGなりJPEGなり好みの画像フォーマットで書き出しできます。

ascii1.png
▲shouldAntialias=falseでレンダリングした画像

ascii2.png
▲shouldAntialias=trueでレンダリングした画像

inv.png
▲自分でデータ作成をこころみてみたものの、思い通りに描画されなかったデータ。コツが必要なのか意外と難しい、、、、

AppleScript名:ASCIImageでPNG画像をデスクトップに作成する
– Created 2017-03-09 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “asciiImageKit” –https://github.com/cparnot/ASCIImage
use framework “AppKit”
–http://piyocast.com/as/archives/4517

set aColor to current application’s NSColor’s blackColor()

set aRep to {· · · 1 2 · · · · ·, ¬
  · · · A # # · · · ·, ¬
  
· · · · # # # · · ·, ¬
  
· · · · · # # # · ·, ¬
  
· · · · · · 9 # 3 ·, ¬
  
· · · · · · 8 # 4 ·, ¬
  
· · · · · # # # · ·, ¬
  
· · · · # # # · · ·, ¬
  
· · · 7 # # · · · ·, ¬
  
· · · 6 5 · · · · ·}

set anImage to current application’s NSImage’s imageWithASCIIRepresentation:aRep |color|:aColor shouldAntialias:false

set aPath to (POSIX path of (path to desktop) & (current application’s NSUUID’s UUID())’s UUIDString() as string) & “.png”
set fRes to saveNSImageAtPathAsPNG(anImage, aPath) of me

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –true/false
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/03/02 指定の画像が真っ白かどうか判定する

オープンソースのフレームワーク「GPUImage」(By Brad Larson)を利用して、指定の画像が真っ白かどうかを判定するAppleScriptです。指定画像が真っ白の場合にはtrueを、そうでない場合にはfalseを返します。

テストにあたっては、GPUImageフレームワークをXcodeでビルドして、~/Library/Frameworksフォルダに入れておいてください。

GPUImage.frameworkには特殊なフィルタが存在しており、その中で最もユニークなのが指定画像(NSImage)のヒストグラムを求めるものです。つまり、画像をフィルタ加工するのではなく、分析した結果を画像(NSImage)に出力します。

そのうちの「明度ヒストグラム」のフィルタ(?)を指定して、指定画像の明度分布を求めます(一瞬で)。明度分布のヒストグラムは、横256ドット・高さ3ドットの画像(NSImage)として出力されます。うち、中央の1ドットが左側が0(暗い=黒)右側が255(明るい=白)を表現しています。

white.png
▲GPUImage.frameworkで出力した明度ヒストグラム(真っ白な画像を処理した場合)。幅256ドット、高さ3ドットの画像(高さを90ドットに拡大)。右端(明度=255)のみ白く反応しており、他に明度分布は存在しないことが見て取れる

test2.png

test1.png
▲GPUImage.frameworkで出力した明度ヒストグラム(真っ白ではない画像を処理した場合の処理例)

つまり、画像が真っ白かどうかを判定するという、気が遠くなるほど重そうな画像処理が、わずか256箇所の色情報を調べるだけで、しかもGPUの機能を活用して一瞬で処理できることになります。しかも、AppleScriptで。

  1024×768@72DPIの画像=786,432ドット
  1920×1200@72DPIの画像=2,304,000ドット

これらを全部ループで色検出処理すると、相当の時間がかかるはずです。230万アイテム超のループ処理なんて想像したくもありません。

一応、テストのために、

  1024×768@72DPIの画像で、1ドットだけ黒くしたもの
  1920×1200@72DPIの画像で、1ドットだけ黒くしたもの

の2つを用意して、黒くした1ドットの存在を検出できるかテストしてみたところ、無事検出できました(しかも一瞬で)。

ただし、このことが4Kとか5Kの白い画像に1ドットだけ黒くした場合でも同様に検出できるかどうかは保証のかぎりではありません。

実際に利用するさいには事前にターゲットサイズの白い画像に1ドットだけ黒くして実験して検出可能かどうかを確認。検出できなかった場合には事前に解像度を落とす処理を行うなどの対応が必要です。

AppleScript名:指定の画像が真っ白かどうか判定する
– Created 2017-02-12 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “GPUImage”
–http://piyocast.com/as/archives/4492

set aFile to POSIX path of (choose file of type {“public.image”} with prompt “Select a Image to check it is white (or not) “)
set anNSImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile
set wRes to my detectAllWhite:anNSImage

–指定のNSImageが真っ白かどうかをチェック
on detectAllWhite:anNSImage
  
  
–明度ヒストグラム画像を取得
  
set imgRes to getHistogramFromImage(anNSImage, 4) of me
  
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:(imgRes’s TIFFRepresentation())
  
  
–白い画像のデータパターン
  
set aWhitePattern to current application’s NSMutableArray’s arrayWithArray:{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}
  
  
set resArray to current application’s NSMutableArray’s alloc()’s init()
  
repeat with i from 0 to 255
    set origColor to (aRawimg’s colorAtX:i y:1)
    
set srgbColSpace to current application’s NSColorSpace’s genericGrayColorSpace
    
set aColor to (origColor’s colorUsingColorSpace:srgbColSpace)
    
set aWhite to aColor’s whiteComponent()
    (
resArray’s addObject:aWhite)
  end repeat
  
  
set aRes to (resArray’s isEqualTo:aWhitePattern) as boolean
  
return aRes
  
end detectAllWhite:

–指定のNSImageをGPUImage.frameworkで明度ヒストグラム化してNSImageで返す
on getHistogramFromImage(aNSImage, histogramType)
  set aFilter to current application’s GPUImageHistogramFilter’s alloc()’s initWithHistogramType:histogramType
  
set aProcImg to (aFilter’s imageByFilteringImage:aNSImage)
  
return aProcImg
end getHistogramFromImage

–NSImageをGPUImage.frameworkの指定フィルタで処理してNSImageを返す
on filterWithNSImage(aNSImage, filterName as string)
  set aClass to current application’s NSClassFromString(filterName)
  
set aImageFilter to aClass’s alloc()’s init()
  
set aProcImg to (aImageFilter’s imageByFilteringImage:aNSImage)
  
return aProcImg
end filterWithNSImage

★Click Here to Open This Script 

2017/02/05 GPUImageで画像にすべてのフィルタを実行してデスクトップにPNG形式で保存

オープンソースのフレームワーク「GPUImage」(By Brad Larson)を呼び出して、指定画像にGPUImageのすべてのフィルタを実行して、デスクトップにフィルタ名でPNGに保存するAppleScriptです。

テストにあたっては、GPUImageフレームワークをXcodeでビルドして、~/Library/Frameworksフォルダに入れておいてください。

ドキュメントによれば125種類ものフィルタを内蔵しているというGPUImageですが、どれがどのような処理を行ってくれるのかは、実際に呼び出してみないとわかりません。また、単に呼び出して画像にフィルタを実行しただけでは記述内容が不足しているというものもありそうです(パラメータを指定しないと意味がないケース、フィルタが仕様の都合で複数の画像を要求するものも)。

そこで、ヘッダーファイルからすべてのフィルタ名称を取り出して、ループで順次実行させてみました。デスクトップにフィルター名称でPNG画像を書き出します。

ヘッダーファイルに記載されていたフィルターとおぼしきものが145、うち実行可能だったものが100、エラーが45となりました。また、エラーは出なかったものの何らかのパラメータを指定しないとおそらく意味がない(オリジナル画像と変わらない)ものもありました。

samples_out.png

フィルタをallocしてinitした段階でエラーが出るものもあったり、エラーをキャッチできるまでに時間がかかるものもありましたが、with timedoutでタイムアウト時間を指定してもエラーとして検出することはできませんでした。

フレームワークを呼び出すのはAppleEventの枠組みの中でやっているわけではないはずなので、タイムアウトを仕掛けて適用されなくても仕方ありません。

AppleScript名:GPUImageで画像にすべてのフィルタを実行してデスクトップにPNG形式で保存
– Created 2017-02-05 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “GPUImage”
–https://github.com/BradLarson/GPUImage
–http://piyocast.com/as/archives/4441

–Read JPEG file
set aFile to POSIX path of (choose file of type {“public.image”})
set anImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile

–Select Filter
set erroredFilter to {}
set aList to {“GPUImageFilter”, “GPUImageTwoPassFilter”, “GPUImage3×3TextureSamplingFilter”, “GPUImageContrastFilter”, “GPUImageSaturationFilter”, “GPUImageBrightnessFilter”, “GPUImageLevelsFilter”, “GPUImageExposureFilter”, “GPUImageRGBFilter”, “GPUImageHueFilter”, “GPUImageWhiteBalanceFilter”, “GPUImageMonochromeFilter”, “GPUImagePixellateFilter”, “GPUImageSobelEdgeDetectionFilter”, “GPUImageSketchFilter”, “GPUImageToonFilter”, “GPUImageGrayscaleFilter”, “GPUImageKuwaharaFilter”, “GPUImageFalseColorFilter”, “GPUImageSharpenFilter”, “GPUImageUnsharpMaskFilter”, “GPUImageTwoInputFilter”, “GPUImageGaussianBlurFilter”, “GPUImageTwoPassTextureSamplingFilter”, “GPUImageFilterGroup”, “GPUImageTransformFilter”, “GPUImageCropFilter”, “GPUImageGaussianBlurPositionFilter”, “GPUImageGaussianSelectiveBlurFilter”, “GPUImageBilateralFilter”, “GPUImageBoxBlurFilter”, “GPUImageSingleComponentGaussianBlurFilter”, “GPUImageMedianFilter”, “GPUImageMotionBlurFilter”, “GPUImageZoomBlurFilter”, “GPUImageAddBlendFilter”, “GPUImageColorBurnBlendFilter”, “GPUImageDarkenBlendFilter”, “GPUImageDivideBlendFilter”, “GPUImageLightenBlendFilter”, “GPUImageMultiplyBlendFilter”, “GPUImageOverlayBlendFilter”, “GPUImageColorDodgeBlendFilter”, “GPUImageLinearBurnBlendFilter”, “GPUImageScreenBlendFilter”, “GPUImageColorBlendFilter”, “GPUImageExclusionBlendFilter”, “GPUImageHueBlendFilter”, “GPUImageLuminosityBlendFilter”, “GPUImageNormalBlendFilter”, “GPUImagePoissonBlendFilter”, “GPUImageSaturationBlendFilter”, “GPUImageSoftLightBlendFilter”, “GPUImageHardLightBlendFilter”, “GPUImageSubtractBlendFilter”, “GPUImageTwoInputCrossTextureSamplingFilter”, “GPUImageDifferenceBlendFilter”, “GPUImageDissolveBlendFilter”, “GPUImageChromaKeyBlendFilter”, “GPUImageMaskFilter”, “GPUImageOpacityFilter”, “GPUImageAlphaBlendFilter”, “GPUImageColorMatrixFilter”, “GPUImageSepiaFilter”, “GPUImageGammaFilter”, “GPUImageHazeFilter”, “GPUImageToneCurveFilter”, “GPUImageHighlightShadowFilter”, “GPUImageLookupFilter”, “GPUImageAmatorkaFilter”, “GPUImageMissEtikateFilter”, “GPUImageSoftEleganceFilter”, “GPUImage3×3ConvolutionFilter”, “GPUImageEmbossFilter”, “GPUImageLaplacianFilter”, “GPUImageLanczosResamplingFilter”, “GPUImageThreeInputFilter”, “GPUImageFourInputFilter”, “GPUImageColorInvertFilter”, “GPUImageHistogramFilter”, “GPUImageHistogramGenerator”, “GPUImageAverageColor”, “GPUImageLuminosity”, “GPUImageSolidColorGenerator”, “GPUImageAdaptiveThresholdFilter”, “GPUImageAverageLuminanceThresholdFilter”, “GPUImageLuminanceThresholdFilter”, “GPUImageSolarizeFilter”, “GPUImageHalftoneFilter”, “GPUImagePixellatePositionFilter”, “GPUImagePolarPixellateFilter”, “GPUImagePolkaDotFilter”, “GPUImageCrosshatchFilter”, “GPUImageXYDerivativeFilter”, “GPUImageDirectionalNonMaximumSuppressionFilter”, “GPUImageDirectionalSobelEdgeDetectionFilter”, “GPUImageCannyEdgeDetectionFilter”, “GPUImagePrewittEdgeDetectionFilter”, “GPUImageThresholdEdgeDetectionFilter”, “GPUImageHarrisCornerDetectionFilter”, “GPUImageNobleCornerDetectionFilter”, “GPUImageShiTomasiFeatureDetectionFilter”, “GPUImageThresholdedNonMaximumSuppressionFilter”, “GPUImageColorPackingFilter”, “GPUImageHoughTransformLineDetector”, “GPUImageParallelCoordinateLineTransformFilter”, “GPUImageCrosshairGenerator”, “GPUImageLineGenerator”, “GPUImageBuffer”, “GPUImageLowPassFilter”, “GPUImageHighPassFilter”, “GPUImageMotionDetector”, “GPUImageThresholdSketchFilter”, “GPUImageSmoothToonFilter”, “GPUImageTiltShiftFilter”, “GPUImageCGAColorspaceFilter”, “GPUImagePosterizeFilter”, “GPUImageKuwaharaRadius3Filter”, “GPUImageChromaKeyFilter”, “GPUImageVignetteFilter”, “GPUImageBulgeDistortionFilter”, “GPUImagePinchDistortionFilter”, “GPUImageStretchDistortionFilter”, “GPUImageClosingFilter”, “GPUImageRGBClosingFilter”, “GPUImageDilationFilter”, “GPUImageRGBDilationFilter”, “GPUImageErosionFilter”, “GPUImageRGBErosionFilter”, “GPUImageOpeningFilter”, “GPUImageRGBOpeningFilter”, “GPUImageSphereRefractionFilter”, “GPUImageGlassSphereFilter”, “GPUImageSwirlFilter”, “GPUImageJFAVoronoiFilter”, “GPUImageVoronoiConsumerFilter”, “GPUImageLocalBinaryPatternFilter”, “GPUImageColorLocalBinaryPatternFilter”, “GPUImageMosaicFilter”, “GPUImagePerlinNoiseFilter”, “GPUImageWeakPixelInclusionFilter”, “GPUImageNonMaximumSuppressionFilter”, “GPUImageSourceOverBlendFilter”, “GPUImageColourFASTFeatureDetector”, “GPUImageColourFASTSamplingOperation”}

repeat with i in aList
  set j to contents of i
  
set aClass to current application’s NSClassFromString(j)
  
  
–Filter Image
  
set errorFlag to true
  
try
    with timeout of 5 seconds
      set stillImageFilter to aClass’s alloc()’s init()
      
set aProcImg to (stillImageFilter’s imageByFilteringImage:anImage)
    end timeout
  on error erM
    set the end of erroredFilter to {j, erM, 1}
    
set errorFlag to false
  end try
  
  
if errorFlag = true then
    –Make New File Name
    
set aPath to (((current application’s NSString’s stringWithString:aFile)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:j)’s stringByAppendingPathExtension:“png”)
    
try
      set sRes to saveNSImageAtPathAsPNG(aProcImg, aPath as string) of me
    on error erM
      set the end of erroredFilter to {j, erM, 2}
    end try
  end if
end repeat

return erroredFilter
–> {{”GPUImageTwoInputFilter”, “missing valueは“representationUsingType_properties_”メッセージを認識できません。”, 2}, …..

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –true/false
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/02/05 GPUImageで画像にGPUImageMonochromeFilterを実行してデスクトップにPNG形式で保存

オープンソースのフレームワーク「GPUImage」(By Brad Larson)を呼び出して、指定画像にフィルタ(モノクローム画像化)を実行して、デスクトップにPNGで保存するAppleScriptです。

テストにあたっては、GPUImageフレームワークをXcodeでビルドして、~/Library/Frameworksフォルダに入れておいてください。

GPUImageはもともとiOSデバイス用に作られたようですが、Macもサポートしており、さまざまな(125種類もの)画像フィルタが用意されており、手軽に利用できます。CoreImageをAppleScriptから呼び出してフィルタを実行してみたこともありますが、CoreImageよりも手軽に感じられました。

フィルタ実行部分は2行だけで、ファイルを選択したり画像を保存する部分がほとんどなので、やることはほとんどありません。ある意味、Photoshopを呼び出すよりも手軽です。

img_0007_resized.png
▲実行前のオリジナル画像(Haneda Airport, Tokyo, Japan)

a5dfc34c-d1e4-47e6-8379-f46412dbc30d_resized.png
▲GPUImageMonochromeFilterを実行した画像

AppleScript名:GPUImageで画像にGPUImageMonochromeFilterを実行してデスクトップにPNG形式で保存
– Created 2017-02-05 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “GPUImage”
–https://github.com/BradLarson/GPUImage
–http://piyocast.com/as/archives/4438

–Read JPEG file
set aFile to POSIX path of (choose file of type {“public.image”})
set anImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile

–Filter Image
set stillImageFilter to current application’s GPUImageMonochromeFilter’s alloc()’s init()
set aProcImg to stillImageFilter’s imageByFilteringImage:anImage

–Make New File Name
set aUUIDstr to (current application’s NSUUID’s UUID()’s UUIDString()) as string
set aPath to ((current application’s NSString’s stringWithString:aFile)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:“png”
set sRes to saveNSImageAtPathAsPNG(aProcImg, aPath as string) of me

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –true/false
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2017/02/03 倍率を指定してNSImageをリサイズする

与えられたNSImageをリサイズするAppleScriptです。

実行サンプルとして、実行中のコンピュータの画像(NSImageNameComputer)をNSImageで取得、このNSImageを16倍の大きさにリサイズし、指定場所&名称でPNG形式で保存します。

AppleScript名:NSImageの倍率を変更してNSImageをリサイズする
– Created 2017-02-03 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://stackoverflow.com/questions/11949250/how-to-resize-nsimage
–http://piyocast.com/as/archives/4437

set aPath to POSIX path of (choose file name with prompt “Enter PNG file name”)

–Get Computer Icon
set anImage to current application’s NSImage’s imageNamed:(current application’s NSImageNameComputer)

–Resize it to x16
set resizedImg to my resizedImage:anImage toScale:16
set aRes to saveNSImageAtPathAsPNG(resizedImg, aPath) of me

on resizedImage:aSourceImg toScale:imgScale
  if (aSourceImg’s isValid()) as boolean = false then error “Invalid NSImage”
  
  
set aSize to aSourceImg’s |size|()
  
–>  {width:32.0, height:32.0}
  
  
set aWidth to (aSize’s width) * imgScale
  
set aHeight to (aSize’s height) * imgScale
  
  
set aRep to current application’s NSBitmapImageRep’s alloc()’s initWithBitmapDataPlanes:(missing value) pixelsWide:aWidth pixelsHigh:aHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:true isPlanar:false colorSpaceName:(current application’s NSCalibratedRGBColorSpace) bytesPerRow:0 bitsPerPixel:0
  
  
set newSize to {width:aWidth, height:aHeight}
  
aRep’s setSize:newSize
  
  
current application’s NSGraphicsContext’s saveGraphicsState()
  
current application’s NSGraphicsContext’s setCurrentContext:(current application’s NSGraphicsContext’s graphicsContextWithBitmapImageRep:aRep)
  
  
aSourceImg’s drawInRect:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) fromRect:(current application’s NSZeroRect) operation:(current application’s NSCompositeCopy) fraction:(1.0)
  
  
current application’s NSGraphicsContext’s restoreGraphicsState()
  
  
set newImg to current application’s NSImage’s alloc()’s initWithSize:newSize
  
newImg’s addRepresentation:aRep
  
  
return newImg
end resizedImage:toScale:

–NSImageを指定パスにPNG形式で保存
on saveNSImageAtPathAsPNG(anImage, outPath)
  –画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
  
–書き出しファイルパス情報を作成
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
–書き出し
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –成功ならtrue、失敗ならfalseが返る
end saveNSImageAtPathAsPNG

★Click Here to Open This Script 

2016/12/05 アニメーションGIFをフレームごとに画像に分解する

アニメーションGIFを指定すると、指定フォルダ内にフレームごとに個別の連番GIF画像に分解出力するAppleScriptです。

AppleScript名:アニメーションGIFをフレームごとに画像に分解する
– Created 2016-11-29 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4341

set gifFile to POSIX path of (choose file of type “com.compuserve.gif” with prompt “Select Animation-GIF file”)
set destFol to POSIX path of (choose folder with prompt “Select the folder to save gif’s frames”)

set anImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:gifFile
if anImage is equal to missing value then error “Illegal GIF Image”

set anImgRep to anImage’s representations()’s firstObject()
set framesNum to (anImgRep’s valueForProperty:“NSImageFrameCount”) as integer

repeat with i from 0 to (framesNum - 1)
  (anImgRep’s setProperty:“NSImageCurrentFrame” withValue:i)
  
set aRep to (anImgRep’s representationUsingType:(current application’s NSGIFFileType) |properties|:(missing value))
  (
aRep’s writeToFile:(destFol & (i as string) & “.gif”) atomically:true)
end repeat

★Click Here to Open This Script 

2016/09/20 連番JPEGファイルを読み込んで連結したPDFを作成(新規作成)

連番JPEG画像を番号順にソートして、順次連結したPDFを新規作成するAppleScriptです。

jpeg_catfiles.jpg

このような連番画像を連結して任意のファイル名のPDFに合成します。出来上がるPDFは、元のJPEGファイルの圧縮度に応じて大きくなります。

新規作成よりも、すでに存在しているPDFにJPEGファイルを連結するほうが実用的だと思います。

AppleScript名:連番JPEGファイルを読み込んで連結したPDFを作成(新規作成)
– Created 2016-09-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”
use framework “Quartz”
use framework “AppKit”

set aExt to “.jpg”
set aFol to choose folder
set fList to getFilePathList(aFol, aExt) of me
set f2List to my sort1DList:fList ascOrder:true –sort by ascending

set newFile to POSIX path of (choose file name with prompt “新規PDFファイルの名称を選択”)
set newFilePath to current application’s NSString’s stringWithString:newFile

–Make Blank PDF
set aPDFdoc to current application’s PDFDocument’s alloc()’s init()

set pageNum to 0

repeat with i in f2List
  set j to contents of i
  
set aURL to (current application’s |NSURL|’s fileURLWithPath:j)
  
set bImg to (current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL)
  (
aPDFdoc’s insertPage:(current application’s PDFPage’s alloc()’s initWithImage:bImg) atIndex:pageNum)
  
set pageNum to pageNum + 1
end repeat

aPDFdoc’s writeToFile:newFilePath

–ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)
on getFilePathList(aFol, aExt)
  set aPath to current application’s NSString’s stringWithString:(POSIX path of aFol)
  
set aFM to current application’s NSFileManager’s defaultManager()
  
set nameList to (aFM’s contentsOfDirectoryAtPath:aPath |error|:(missing value)) as list
  
set anArray to current application’s NSMutableArray’s alloc()’s init()
  
  
repeat with i in nameList
    set j to i as text
    
if (j ends with aExt) and (j does not start with “.”) then –exclude invisible files
      set newPath to (aPath’s stringByAppendingString:j)
      (
anArray’s addObject:newPath)
    end if
  end repeat
  
  
return anArray as list
end getFilePathList

–1D List(文字)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
on sort1DList:theList ascOrder:aBool
  set aDdesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“self” ascending:aBool selector:“localizedCaseInsensitiveCompare:”
  
set theArray to current application’s NSArray’s arrayWithArray:theList
  
return (theArray’s sortedArrayUsingDescriptors:{aDdesc}) as list
end sort1DList:ascOrder:

★Click Here to Open This Script 

2016/07/27 PDFをページごとに分解してJPEGで保存する v2

PDFをページごとに分解してJPEG画像で保存するAppleScriptのアップデート版です。

実際に連番画像に変換して、ePub書類に変換させてみたらページの順序が狂ってしまいました。連番を振るときにゼロパディングしなかったためだとすぐにわかったので、ゼロパディングの処理を追加したものです。

ただし、実際にはこれだと解像度が不足しており、2倍の解像度で出力するように改良して実戦投入(Retina Display環境に配慮しつつ)しました。

AppleScript名:ASOCでPDFをページごとに分解してJPEGで保存する v2
– Created 2014-12-26 by Takaaki Naganoya
– Modified 2015-09-26 by Takaaki Naganoya
– Modified 2015-10-01 by Takaaki Naganoya
– Modified 2016-07-27 by Takaaki Naganoya–save each PDF page as jpeg
– Modified 2016-07-27 by Takaaki Naganoya–added zero padding function
– 2016 Piyomaru Software
# http://piyocast.com/as/archives/4176

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “QuartzCore”
use framework “AppKit”

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “ページごとに分解するPDFを指定してください”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

set aPOSIXpath to POSIX path of aHFSPath —書き出し先パスをPOSIX pathで用意しておく(あとで加工)

set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

set compFactor to 1.0 – 0.0 = max jpeg compression, 1.0 = none

–PDFをページごとに分割してJPEGでファイル書き出し
repeat with i from 0 to (pCount - 1)
  set thisPage to (aPDFdoc’s pageAtIndex:(i))
  
set thisDoc to (current application’s NSImage’s alloc()’s initWithData:(thisPage’s dataRepresentation()))
  
if thisDoc = missing value then error “Error in getting imagerep from PDF in page:” & (i as string)
  
  
set theData to thisDoc’s TIFFRepresentation()
  
set newRep to (current application’s NSBitmapImageRep’s imageRepWithData:theData)
  
set targData