Archive for the 'NSColor' Category

2017/10/18 QuartzComoserでグラフ表示てすと v4(10.13対応)

QuartzComposerのCompositionを任意のパラメータでレンダリングして表示するAppleScriptのmacOS 10.13.x対応版です。

composition.png

macOS 10.13で変更になったのはQuartzComposerまわりではなく、NSDictionary/NSMutableDictionaryまわりで、キーと値を列挙して、

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aDict to (current application’s NSMutableDictionary’s dictionaryWithObjectsAndKeys_(1, “aKey”, 2, “bKey”, missing value)) as record
–>  {bKey:2, aKey:1}

★Click Here to Open This Script 

などとNSDictionary/NSMutableDictionaryを作成するタイプのメソッド(末尾にmissing valueがつくもの)です。macOS 10.13上で実行すると、

1013error.jpg

このように(↑)エラーになるので、

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aDict to (current application’s NSDictionary’s dictionaryWithObjects:{1, 2} forKeys:{“aKey”, “bKey”}) as record
–> {bKey:2, aKey:1}

★Click Here to Open This Script 

などと書き換える必要があります(Thanks Shane!)。

前者の書き方については、書くのが面倒に感じていたので本Blog中でもかぞえるほどしか登場していませんでした。10.13向けの書き換え例としてこれが向いていると判断して掲載してみた次第です。QuartzComposer自体にはとくに思い入れもありません。

なお、表示対象のQuartzCompositionは、本Script Bundle中に入っていることを前提としていますが、バンドル外のものを表示するように書き換えるのも簡単なので実験してみるとよいでしょう。

comp_loc.png

本Script自体はmacOS 10.12上で作成して実行確認しています(当然、10.13.1beta上でも動作確認していますが)。10.13以降で追加になった機能を前提としていません。

–> Download script bundle including Composition

AppleScript名:QuartzComoserでグラフ表示てすと v4(10.13対応)
– Created 2015-11-03 by Takaaki Naganoya
– Modified 2017-10-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”
use framework “Carbon” – AEInteractWithUser() is in Carbon
–http://piyocast.com/as/archives/4900

property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSWindowCloseButton : a reference to current application’s NSWindowCloseButton
property NSScreen : a reference to current application’s NSScreen
property NSPredicate : a reference to current application’s NSPredicate
property NSDictionary : a reference to current application’s NSDictionary
property NSBackingStoreBuffered : a reference to current application’s NSBackingStoreBuffered
property NSMutableArray : a reference to current application’s NSMutableArray
property NSTitledWindowMask : a reference to current application’s NSTitledWindowMask
property NSString : a reference to current application’s NSString
property NSWindow : a reference to current application’s NSWindow
property NSNumber : a reference to current application’s NSNumber
property NSNormalWindowLevel : a reference to current application’s NSNormalWindowLevel
property QCView : a reference to current application’s QCView
property NSColor : a reference to current application’s NSColor

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

set chartData to NSMutableArray’s new()

–chartData’s addObject:(NSMutableDictionary’s dictionaryWithObjectsAndKeys_(”練馬区”, “label”, 3, “value”, missing value))–older way (Obsolete in 10.13)
chartData’s addObject:(my recWithLabels:{“label”, “value”} andValues:{“練馬区”, 3})
chartData’s addObject:(my recWithLabels:{“label”, “value”} andValues:{“青梅市”, 1})
chartData’s addObject:(my recWithLabels:{“label”, “value”} andValues:{“中野区”, 2})

–上記データの最大値を求める
set aMaxRec to chartData’s filteredArrayUsingPredicate:(NSPredicate’s predicateWithFormat_(“SELF.value == %@.@max.value”, chartData))
set aMax to value of aMaxRec
set aMaxVal to (first item of aMax) as integer

–Scalingの最大値を求める
if aMaxVal 10 then
  set aScaleMax to (10 div aMaxVal)
  
set aScaleMin to aScaleMax div 10
else
  set aScaleMax to (10 / aMaxVal)
  
set aScaleMin to 1
end if

try
  set aPath to path to resource “Chart.qtz”
on error
  return
end try

set qtPath to NSString’s stringWithString:(POSIX path of aPath)

set aView to QCView’s alloc()’s init()
set qtRes to (aView’s loadCompositionFromFile:qtPath)

aView’s setValue:chartData forInputKey:“Data”
aView’s setValue:(NSNumber’s numberWithFloat:(0.5)) forInputKey:“Scale”
aView’s setValue:(NSNumber’s numberWithFloat:(0.2)) forInputKey:“Spacing”
aView’s setAutostartsRendering:true

set maXFrameRate to aView’s maxRenderingFrameRate()

set aWin to (my makeWinWithView(aView, 800, 600, “AppleScript Composition Test”))

(aView’s setValue:(NSNumber’s numberWithFloat:aScaleMax / 10) forInputKey:“Scale”)
delay 5

my closeWin:aWin
aView’s stopRendering() –レンダリング停止

–make Window for Display
on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle)
  set aScreen to NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {aWinWidth, aWinHeight}}
  
  
set aBacking to NSTitledWindowMask
  
  
set aDefer to NSBackingStoreBuffered
  
  
– Window
  
set aWin to NSWindow’s alloc()
  (
aWin’s initWithContentRect:aFrame styleMask:aBacking backing:aDefer defer:false screen:aScreen)
  
aWin’s setBackgroundColor:(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:(NSNormalWindowLevel)
  
aWin’s setOpaque:false
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
aWin’s makeKeyAndOrderFront:(me)
  
–aWin’s movableByWindowBackground:true
  
  
– Set Custom View
  
aWin’s setContentView:aView
  
  
–Set Close Button  
  
set closeButton to NSWindow’s standardWindowButton:(NSWindowCloseButton) forStyleMask:(NSTitledWindowMask)
  
  
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:

on recWithLabels:theKeys andValues:theValues
  return (NSDictionary’s dictionaryWithObjects:theValues forKeys:theKeys) as record
end recWithLabels:andValues:

★Click Here to Open This Script 

2017/09/29 macOS 10.13で変更されたPDFアノテーションの作成

macOS 10.13, High Sierraで変更になった、PDF書類へのアノテーション作成を行うAppleScriptです。

とくにサンプルプログラムが見当たらなかったのですが、「まあこんなもんだろー」とあたりをつけて書いてみたら動きました。Objective-CのコードもSwiftのコードも見当たらず、いまのところPDFアノテーション作成コードはこのAppleScriptしか見当たらない状態、、、、、、

選択したPDFに対してアノテーションを追加します。自分は動作検証用に作っためもり入りの「方眼紙PDF」に対してアノテーションを追加してみました(掲載スクリーンショット)。PDFの座標系は左下が原点です。

AppleがmacOS 10.13に作ったScripting BridgeのNSRectの変換ミス(?)のバグに対処してあります。恥かしいレベルのバグだし、まいどまいど腹がたつのでさっさと修正してほしいのですが、いつごろ修正されるものやら。予想以上に今回のバグの被害範囲が広いので、さっさと修正してほしいものです(指定写真の顔の部分をエリア検出してフィルタをかけるといった処理が途中でエラーに。ものすごく腹立たしい)。

circle_annotation_resized.png

従来の書き方でもまだ動くので、今日明日ですぐに切り替えが必要になるわけではなさそうです。

新しい書き方のほうが単純で、さまざまなアノテーションでもだいたい同様に記述できるので、個人的にはこちらのほうがいい感じがします。

→ 指定PDFの最初のページに大量のスクウェアアノテーションを添付する

→ 指定PDFの最初のページにアノテーションを追加する(テキストアノテーション)

AppleScript名:指定PDFの最初のページにサークルアノテーションを追加する(High Sierra)
– Created 2017-09-27 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.7″ –macOS 10.13 or later
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”
–http://piyocast.com/as/archives/4855

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Choose a PDF”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

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

–macOS 10.13以降で指定する形式のAnnotation
set keyList to {current application’s PDFAnnotationKeyColor, current application’s PDFAnnotationKeyInteriorColor}
set valList to {current application’s NSColor’s blackColor(), current application’s NSColor’s grayColor()}
set propDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList

–macOS 10.13のバグ対策。NSRectはwidth–>heightの順にパラメータを並べる
set anAnnotation to current application’s PDFAnnotation’s alloc()’s initWithBounds:{origin:{x:100, y:100}, |size|:{width:600, height:600}} forType:(current application’s PDFAnnotationSubtypeCircle) withProperties:propDict

firstPage’s addAnnotation:anAnnotation

aPDFdoc’s writeToFile:aPOSIX

★Click Here to Open This Script 

square_annotation_resized.png

AppleScript名:指定PDFの最初のページにスクウェアアノテーションを追加する(High Sierra)
– Created 2017-09-27 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.7″ –macOS 10.13 or later
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”
–http://piyocast.com/as/archives/4855

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Choose a PDF”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

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

–macOS 10.13以降で指定する形式のAnnotation
set keyList to {current application’s PDFAnnotationKeyColor, current application’s PDFAnnotationKeyInteriorColor}
set valList to {current application’s NSColor’s blackColor(), current application’s NSColor’s grayColor()}
set propDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList

–macOS 10.13のバグ対策。NSRectはwidth–>heightの順にパラメータを並べる
set anAnnotation to current application’s PDFAnnotation’s alloc()’s initWithBounds:{origin:{x:100, y:100}, |size|:{width:500, height:500}} forType:(current application’s PDFAnnotationSubtypeSquare) withProperties:propDict

firstPage’s addAnnotation:anAnnotation

aPDFdoc’s writeToFile:aPOSIX

★Click Here to Open This Script 

text_annotation_resized.png

AppleScript名:指定PDFの最初のページにテキストアノテーションを追加する(High Sierra)
– Created 2017-09-27 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.7″ –macOS 10.13 or later
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”
–http://piyocast.com/as/archives/4855

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Choose a PDF”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

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

–macOS 10.13以降で指定する形式のAnnotation
set keyList to {current application’s PDFAnnotationKeyInteriorColor, current application’s PDFAnnotationKeyContents}
set valList to {current application’s NSColor’s yellowColor(), “Piyomaru Software” & return & “ぴよまるソフトウェア”}
set propDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList

–macOS 10.13のバグ対策。NSRectはwidth–>heightの順にパラメータを並べる
set anAnnotation to current application’s PDFAnnotation’s alloc()’s initWithBounds:{origin:{x:100, y:100}, |size|:{width:200, height:50}} forType:(current application’s PDFAnnotationSubtypeFreeText) withProperties:propDict

firstPage’s addAnnotation:anAnnotation

aPDFdoc’s writeToFile:aPOSIX

★Click Here to Open This Script 

line_annotation_resized.png

AppleScript名:指定PDFの最初のページにラインアノテーションを追加する(High Sierra)
– Created 2017-09-27 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.7″ –macOS 10.13 or later
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”
–http://piyocast.com/as/archives/4855

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Choose a PDF”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

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

–macOS 10.13以降で指定する形式のAnnotation
set keyList to {current application’s PDFAnnotationKeyColor}
set valList to {current application’s NSColor’s blackColor()}
set propDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList

–macOS 10.13のバグ対策。NSRectはwidth–>heightの順にパラメータを並べる
set anAnnotation to current application’s PDFAnnotation’s alloc()’s initWithBounds:{origin:{x:100, y:100}, |size|:{width:600, height:600}} forType:(current application’s PDFAnnotationSubtypeLine) withProperties:propDict

firstPage’s addAnnotation:anAnnotation

aPDFdoc’s writeToFile:aPOSIX

★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/24 迷路をRTFで作成して脱出経路を赤く着色する v3

2D迷路の作成プログラム「MazeFinder」(By Toby Jennings)をフレームワーク化したものを呼び出して、文字ベースの迷路データをRTFに変換して脱出経路情報を着色してデスクトップに書き出すAppleScriptのアップデート版です。

迷路データの作成はこの際どうでもよく、文字列の検索を行う部分で問題が起こったことへの対処を行いました。

NSStringの文字検索メソッドrangeOfString: で、検索文字列が見つからなかった場合にNSNotFound(=-1)が返ってくるはずですが、macOS 10.13 betaで動かしてみたところNSNotFoundではなく巨大な数が返ってくることに気づきました。9,223,372,036,854,775,807と巨大すぎてAppleScriptの処理系では数値の精度上限を超えてしまっています。

いろいろ情報収集してみたところ、10.13にかぎらずよく知られた動作のようで、-1ではなく巨大な数を返してしまうパターンがある、と認識しておく必要があるようです(いつものApple仕事)。

AppleScript名:迷路をRTFで作成して脱出経路を赤く着色する v3
– Created 2017-09-19 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “MazeFinder” –https://github.com/tcjennings/MazeFinder
–http://piyocast.com/as/archives/4842

property NSColor : a reference to current application’s NSColor
property Board2D : a reference to current application’s Board2D
property NSUUID : a reference to current application’s NSUUID
property NSDictionary : a reference to current application’s NSDictionary
property NSMutableArray : a reference to current application’s NSMutableArray
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSFont : a reference to current application’s NSFont
property NSString : a reference to current application’s NSString
property NSDocumentTypeDocumentAttribute : a reference to current application’s NSDocumentTypeDocumentAttribute
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property Pathfinder : a reference to current application’s Pathfinder
property NSLiteralSearch : a reference to current application’s NSLiteralSearch
–NSNotFoundはプロパティに代入しても認識されなかった

set targFontName to “Courier-Bold” –PostScript Name
set targFontSize to 13 –Point

–迷路テキストデータ作成→Attributed Stringに
set aStr to create2DMazeAndSolveIt(30, 30, 1, 1, 28, 28) of me –Plain Text
set anAttr to changeAttrStrsFontAttribute(aStr, targFontName, targFontSize) of me –Attributed String

–迷路データに着色(参照呼び出し, Call by reference)
markCharOfAttributedString(anAttr, aStr, “!”, (NSColor’s redColor())) of me

–結果のRTFをデスクトップ上に書き出す。ファイル名はUUID.rtf
set targFol to current application’s NSHomeDirectory()’s stringByAppendingPathComponent:“Desktop”
set aRes to my saveStyledTextAsRTF(targFol, anAttr)

–指定のAttributed String内で指定文字列が含まれる箇所に指定の色をつける(結果はメイン側に参照渡し)
on markCharOfAttributedString(anAttr, origStr, aTargStr, aColor)
  set rList to searchWordWithRange(origStr, aTargStr) of me
  
repeat with ii in rList
    (anAttr’s addAttribute:(NSForegroundColorAttributeName) value:aColor range:ii)
  end repeat
end markCharOfAttributedString

–指定の文字列をAttributed Stringに変換して任意のフォントを一括指定
on changeAttrStrsFontAttribute(aStr, aFontPSName, aFontSize)
  set tmpAttr to NSMutableAttributedString’s alloc()’s initWithString:aStr
  
set aRange to current application’s NSMakeRange(0, tmpAttr’s |length|())
  
set aVal1 to NSFont’s fontWithName:aFontPSName |size|:aFontSize
  
tmpAttr’s beginEditing()
  
tmpAttr’s addAttribute:(NSFontAttributeName) value:aVal1 range:aRange
  
tmpAttr’s endEditing()
  
return tmpAttr
end changeAttrStrsFontAttribute

–指定テキストデータ(atargText)内に、指定文字列(aSearchStr)が含まれる範囲情報(NSRange)をすべて取得する
on searchWordWithRange(aTargText, aSearchStr)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:NSLiteralSearch range:aRange
    
set aLoc to (detectedRange’s location)
    
–CAUTION !!!! Sometimes aLoc returns not NSNotFound (-1) but a Very large number
    
if (aLoc > 9.999999999E+9) or (aLoc = (current application’s NSNotFound)) then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to aLoc as integer
    
set bNum to (detectedRange’s |length|) as integer
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum - (aNum + bNum))
  end repeat
  
  
return hitArray
end searchWordWithRange

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(targFol, aStyledString)
  set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
set theName to (NSUUID’s UUID()’s UUIDString())
  
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

–2D迷路を作成して脱出経路を検索して文字列で迷路データを出力する
–迷路サイズ x,y スタート座標 x, y ゴール座標 x,y
on create2DMazeAndSolveIt(xMax, yMax, xStart, yStart, xGoal, yGoal)
  set myBoard to Board2D’s alloc()’s init()
  
myBoard’s setupBoardWithRows:xMax WithColumns:yMax –60×60ぐらいが上限。正方形でないとダメ
  
myBoard’s createMazeFromBoard()
  
  
set myPathfinder to Pathfinder’s alloc()’s init()
  
set myPath to myPathfinder’s findPathThroughMaze:myBoard fromX:xStart fromY:yStart toX:xGoal toY:yGoal
  
  
set aCount to myPath’s |count|()
  
if aCount > 0 then
    set aRes to myBoard’s drawPathThroughMaze:myPath
    
return aRes as string
  else
    return false
  end if
end create2DMazeAndSolveIt

★Click Here to Open This Script 

2017/09/21 迷路をRTFで作成して脱出経路を赤く着色する v2

2D迷路の作成プログラム「MazeFinder」(By Toby Jennings)をフレームワーク化したものを呼び出して、文字ベースの迷路データをRTFに変換して脱出経路情報を着色してデスクトップに書き出すAppleScriptのアップデート版です。

maze1.png

処理結果はとくに前バージョンと変化ありませんし、実行時間については前バージョンよりも0.02秒ほど余計にかかるようになりました。

では、なぜ書き換えたかといえば、各機能の再利用性の向上が目的です。せっかく書いておいても、他の用途に転用するのに手間がかかるようであれば意味がありません。さまざまな用途に転用しやすい構造(サブルーチンとしてまとめているとか)に書いておくことはとても重要です。

再利用したい機能モジュールをよりサブルーチン化するように書き換えました。こうしておくことで、まったく違った用途にもすぐに転用できます。

本Scriptを試す場合には、MazeFinder.frameworkをダウンロードして~/Library/Frameworksフォルダに入れてください。

–> Download Framework Binary

60×60の迷路を作成して着色してファイル書き出しを終了するまでに、開発環境で0.1秒程度かかりました(前バージョンは0.08秒ぐらい)。

AppleScript名:迷路をRTFで作成して脱出経路を赤く着色する v2
– Created 2017-09-19 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “MazeFinder” –https://github.com/tcjennings/MazeFinder
–http://piyocast.com/as/archives/4834

property NSColor : a reference to current application’s NSColor
property Board2D : a reference to current application’s Board2D
property NSUUID : a reference to current application’s NSUUID
property NSDictionary : a reference to current application’s NSDictionary
property NSMutableArray : a reference to current application’s NSMutableArray
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSFont : a reference to current application’s NSFont
property NSString : a reference to current application’s NSString
property NSDocumentTypeDocumentAttribute : a reference to current application’s NSDocumentTypeDocumentAttribute
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property Pathfinder : a reference to current application’s Pathfinder
property NSLiteralSearch : a reference to current application’s NSLiteralSearch
–NSNotFoundはプロパティに代入しても認識されなかった

set targFontName to “Courier-Bold” –PostScript Name
set targFontSize to 13 –Point

–迷路テキストデータ作成→Attributed Stringに
set aStr to create2DMazeAndSolveIt(30, 30, 1, 1, 28, 28) of me –Plain Text
set anAttr to changeAttrStrsFontAttribute(aStr, targFontName, targFontSize) of me –Attributed String

–迷路データに着色(参照呼び出し, Call by reference)
markCharOfAttributedString(anAttr, aStr, “!”, (NSColor’s redColor())) of me

–結果のRTFをデスクトップ上に書き出す。ファイル名はUUID.rtf
set targFol to current application’s NSHomeDirectory()’s stringByAppendingPathComponent:“Desktop”
set aRes to my saveStyledTextAsRTF(targFol, anAttr)

–指定のAttributed String内で指定文字列が含まれる箇所に指定の色をつける(結果はメイン側に参照渡し)
on markCharOfAttributedString(anAttr, origStr, aTargStr, aColor)
  set rList to searchWordWithRange(origStr, aTargStr) of me
  
repeat with ii in rList
    (anAttr’s addAttribute:(NSForegroundColorAttributeName) value:aColor range:ii)
  end repeat
end markCharOfAttributedString

–指定の文字列をAttributed Stringに変換して任意のフォントを一括指定
on changeAttrStrsFontAttribute(aStr, aFontPSName, aFontSize)
  set tmpAttr to NSMutableAttributedString’s alloc()’s initWithString:aStr
  
set aRange to current application’s NSMakeRange(0, tmpAttr’s |length|())
  
set aVal1 to NSFont’s fontWithName:aFontPSName |size|:aFontSize
  
tmpAttr’s beginEditing()
  
tmpAttr’s addAttribute:(NSFontAttributeName) value:aVal1 range:aRange
  
tmpAttr’s endEditing()
  
return tmpAttr
end changeAttrStrsFontAttribute

–指定テキストデータ(atargText)内に、指定文字列(aSearchStr)が含まれる範囲情報(NSRange)をすべて取得する
on searchWordWithRange(aTargText, aSearchStr)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
set aCount to 1
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:NSLiteralSearch range:aRange
    
if detectedRange’s location is equal to (current application’s NSNotFound) then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to (detectedRange’s location) as integer
    
set bNum to (detectedRange’s |length|) as integer
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum - (aNum + bNum))
    
set aCount to aCount + 1
  end repeat
  
  
return hitArray
end searchWordWithRange

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(targFol, aStyledString)
  set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
set theName to (NSUUID’s UUID()’s UUIDString())
  
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

–2D迷路を作成して脱出経路を検索して文字列で迷路データを出力する
–迷路サイズ x,y スタート座標 x, y ゴール座標 x,y
on create2DMazeAndSolveIt(xMax, yMax, xStart, yStart, xGoal, yGoal)
  set myBoard to Board2D’s alloc()’s init()
  
myBoard’s setupBoardWithRows:xMax WithColumns:yMax –60×60ぐらいが上限。正方形でないとダメ
  
myBoard’s createMazeFromBoard()
  
  
set myPathfinder to Pathfinder’s alloc()’s init()
  
set myPath to myPathfinder’s findPathThroughMaze:myBoard fromX:xStart fromY:yStart toX:xGoal toY:yGoal
  
  
set aCount to myPath’s |count|()
  
if aCount > 0 then
    set aRes to myBoard’s drawPathThroughMaze:myPath
    
return aRes as string
  else
    return false
  end if
end create2DMazeAndSolveIt

★Click Here to Open This Script 

2017/09/20 迷路をRTFで作成して脱出経路を赤く着色する

2D迷路の作成プログラム「MazeFinder」(By Toby Jennings)をフレームワーク化したものを呼び出して、文字ベースの迷路データをRTFに変換して脱出経路情報を着色してデスクトップに書き出すAppleScriptです。

maze1.png

本Scriptを試す場合には、MazeFinder.frameworkをダウンロードして~/Library/Frameworksフォルダに入れてください。

60×60の迷路を作成して着色してファイル書き出しを終了するまでに、開発環境で0.08秒程度かかりました。

–> Download Framework Binary

迷路作成の処理自体についてはとくに意味はありませんが、迷路プログラム自体にもいろいろあるようです。このMazeFinderについてはいろいろ制約条件がきつく(最大サイズ60×60程度、迷路が正方形でないとクラッシュ)、あまり迷路らしい迷路にもなっていません。

「テキストデータをRTFで出力して特定文字に着色する」というあたりの処理がミソでしょうか。

AppleScript名:迷路をRTFに作成して脱出経路を赤く着色する
– Created 2017-09-19 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “MazeFinder” –https://github.com/tcjennings/MazeFinder
–http://piyocast.com/as/archives/4831

property NSColor : a reference to current application’s NSColor
property Board2D : a reference to current application’s Board2D
property NSUUID : a reference to current application’s NSUUID
property NSDictionary : a reference to current application’s NSDictionary
property NSMutableArray : a reference to current application’s NSMutableArray
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSFont : a reference to current application’s NSFont
property NSString : a reference to current application’s NSString
property NSDocumentTypeDocumentAttribute : a reference to current application’s NSDocumentTypeDocumentAttribute
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property Pathfinder : a reference to current application’s Pathfinder
property NSLiteralSearch : a reference to current application’s NSLiteralSearch

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

–Create Maze Text
set aStr to create2DMazeAndSolveIt(30, 30, 1, 1, 28, 28) of me
set anAttr to NSMutableAttributedString’s alloc()’s initWithString:aStr

set bList to {“!”} –Mark Target List

–Set Fixed Width Font
set aRange to current application’s NSMakeRange(0, anAttr’s |length|())
set aVal1 to NSFont’s fontWithName:targFontName |size|:13
anAttr’s beginEditing()
anAttr’s addAttribute:(current application’s NSFontAttributeName) value:aVal1 range:aRange
anAttr’s endEditing()

–Change Attribute (red color)
repeat with i in bList
  set rList to searchWordWithRange(aStr, i as string) of me
  
repeat with ii in rList
    (anAttr’s addAttribute:(current application’s NSForegroundColorAttributeName) value:(NSColor’s redColor()) range:ii)
  end repeat
end repeat

–結果のRTFをデスクトップ上に書き出す
set targFol to current application’s NSHomeDirectory()’s stringByAppendingPathComponent:“Desktop”
set aFileName to (NSUUID’s UUID()’s UUIDString() as text)
set aRes to my saveStyledTextAsRTF(aFileName, targFol, anAttr)

on searchWordWithRange(aTargText, aSearchStr)
  set aStr to NSString’s stringWithString:aTargText
  
set bStr to NSString’s stringWithString:aSearchStr
  
set hitArray to NSMutableArray’s alloc()’s init()
  
set cNum to (aStr’s |length|()) as integer
  
  
set aRange to current application’s NSMakeRange(0, cNum)
  
  
set aCount to 1
  
repeat
    set detectedRange to aStr’s rangeOfString:bStr options:NSLiteralSearch range:aRange
    
if detectedRange’s location is equal to (current application’s NSNotFound) then exit repeat
    
    
hitArray’s addObject:detectedRange
    
    
set aNum to (detectedRange’s location) as integer
    
set bNum to (detectedRange’s |length|) as integer
    
    
set aRange to current application’s NSMakeRange(aNum + bNum, cNum - (aNum + bNum))
    
set aCount to aCount + 1
  end repeat
  
  
return hitArray
end searchWordWithRange

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings to RTF
  
set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
– Build Path
  
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

–2D迷路を作成して脱出経路を検索して文字列で迷路データを出力する
–迷路サイズ x,y スタート座標 x, y ゴール座標 x,y
on create2DMazeAndSolveIt(xMax, yMax, xStart, yStart, xGoal, yGoal)
  set myBoard to Board2D’s alloc()’s init()
  
myBoard’s setupBoardWithRows:xMax WithColumns:yMax –60×60ぐらいが上限。正方形でないとダメ
  
myBoard’s createMazeFromBoard()
  
  
set myPathfinder to Pathfinder’s alloc()’s init()
  
set myPath to myPathfinder’s findPathThroughMaze:myBoard fromX:xStart fromY:yStart toX:xGoal toY:yGoal
  
  
set aCount to myPath’s |count|()
  
if aCount > 0 then
    set aRes to myBoard’s drawPathThroughMaze:myPath
    
return aRes as string
  else
    return false
  end if
end create2DMazeAndSolveIt

★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/06/16 指定PDFの最初のページに大量のスクウェアアノテーションを添付する

指定PDFの最初のページに大量のスクウェアアノテーションを添付するAppleScriptです。

他のGUIアプリケーションを併用せずQuartz Frameworkの機能を利用して、PDFに対するアノテーションの添付を行います。

square_anno1.png

PDFのアノテーションまわりはmacOS 10.13で大幅に変更されているため、本Scriptがそのまま10.13上でも動作することは期待していません。

AppleScript名:指定PDFの最初のページに大量のスクウェアアノテーションを添付する
– Created 2017-06-16 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”
–http://piyocast.com/as/archives/4688

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Select PDF”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

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

set firstPage to (aPDFdoc’s pageAtIndex:0)

–Remove Annotation
my removeAnnotationFromPage:firstPage –Call by Reference

–Get PDF size by Point
set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxMediaBox)
set aSize to |size| of aBounds

–Add Annotation
repeat with xNum from 30 to ((width of aSize) - 30) by 50
  repeat with yNum from 30 to ((height of aSize) - 30) by 50
    set squAnn to (current application’s PDFAnnotationSquare’s alloc()’s initWithBounds:{origin:{x:xNum, y:yNum}, |size|:{width:40, height:40}})
    (
squAnn’s setValue:(current application’s NSColor’s blueColor()) forAnnotationKey:(current application’s kPDFAnnotationKey_Color))
    (
squAnn’s setValue:(current application’s NSColor’s clearColor()) forAnnotationKey:(current application’s kPDFAnnotationKey_InteriorColor))
    (
firstPage’s addAnnotation:squAnn)
  end repeat
end repeat

–Save It
aPDFdoc’s writeToFile:aPOSIX

–Remove All Annotation from a Page. Call by Reference
on removeAnnotationFromPage:aPage
  set anoList to (aPage’s annotations()) as list
  
repeat with i in anoList
    (aPage’s removeAnnotation:i)
  end repeat
end removeAnnotationFromPage:

★Click Here to Open This Script 

2017/05/27 書式つきテキストを組み立てて、クリップボードに設定(影をつける)

書式つきテキスト(NSAttributedString)を組み立てて、クリップボードに設定するAppleScriptの改良版です。影(NSShadow)の追加指定を行ってみました。

stylet2.png

AppleScript名:書式つきテキストを組み立てて、クリップボードに設定(影をつける)
– Created 2017-05-26 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/4664

set anAttrStr to makeRTFfromParameters("ぴよまるソフトウェア", 2.0, 36) of me

set attrList to {anAttrStr}
restoreClipboard(attrList) of me –set the clipboard to rtf_data

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, outlineNum as real, aFontSize as real)
  –フォント
  
set aVal1 to current application’s NSFont’s fontWithName:"HiraKakuStdN-W8" |size|:aFontSize
  
set aKey1 to (current application’s NSFontAttributeName)
  
  
–色
  
set aVal2 to current application’s NSColor’s blackColor()
  
set aKey2 to (current application’s NSForegroundColorAttributeName)
  
  
–カーニング
  
set aVal3 to -2.0
  
set akey3 to (current application’s NSKernAttributeName)
  
  
–アンダーライン
  
set aVal4 to 0
  
set akey4 to (current application’s NSUnderlineStyleAttributeName)
  
  
–リガチャ
  
set aVal5 to 2 –全てのリガチャを有効にする
  
set akey5 to (current application’s NSLigatureAttributeName)
  
  
–枠線(アウトライン)
  
set aVal6 to outlineNum
  
set akey6 to (current application’s NSStrokeWidthAttributeName)
  
  
–Shadow
  
set aVal7 to current application’s NSShadow’s alloc()’s init()
  
aVal7’s setShadowOffset:(current application’s CGSizeMake(1.0, 1.0)) –影のサイズ
  
aVal7’s setShadowColor:(current application’s NSColor’s blackColor()) –影の色
  
aVal7’s setShadowBlurRadius:2.0 –ぼかしの半径
  
set akey7 to (current application’s NSShadowAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey6, akey7}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aVal6, aVal7}
  
set attrsDictionary to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to current application’s NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
  
end makeRTFfromParameters

–From Shane Stanley’s Book "Everyday AppleScriptObjC"
on restoreClipboard(theArray as list)
  set thePasteboard to current application’s NSPasteboard’s generalPasteboard()
  
thePasteboard’s clearContents()
  
thePasteboard’s writeObjects:theArray
end restoreClipboard

★Click Here to Open This Script 

2017/05/26 書式つきテキストを組み立てて、クリップボードに設定

書式つきテキスト(NSAttributedString)を組み立てて、クリップボードに設定するAppleScriptです。

作成した書式つきテキストは、そのままKeynoteなどのアプリケーションにペーストして利用することが可能です。グラフィックではないため、アプリケーション上での再編集や影の指定、色の変更などが可能です。

styles.png

Keynoteでアウトライン文字を使いたいことはままあるので、このように手軽にクリップボードに転送して利用できると実用性が高いことでしょう。

後日談:という紹介をしたら、KeynoteのヘビーユーザーからKeynoteのGUI上からアウトライン文字の書式を指定できることを教えてもらいました。

AppleScript名:書式つきテキストを組み立てて、クリップボードに設定
– Created 2017-05-26 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/4662

set anAssrStr to makeRTFfromParameters(“ぴよまるソフトウェア”, 3.0, 72) of me

set attrList to {anAssrStr}
restoreClipboard(attrList) of me –set the clipboard to rtf_data

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, outlineNum as real, aFontSize as real)
  –フォント
  
set aVal1 to current application’s NSFont’s fontWithName:“HiraKakuStdN-W8″ |size|:aFontSize
  
set aKey1 to (current application’s NSFontAttributeName)
  
  
–色
  
set aVal2 to current application’s NSColor’s blueColor()
  
set aKey2 to (current application’s NSForegroundColorAttributeName)
  
  
–カーニング
  
set aVal3 to -2.0
  
set akey3 to (current application’s NSKernAttributeName)
  
  
–アンダーライン
  
set aVal4 to 0
  
set akey4 to (current application’s NSUnderlineStyleAttributeName)
  
  
–リガチャ
  
set aVal5 to 2 –全てのリガチャを有効にする
  
set akey5 to (current application’s NSLigatureAttributeName)
  
  
–枠線(アウトライン)
  
set aVal6 to outlineNum
  
set akey6 to (current application’s NSStrokeWidthAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey6}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aVal6}
  
set attrsDictionary to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to current application’s NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
  
end makeRTFfromParameters

–From Shane Stanley’s Book “Everyday AppleScriptObjC”
on restoreClipboard(theArray as list)
  set thePasteboard to current application’s NSPasteboard’s generalPasteboard()
  
thePasteboard’s clearContents()
  
thePasteboard’s writeObjects:theArray
end restoreClipboard

★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/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/04/19 NSColorからCIColorを作成

NSColorからCIColorを作成するAppleScriptです。

CoreImageの各種フィルタを利用して画像加工するさいに、色オブジェクトを指定するフィルタがいくつかあります。その際に指定するのがCIColor。そのため、NSColorからCIColorを求めるサンプルを書いてみました。

ただ、パラメータを指定してCIColorを作ってみても、たいして難しくもなんともないんですね(汗)

AppleScript名:NSColorからCIColorを作成
– Created 2017-04-19 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”
use framework “AppKit”
–http://piyocast.com/as/archives/4591

set redValue to 0
set greenValue to 0
set blueValue to 1
set alphaVlaue to 1.0

set aNSColor to current application’s NSColor’s colorWithCalibratedRed:redValue green:greenValue blue:blueValue alpha:alphaVlaue
set aCIColor to current application’s CIColor’s alloc()’s initWithColor:aNSColor
–>  (CIColor) (0 0 1 1)

★Click Here to Open This Script 

AppleScript名:値を指定してCIColorを作成
– Created 2017-04-19 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/4591

set redValue to 0
set greenValue to 0
set blueValue to 1
set alphaVlaue to 1.0

set aCIColor to current application’s CIColor’s alloc()’s initWithRed:redValue green:greenValue blue:blueValue alpha:alphaVlaue
–>  (CIColor) (0 0 1 1)

★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/04 256×3のグラフ画像を縦方向に拡大する

先日掲載した「GPUImage.frameworkを利用して指定画像が真っ白かを判定する」AppleScriptで、GPUImage.frameworkの明度ヒストグラムの出力画像を加工するために作成したAppleScriptです。

→ 改良版を掲載しています「256×3のグラフ画像を縦方向に拡大する v2」

256×3ドットという、

2906be82-598a-4dbf-86ec-efe081461ade.png

掲載に難のあるグラフィック。これをそのまま掲載するだけでもよかったのですが、HTMLタグで無理やりサイズを変更。

2906be82-598a-4dbf-86ec-efe081461ade.png

これでだいぶ見やすくはなったものの、Webブラウザ側で不要なスムージング処理をしてしまうようで、意図したようには表示されません。

1つだけPhotoshopで加工してみた(盛大にコピペ)のですが、あまりの作業の不毛さに、2つ以上作るのは勘弁してほしいという内容でした。

そこで作成したのが本Scriptです(ザ・作り捨てScript)。本当に256×90の黒い画像を作成し、指定のヒストグラム画像からデータ表示部分の内容を縦方向に拡大します。

実際にためして驚いたのが、指定サイズのNSImageを作成してそのままNSBitmapImageRepに変換すれば指定サイズのビットマップ画像が得られると思っていたのに、missing valueが返ってきたこと。仕方なく本当に(黒く)塗りつぶしています。

atest3.png

GPUImage.frameworkを使っているわけでもないし、普通に漫然とループ処理でドット単位の塗りつぶしを行なっているだけなので、処理には数秒待たされます。もう少しうまいやりかたもありそうですが、数秒程度なら許容範囲でしょう。掲載資料作成用の作り捨てScriptだし。

AppleScript名:256×3のグラフ画像を縦方向に拡大する
– Created 2017-03-03 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/4504

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
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:(anImage’s TIFFRepresentation())

set bImage to current application’s NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))

–描画実行(黒くぬりつぶし)
set fillColor to current application’s NSColor’s blackColor()
bImage’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()
bImage’s unlockFocus() –描画ここまで

set bRawImg to current application’s NSBitmapImageRep’s imageRepWithData:(bImage’s TIFFRepresentation())

–元画像から色情報読み取り
set origData to {}
repeat with i from 0 to 255
  set origColor to (aRawimg’s colorAtX:i y:1)
  
set the end of origData to origColor
end repeat

–新規作成画像をぬりつぶし
repeat with yNum from 1 to 88
  repeat with xNum from 0 to 255
    set anItem to item (xNum + 1) of origData
    (
bRawImg’s setColor:anItem atX:xNum y:yNum)
  end repeat
end repeat

set newImg to current application’s NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
newImg’s addRepresentation:bRawImg

set newFilePath to POSIX path of (choose file name)
saveNSImageAtPathAsPNG(newImg, newFilePath)

–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 

2016/05/31 デスクトップピクチャを白いピクチャとトグルで差し替え

ソフトウェアの説明書などを作る際に、ウィンドウやメニューなどの画面のスクリーンショットを撮ることが多々あります。そのような場合に、一時的にデスクトップピクチャを白い色にしておきたいことがあります。通常デスクトップピクチャと白いピクチャの切り替えを行うAppleScriptです。

普通にスクリプトエディタで本スクリプトをオープンしておいて、実行するたびにトグルで状態が切り替わります。

img_3596_resized.png
▲通常のデスクトップピクチャの表示状態

img_3597_resized.png
▲スクリーンショットを撮るために背景を白い画像に設定した状態

AppleScript名:デスクトップピクチャを白いピクチャとトグルで差し替え
– Created 2016-05-31 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

property aSwitch : false
property desktopPictures : {}
property aColpath : “”

if aSwitch = false then
  –デスクトップを白くする
  
set desktopPictures to getDesktopPicturePathList() of me
  
–白い画像を作成してデスクトップピクチャに設定
  
set aColpath to makeColordImageToTmp(255, 255, 255, 255) of me –R,G,B,A(それぞれ 0〜255)
  
setDesktopPicture(aColpath) of me
  
set aSwitch to true
else
  –保存しておいたDesktop Pictureのリストを戻す
  
setDesktopPicturePathList(desktopPictures) of me
  
do shell script “rm -f “ & quoted form of aColpath
  
set aSwitch to false
end if

–デスクトップピクチャの状態を復帰する
on setDesktopPicturePathList(aliasList)
  if aliasList = {} then
    display notification “保存しておいたデスクトップピクチャのリストが空になっています”
    
return
  end if
  
  
tell application “System Events”
    set dCount to count every desktop
    
repeat with i from 1 to dCount
      set j to contents of item i of aliasList
      
tell desktop i
        set picture to (POSIX path of j)
      end tell
    end repeat
  end tell
end setDesktopPicturePathList

–デスクトップピクチャの強制指定
on setDesktopPicture(aPathStr)
  tell application “System Events”
    set picture of every desktop to aPathStr
  end tell
end setDesktopPicture

–デスクトップピクチャのパスをaliasリストで取得
on getDesktopPicturePathList()
  set pList to {}
  
tell application “System Events”
    set dCount to count every desktop
    
repeat with i from 1 to dCount
      tell desktop i
        set aPic to (picture as POSIX file) as alias
        
set end of pList to aPic
      end tell
    end repeat
  end tell
  
return pList
end getDesktopPicturePathList

–テンポラリフォルダに指定色の画像を作成
on makeColordImageToTmp(rDat as integer, gDat as integer, bDat as integer, aDat as integer)
  set rCol to 255 / rDat
  
set gCol to 255 / gDat
  
set bCol to 255 / bDat
  
set aCol to 255 / aDat
  

  
set aColor to current application’s NSColor’s colorWithDeviceRed:rCol green:gCol blue:bCol alpha:aCol
  
set aDesktopPath to current application’s NSString’s stringWithString:(POSIX path of (path to temporary items))
  
set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.png”)
  
set aRes to makeImageWithFilledWithColor(1, 1, savePath, aColor) of me
  
return (savePath as string)
end makeColordImageToTmp

–指定サイズの画像を作成し、指定色で塗ってファイル書き出し
on makeImageWithFilledWithColor(aWidth, aHeight, outPath, fillColor)
  –Imageの作成  
  
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() –描画ここまで
  
  
–生成した画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
  
–書き出しファイルパス情報を作成
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –成功ならtrue、失敗ならfalseが返る
  
end makeImageWithFilledWithColor

★Click Here to Open This Script 

2015/11/26 動的にテキストビューを表示

動的にNSTextViewを作成してログ表示するAppleScriptです。

textview1.png

Script Editor上でControl+Command+Rで、ASObjC Explorer 4上では「Run in Foreground」をチェックして実行する必要があります。

AppleScript名:ASOCでテキストビューを表示
– Created 2015-11-25 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set aWidth to 400
set aHeight to 600
set aColor to current application’s NSColor’s colorWithDeviceRed:0.0 green:0.0 blue:0.0 alpha:1.0
set aTitle to “テキストビューのじっけん/TextView Test”
set outText to “ぴよまるソフトウェア / Piyomaru Software “

set aScroll to current application’s NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
set aView to current application’s NSTextView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))

set aStr to current application’s NSMutableString’s alloc()’s init()

aView’s setRichText:true
aView’s useAllLigatures:true
aView’s setTextColor:(current application’s NSColor’s cyanColor())

aView’s setBackgroundColor:aColor
aScroll’s setDocumentView:aView
aView’s enclosingScrollView()’s setHasVerticalScroller:true

set aWin to makeWinWithView(aScroll, aWidth, aHeight, aTitle, 0.8)
aWin’s makeKeyAndOrderFront:(missing value)
aWin’s makeFirstResponder:aView

repeat with i from 1 to 100
  set bStr to (current application’s NSMutableString’s stringWithString:(outText & (i as string) & return))
  
set aStr to (bStr’s stringByAppendingString:aStr)
  (
aView’s setString:aStr)
end repeat

my closeWin:aWin

–make Window for Input
on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle, alphaV)
  set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {aWinWidth, aWinHeight}}
  
set aBacking to current application’s NSTitledWindowMask –NSBorderlessWindowMask
  
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 setAlphaValue:alphaV –append
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
aWin’s makeKeyAndOrderFront:(me)
  
  
– Set Custom View
  
aWin’s setContentView:aView
  
  
return aWin
  
end makeWinWithView

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

★Click Here to Open This Script 

2015/08/20 ASOCで動的にWindowを作成

Cocoaの機能を用いて動的にWindowを作成し、メッセージを表示したあとにWindowを消すAppleScriptです。

dispcustomwin.png

Mac OS X登場当時から、こうしたカスタムメッセージ表示用の部品の必要性がひろくscripterに認識されており、さまざまな実装が試されたなか・・・OS Xのnotification center(display notificationでAppleScriptからも表示可能)に集約されていったという歴史があります。

notification.png

オリジナルは、edama2さんの「Okaeri(シンプル版)」のコードで、そこから大幅に機能を簡略化し、当時のCocoa AppleScript Appletから、OS X 10.10上のAppleScriptObjC向けに書き換えたものです。

dispcustomwin2_resized.png

AppleScript側から汎用的にメッセージを表示させるサブルーチンに変更してみました。かなり手軽に使えます。ASOCはARC環境で動いているので、Windowオブジェクトを明示的にReleaseしてあげる必要はないはずですが・・・さて?

# 連続して実行すると3回目に表示がおかしくなるのは、、、何か足りないかも、、、まだ油断できないレベルです

Shaneから「foreground/main threadから実行する必要があるよ」という指摘があり、ASObjC Explorer 4では問題なく連続して何回でも実行できることを確認。Script EditorだとCommand-Control-Rを実行して、表示がすぐに消えたりやっぱり3回目にScript Editorごとクラッシュしたりと不思議な現象が(ーー;;;

AppleScript名:ASOCで動的にWindowを作成
– Created 2012-06-13 by edama2
– Modified 2015-08-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

if not (current application’s NSThread’s isMainThread()) as boolean then
  display alert “This script must be run from the main thread (Command-Control-R in Script Editor).” buttons {“Cancel”} as critical
  
error number -128
end if

set aWin to makeWinWithMessage(“Piyomaru Software”, “Custom Message From Takaaki Naganoya”)
tell current application
  delay 5
end tell
my closeWin:aWin

–ウィンドウを作成
on makeWinWithMessage(aTitle, aMes)
  
  
set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {800, 250}}
  
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) –’s autorelease()
  
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:true
  
aWin’s setLevel:(current application’s NSNormalWindowLevel)
  
aWin’s setOpaque:false
  
aWin’s setReleasedWhenClosed:true
  
aWin’s |center|()
  
aWin’s makeKeyAndOrderFront:(me)
  
  
– Custom View
  
set aCustView to current application’s NSView’s alloc()
  
aCustView’s initWithFrame:aFrame
  
aCustView’s setNeedsDisplay:true
  
set {origin:{x:x, y:y}, |size|:{width:w, height:h}} to aCustView’s |bounds|()
  
aWin’s setContentView:aCustView
  
  
– Text View
  
set aTV2 to current application’s NSTextView’s alloc()
  
  
set titleHeight to 26
  
set y2 to h - titleHeight - (titleHeight / 6)
  
set y3 to h - titleHeight
  
set y3 to h - y3 - (y3 / 6)
  
  
aTV2’s initWithFrame:{{0, y3}, {w, y2}}
  
aTV2’s insertText:aMes
  
aTV2’s setAlignment:(current application’s NSCenterTextAlignment)
  
aTV2’s setDrawsBackground:false
  
aTV2’s setEditable:false
  
aTV2’s setFont:(current application’s NSFont’s fontWithName:“HiraMinPro-W3″ |size|:72)
  
aTV2’s setSelectable:false
  
aTV2’s setTextColor:(current application’s NSColor’s blackColor())
  
aCustView’s addSubview:aTV2
  
  
–aWin’s setBackgroundColor:(current application’s NSColor’s clearColor())
  
  
return aWin
  
end makeWinWithMessage

–ウィンドウを閉じる
on closeWin:aWindow
  delay 3
  
repeat with n from 10 to 1 by -1
    (aWindow’s setAlphaValue:n / 10)
    
delay 0.02
  end repeat
  
aWindow’s |close|()
end closeWin:

★Click Here to Open This Script 

2015/08/12 ASOCでScript Editorの構文色分け情報を設定ファイルから取り出す v2

Cocoaの機能を用いて、AppleScriptの構文色分け(色+フォント)情報が入っているplistから情報を取り出し、RGBの各8ビットの値のリストにまとめるAppleScriptです。

NSDeviceRGBColorからRGBの各値を取り出すテストを行ったものです。

AppleScript名:ASOCでScript Editorの構文色分け情報を設定ファイルから取り出す v2
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set AppleScriptFontFile to “~/Library/Preferences/com.apple.applescript.plist”
set aRec to retDictFromPlist(AppleScriptFontFile) of me

set asAttr to AppleScriptSourceAttributes of aRec
set colList to {}
set aMAX to 255 –or 65535 (AS Color は0〜65535 あまり意味はないが、、、)

repeat with i in asAttr
  set aCol to NSColor of i
  
–>  {{(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.568627 0.156863 0.564706 1….}
  
set aColO to (current application’s NSUnarchiver’s unarchiveObjectWithData:aCol)
  
set the end of colList to retColListFromNSColor(aColO, aMAX)
end repeat
colList
–aMAX=255の場合
–> {{128, 0, 128}, {95, 94, 94}, {14, 62, 251}, {120, 52, 203}, {252, 42, 28}, {0, 0, 0}, {145, 82, 17}, {18, 18, 18}, {39, 201, 201}, {15, 62, 251}, {31, 182, 252}, {129, 58, 217}, {93, 54, 146}, {9, 55, 187}, {8, 55, 187}, {9, 55, 186}, {86, 55, 189}, {52, 32, 99}}

–aMax=65535の場合
–> {{32768, 0, 32768}, {24415, 24158, 24158}, {3598, 15934, 64507}, {30840, 13364, 52171}, {64764, 10794, 7196}, {0, 0, 0}, {37265, 21074, 4369}, {4721, 4721, 4721}, {10023, 51657, 51657}, {3855, 15934, 64507}, {7967, 46774, 64764}, {33153, 14906, 55769}, {23901, 13878, 37522}, {2313, 14135, 48059}, {2056, 14135, 48059}, {2313, 14135, 47802}, {22102, 14135, 48573}, {13364, 8224, 25443}}

–Read plist as record
on retDictFromPlist(aPath as text)
  set thePath to current application’s NSString’s stringWithString:aPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict as record
end retDictFromPlist

–NSColorからrgbの8bitの値を取り出す
on retColListFromNSColor(aCol, aMAX as integer)
  set aRed to round ((aCol’s redComponent()) * aMAX) rounding as taught in school
  
set aGreen to round ((aCol’s greenComponent()) * aMAX) rounding as taught in school
  
set aBlue to round ((aCol’s blueComponent()) * aMAX) rounding as taught in school
  
return {aRed, aGreen, aBlue}
end retColListFromNSColor

★Click Here to Open This Script 

2015/08/04 ASOCで画像+文字作成テスト_v2

Cocoaの機能を用いて指定サイズの単色塗り画像を作成し、指定の文字列を描画してPNG形式の画像ファイルに書き出すAppleScriptの別バージョンです。

test3.png
▲こんな画像(test.png)がデスクトップに書き出されます

多くの場合、バージョンアップすると機能を増やしたり強化したりしていますが、このv2は初版と機能面で差はありません。出力される画像の色やサイズを変更していることには、とくに意味はありません。

本件についてShane Stanleyと週をまたいでメールのやりとりをしていて、ようやく「なるほど」という落着点を見出せたので掲載にいたっています。

今をさかのぼること10年以上昔、Classic Mac OSの時代に、AppleScriptのサブルーチン(ハンドラ)呼び出しなどで参照渡し(call by reference)によるデータのやりとりを行っていました。当時はまだCPUも遅く、AppleScriptの処理系もいまほど高速ではなかったので、高速化手法のひとつとして参照渡しは割と使われていたテクニックでした。

AppleScript名:参照渡しのテスト
set aList to {1, 2, 3}
modList(aList)
log aList
–> {1, 2, 3, 4}

–Call By Reference
on modList(someList)
  set end of someList to 4
end modList

★Click Here to Open This Script 

ただ、プログラムがわかりにくくなる上にバグが入り込む隙間が大きいので、自分は当時から各種サブルーチンを「値渡し」(call by value)で記述するようにスタイルを固定して今日にいたっています。おかげで、巨大なプログラムを作っても割とトラブル知らずでやってこれたように思います(偏見)。

AppleScript名:値渡しのテスト
set aList to {1, 2, 3}
set aList to modList(aList)
log aList
–> {1, 2, 3, 4}

–Call By Value
on modList(someList)
  set newList to {}
  
copy someList to newList –deep copy
  
set end of newList to 4
  
return newList
end modList

★Click Here to Open This Script 

今回、Shaneが「こういう書き方はどう?」と提案してきた書き方は、この「参照渡し」によるものでしたが、てっきり

 「Cocoaのオブジェクト生成はAppleScriptの範疇とは別で管理されている(ものもある)のか?」

と勘違いしてしまったものでした(MacScripterでたまに見かける記述で、首をひねっていた)。ここ、自分は間違って理解していたので、あえて自分の勘違いも含めて書いておきます。

Shaneによる変更点は、_蔀呂良分の塗りのグラフィックを生成 のあとの、 ▲哀薀侫ックに文字を塗りで描画する の部分で,離哀薀侫ック(aImage1)をハンドラに渡したあと、実行結果を変数aImage1に受け取っている部分です(参照渡し)。

Shaneがここで、判読しにくくなる危険をおかしてでも参照渡しでデータをやりとりした理由は、

「本来は同じ値の変数で処理の段階が異なるものが複数存在していた場合、間違って最新のもの以外を利用してしまう危険が発生する。なるべく同じデータであれば1つの変数に格納しておくべき」

というものでした。メモリー使用量の削減には効果は大してなく、処理速度の問題でもない、と。

内容と使うべき理由について、よく理解できたので掲載しておきます(でも、自分は使用済みゴミ変数を撒き散らしつつ値渡しで書くでしょう、、、)。

海外のMLやBBS(とくに、MacScripter.net)でこのような書き方が見られるケースがありますので、参考にしてください。

AppleScript名:ASOCで画像+文字作成テスト_v2
– Created 2015-07-31 by Takaaki Naganoya
– Modified 2015-08-01 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set aWidth to 400.0 –幅
set aHeight to 200.0 –高さ
set outPath to “~/Desktop/test.png” –書き出し先のファイルパス
set fillColor to current application’s NSColor’s blackColor –塗り色
set drawColor to current application’s NSColor’s whiteColor –文字色
set aText to “ぴよまるソフトウェア”
set {xPos, yPos} to {1, 5}

–新規画像を作成して背景を塗る
set aImage1 to makeImageWithFilledColor(aWidth, aHeight, outPath, fillColor) of me

–画像に文字を塗る(参照渡し(call by reference)で、結果はaImage1に入る)
drawStringsOnImage(aImage1, aText, “HiraKakuStd-W8″, 36.0, drawColor, xPos, yPos) of me

–ファイル保存
set aRes to saveImageRepAtPathAsPNG(aImage1, outPath) of me

–画像のうえに指定の文字を描画して画像を返す
on drawStringsOnImage(anImage, aText, aFontName, aPoint, drawColor)
  
  
set aString to current application’s NSString’s stringWithString:aText
  
set aDict to current application’s NSDictionary’s dictionaryWithObjects:{current application’s NSFont’s fontWithName:aFontName |size|:aPoint, drawColor} forKeys:{current application’s NSFontAttributeName, current application’s NSForegroundColorAttributeName}
  
set imageSize to anImage’s |size|()
  
set textSize to aString’s sizeWithAttributes:aDict
  
set xPos to ((width of imageSize) - (width of textSize)) / 2
  
set yPos to ((height of imageSize) - (height of textSize)) / 2
  
–文字描画開始
  
anImage’s lockFocus()
  
aString’s drawAtPoint:(current application’s NSMakePoint(xPos, yPos)) withAttributes:aDict
  
anImage’s unlockFocus()
  
end drawStringsOnImage

–指定サイズの画像を作成し、背景を指定色で塗る
on makeImageWithFilledColor(aWidth, aHeight, outPath, fillColor)
  
  
–Imageの作成  
  
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 makeImageWithFilledColor

–画像を指定パスにPNG形式で保存
on saveImageRepAtPathAsPNG(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 saveImageRepAtPathAsPNG

★Click Here to Open This Script 

2015/07/31 ASOCで画像作成テスト

Cocoaの機能を用いて指定サイズの単色塗り画像(PNG形式)のファイルを書き出すAppleScriptです。

test.png
▲こんな画像がデスクトップに書き出されます

AppleScript名:画像作成テスト
– Created 2015-07-29 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set aWidth to 400.0 –幅
set aHeight to 200.0 –高さ
set outPath to “~/Desktop/test.png” –書き出し先のファイルパス
set fillColor to current application’s NSColor’s greenColor –塗り色

set aRes to makeImageWithFilledWithColor(aWidth, aHeight, outPath, fillColor) of me
–> true

–指定サイズの画像を作成し、指定色で塗ってファイル書き出し
on makeImageWithFilledWithColor(aWidth, aHeight, outPath, fillColor)
  
  
–Imageの作成  
  
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()
  
–描画ここまで
  
  
–生成した画像のRaw画像を作成
  
set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value))
  
  
  
–書き出しファイルパス情報を作成
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
  
–書き出し
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
  
return aRes –成功ならtrue、失敗ならfalseが返る
  
end makeImageWithFilledWithColor

★Click Here to Open This Script 

2014/12/14 AppleScriptのカラーフォーマットを読み込む

Script Editorで設定したAppleScriptの構文色分けのフォーマットを読み込むAppleScriptです。

as_editor.png
▲Piyomaru Softwareが使用しており、本Blogにも反映させている構文色分け設定。似た色でも個別に識別できるよう、わざわざRGB値を微妙に変えてある

このように、Script Editor上で指定したカラー値(R、G、B)、フォント名、フォントサイズ(point)をまとめて返します。

オリジナルはShaneがAppleScript Users MLに投稿したScript(AppleScript Libraries用)だったのですが、普通のAppleScriptで使いやすいように(若干)書き換えました。

同様の機能を持つルーチンをCocoaの機能を使わずに(数年前に)実現していたのですが、このようにまっとうな方法で調査ができるのであれば、安心感がアップします。

# 実際に既存のAppleScript(構文カラーリングを検出して、構文要素区分にもとづいた処理を行うもの)に入れ替えてみたら・・・設定値と実際のカラー値が合わないらしくて、そのままでは使えませんでした。もう少し調べてみる必要があるようで、、、

AppleScript名:AppleScriptのカラーフォーマットを読み込む
– Created 2013-11-11 by Shane Stanley
– Changed 2014-12-14 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set cList to getAppleScriptSourceColors()
–> {{redValue:145, greenValue:40, blueValue:144, fontName:”Osaka”, fontSize:12.0}, {redValue:95, greenValue:94, blueValue:94, fontName:”Osaka”, fontSize:12.0}, {redValue:14, greenValue:62, blueValue:251, fontName:”Osaka”, fontSize:12.0}, {redValue:120, greenValue:52, blueValue:203, fontName:”Osaka”, fontSize:12.0}, {redValue:252, greenValue:42, blueValue:28, fontName:”Osaka”, fontSize:12.0}, {redValue:0, greenValue:0, blueValue:0, fontName:”Osaka”, fontSize:12.0}, {redValue:145, greenValue:82, blueValue:17, fontName:”Osaka”, fontSize:12.0}, {redValue:0, greenValue:0, blueValue:0, fontName:”Osaka”, fontSize:12.0}, {redValue:39, greenValue:201, blueValue:201, fontName:”Osaka”, fontSize:12.0}, {redValue:15, greenValue:62, blueValue:251, fontName:”Osaka”, fontSize:12.0}, {redValue:31, greenValue:182, blueValue:252, fontName:”Osaka”, fontSize:12.0}, {redValue:129, greenValue:58, blueValue:217, fontName:”Osaka”, fontSize:12.0}, {redValue:93, greenValue:54, blueValue:146, fontName:”Osaka”, fontSize:12.0}, {redValue:9, greenValue:55, blueValue:187, fontName:”Osaka”, fontSize:12.0}, {redValue:8, greenValue:55, blueValue:187, fontName:”Osaka”, fontSize:12.0}, {redValue:9, greenValue:55, blueValue:186, fontName:”Osaka”, fontSize:12.0}, {redValue:86, greenValue:55, blueValue:189, fontName:”Osaka”, fontSize:12.0}, {redValue:52, greenValue:32, blueValue:99, fontName:”Osaka”, fontSize:12.0}}

–AppleScriptの構文色分けのカラー値をRGBで取得する
on getAppleScriptSourceColors()
  
  
– get the info as a dictionary
  
set thePath to current application’s NSString’s stringWithString:“~/Library/Preferences/com.apple.applescript.plist”
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theInfo to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
  
– extract relevant part and loop through
  
set theArray to (theInfo’s valueForKey:“AppleScriptSourceAttributes”) as list
  
  
set colList to {}
  
  
repeat with i from 1 to count of theArray
    set anEntry to item i of theArray
    
    
set colorData to NSColor of anEntry
    
set theColor to (current application’s NSUnarchiver’s unarchiveObjectWithData:colorData)
    
    
set rVal to round ((theColor’s redComponent()) * 255) rounding down
    
set gVal to round ((theColor’s greenComponent()) * 255) rounding down
    
set bVal to round ((theColor’s blueComponent()) * 255) rounding down
    
    
    
set fontData to NSFont of anEntry
    
set theFont to (current application’s NSUnarchiver’s unarchiveObjectWithData:fontData)
    
    
set aFontName to theFont’s displayName() as text
    
set aFontSize to theFont’s pointSize()
    
    
set aColRec to {redValue:rVal, greenValue:gVal, blueValue:bVal, fontName:aFontName, fontSize:aFontSize}
    
    
set the end of colList to aColRec
  end repeat
  
  
return colList
end getAppleScriptSourceColors

★Click Here to Open This Script 

2014/12/02 画像中の色数をカウント

画像中の色数をカウントするAppleScriptの試作品です。

ASOCの機能を使って、色数のカウントを行いますが・・・1024 x 768ピクセル程度の「かわいらしいサイズ」の画像であっても、すべてのピクセルを処理しようとすると、78万アイテム程度のデータを処理する必要があるため、10万アイテムをメドに処理するべき/するべきではないという判断を行うならば、「そのままでは処理すべきではない」ということに。

本Scriptは、画像の一部分だけを取り出して色数のカウントを行います。

色数のカウントについては、画像の間引きや中間調部分の除去などの前処理を行うべきであり、実ファイルを直接調べるような、乱暴な処理で行うべきものではないと考えます。とはいえ、こうした処理に手が届きそうになってきたことは体感できるのではないかと。

普通はPhotoshopなどで処理すべきでしょう。ただ、色数カウントという処理は割と骨が折れそうで、、、

AppleScript名:画像中の色数をカウント
– Created 2014-12-01 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “AppKit”

script spd
  property aColList : {}
end script

set aColList of spd to {}

–画像を選択して読み込む
set a to choose file of type {“public.image”}

set aURL to current application’s SMSFord’s URLFrom:a
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL

–画像のサイズ(幅、高さ)をピクセル数で取得する
set aSize to aImage’s |size|()
set aWidth to aSize’s width()
set aHeight to aSize’s height()

–読み込んだ画像のRaw画像を作成
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:(aImage’s TIFFRepresentation())

–画像の一部のピクセルの色を取り出して色数をカウント
repeat with xNum from 0 to ((aWidth as integer) - 1)
  –repeat with yNum from 0 to ((aHeight as integer) - 1)
  
repeat with yNum from 0 to 10
    
    
set origColor to (aRawimg’s colorAtX:xNum y:yNum)
    
set srgbColSpace to current application’s NSColorSpace’s deviceRGBColorSpace
    
    
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
    
set aAlpha to (aColor’s alphaComponent()) * 255
    
    
set oneCol to {aRed as integer, aGreen as integer, aBlue as integer, aAlpha as integer}
    
    
set the end of aColList of spd to oneCol
    
  end repeat
end repeat

–ユニーク化
set aArray to current application’s NSArray’s arrayWithArray:(aColList of spd)
set bArray to aArray’s valueForKeyPath:“@distinctUnionOfObjects.self”

set bList to bArray’s ASify() as list
length of bList

★Click Here to Open This Script 

2014/12/02 画像の特定のピクセルの色を取得

指定画像を読み込んで、特定のピクセルの色を読み取るAppleScriptです。

画像を読み取るといった処理は、Xcode上でAppleScriptObjCのアプリケーションを作成している時にはよく書きますが、Script Editor上で書くAppleScriptObjCだと新鮮な感じがあります。

とくにWindow上に表示したりはしないのですが、実際に読み込んで色のピックアップができているような気がします。ただ、見えないので本当に合っているのかはもうちょっと試行錯誤を、、、

AppleScriptだけで(Photoshopなどを使わないで)画像処理を行うためのテストの一環で行ってみました。キャプチャ画像のリサイズぐらいは、Cocoaの機能だけで行っておきたいところです。

AppleScript名:画像の特定のピクセルの色を取得
– Created 2014-12-01 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "ASObjCExtras"
use framework "AppKit"

–画像を選択して読み込む
set a to choose file of type {"public.image"}

set aURL to current application’s SMSFord’s URLFrom:a
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL

–画像のサイズ(幅、高さ)をピクセル数で取得する
set aSize to aImage’s |size|()
set aWidth to aSize’s width()
set aHeight to aSize’s height()

–読み込んだ画像のRaw画像を作成
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:(aImage’s TIFFRepresentation())

–画像中の{0, 0}のピクセルの色をRGBAそれぞれ取り出す
set origColor to (aRawimg’s colorAtX:0 y:0)
set srgbColSpace to current application’s NSColorSpace’s deviceRGBColorSpace

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
set aAlpha to (aColor’s alphaComponent()) * 255

set oneCol to {aRed as integer, aGreen as integer, aBlue as integer, aAlpha as integer}
–> {255, 255, 255, 218} – sample

★Click Here to Open This Script 

2013/09/09 AppleScriptObjCでNSBoxのタイトル文字の色を変更する

AppleScriptObjCで、NSBoxのタイトル文字の色を変更するサンプルです。

海外のBlogやMailing Listの過去ログを見たかぎりでは、「できない」という投稿が多かったのですが………単に色を指定しただけでは色は変わらず、タイトル文字の変更を行うと「色」+「タイトル」が変わるようです。

またひとつ、つまらないテクニックを見つけてしまいました……。

box1.png

AppleScriptObjCファイル名:AppDelegate.applescript

– AppDelegate.applescript
– boxTest

– Created by Takaaki Naganoya on 2013/09/09.
– Copyright (c) 2013年 Takaaki Naganoya. All rights reserved.


script AppDelegate
  property parent : class “NSObject”
  
property aBox : missing value
  
  on applicationWillFinishLaunching_(aNotification)
    
    tell current application’s NSColorList to set AppleColors to colorListNamed_(“Apple”)
    
set redColor to AppleColors’s colorWithKey_(“Red”)
    
aBox’s setTitle_(“ぴよぴよ〜”)
    
aBox’s titleCell’s setTextColor_(redColor)
    
  end applicationWillFinishLaunching_
  
  on applicationShouldTerminate_(sender)
    – Insert code here to do any housekeeping before your application quits
    
return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/12/28 AppleScriptObjCでボタンの文字色を変更

最初はAppleScriptObjCでWindowのタイトルの文字色を変更できないか試していたのですが、それが(かなり組まないと)ムリだと気付き……逆に、簡単に文字色を変更できるGUI部品がないかテストした試作品です。

NSAttributedStringがどのGUI部品に対して設定可能なのか、APIのドキュメントをキーワード検索して調べました。

coloredb.png

NSTextFieldの中身は当然として、NSButtonのほかNSMenuの内容などに色つき文字(NSAttributedString)を指定できることが分り、とりあえず調査はこのぐらいにしておきました。試作プロジェクトの「WindowTitleTest」はWindowのタイトル色を変更できないか試していた頃の名残りです。

→ Xcodeプロジェクトのダウンロード

AppleScriptObjCファイル名:AppDelegate.applescript

– AppDelegate.applescript
– windowTitleTest

– Created by Takaaki Naganoya on 2012/12/25.
– Copyright (c) 2012年 Takaaki Naganoya. All rights reserved.
– original http://www.macscripter.net/viewtopic.php?id=38088

script AppDelegate
  
  property parent : class “NSObject”
  
  property nsc : class “NSColor”
  
  property tf : missing value
  
property aWin : missing value
  
property aButton : missing value
  
  
  on applicationWillFinishLaunching_(aNotification)
    
    –set colorArray to current application’s NSArray’s arrayWithObjects_(nsc’s redColor(),nsc’s orangeColor(),nsc’s yellowColor(),nsc’s greenColor(),nsc’s blueColor,nsc’s purpleColor(),missing value)
    
    
    tell current application’s NSColorList to set AppleColors to colorListNamed_(“Apple”)
    
set redColor to AppleColors’s colorWithKey_(“Red”)
    
tell current application’s NSFont to set myFont to fontWithName_size_(“HiraKakuPro-W6″, 24)
    
    set attrsDict to current application’s NSDictionary’s dictionaryWithObjects_forKeys_({myFont, redColor}, {current application’s NSFontAttributeName, current application’s NSForegroundColorAttributeName})
    
tell current application’s NSAttributedString to set aString to alloc()’s initWithString_attributes_(“色つき文字を設定できるGUI部品のテスト”, attrsDict)
    
    
    tf’s setAttributedStringValue_(aString) –NSTextField
    
aButton’s setAttributedTitle_(aString) –NSButton
    
  end applicationWillFinishLaunching_
  
  
  on applicationShouldTerminate_(sender)
    – Insert code here to do any housekeeping before your application quits
    
return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/06/13 おかえり(シンプル版)

読者の方(edama2さん)からの投稿です。以前に私がAppleScript Studioで作成して公開していた(る?)、スリープ解除検知&ユーザー通知アプリケーション「おかえり」の簡略版をMac OS X 10.7から作れるようになったAppleScriptエディタベースのAppleScriptObjCで作られました。

yyyeyoyycyaye-2012-06-13-02922.jpeg

yyyeyoyycyaye-2012-06-10-235739.jpeg

投稿していただいてから公開するまでに時間がかかってしまいましたが……実は、AppleScriptエディタベースのASOCのHTML書き出しツールを用意していなかったためで……ようやく、書き出し用のツール(AppleScriptで記述)を準備しました。

——
<edama2さんより>
今日のネタは「おかえり(シンプル版)」です。なかなか更新されない「おかえり」にいらだちを覚え、ついに自分で作り……というのは冗談で、「Cocoa-applescript aplet」の習作として作ってみました。

スリープの復帰の通知を受け取り、半透明のウインドウの表示と音を鳴らすだけです。誕生日とか正月だけの特別なウィンドウはありません。

ウインドウの色と音を変更できるようにしたいところですが、Xcodeを使わずコードだけでウィンドウを作るのは結構面倒だったのとシンプル版ということで省略しました。オリジナルの「おかえり」から「Twentieth Anniversary Macintosh.aiff」だけ使用させていただきました。

最初、同じスプリクト内にカスタムビューのコード(MyView.scpt)を書いていたのですが、初期化の際にエラーが出て難儀しました。どうやら別ファイルにしないと上手く初期化してくれないようです。

作成は10.7.4、テストは10.7.4と10.6.8でしました。ASOC Scriptの新規作成は10.7.4でないとできませんが、編集は書き方によっては10.6.8でもできました。

→ アプレット(編集可能)のダウンロード
</edama2さんより>

スクリプト名:おかえり(シンプル版)
property _sound_name : “Twentieth Anniversary Macintosh”

on run
  #通知の登録
  
tell current application’s NSWorkspace’s sharedWorkspace()
    tell notificationCenter()
      addObserver_selector_name_object_(me, “okaeri:”, “NSWorkspaceScreensDidWakeNotification”, missing value)
    end tell
  end tell
end run

on quit
  current application’s NSNotificationCenter’s defaultCenter()’s removeObserver_(me)
  
continue quit
end quit

#ウィンドウを表示→待機→閉じる
on okaeri_(sender)
  set pool to current application’s NSAutoreleasePool’s new() –>意味があるかよくわからないけどとりあえず。
  
  
copy makeWin() to okaeriWindow
  
  
set filePath to current application’s NSBundle’s mainBundle()’s pathForResource_ofType_(_sound_name, “aiff”)
  
current application’s NSSound’s alloc()’s initWithContentsOfFile_byReference_(filePath, true)’s play()
  
  
delay 5
  
  
closeWin_(okaeriWindow)
  
  
pool’s drain() –release()
end okaeri_

#ウィンドウを作成
on makeWin()
  set aScreen to current application’s NSScreen’s mainScreen()
  
set aFrame to {{0, 0}, {800, 250}}
  
set aBacking to current application’s NSBorderlessWindowMask
  
set aDefer to current application’s NSBackingStoreBuffered
  
  
tell current application’s NSWindow’s alloc()
    tell initWithContentRect_styleMask_backing_defer_screen_(aFrame, aBacking, aDefer, false, aScreen)’s autorelease()
      
      
#カスタムビュー
      
tell current application’s MyView’s alloc()
        tell initWithFrame_(aFrame)
          setNeedsDisplay_(true)
          
set aView to it
        end tell
      end tell
      
      
set {origin:{x:x, y:y}, |size|:{width:w, height:h}} to contentView()’s |bounds|()
      
set titleHeight to 26
      
set y2 to h - titleHeight - (titleHeight / 6)
      
      
#タイトルバー
      
set messageText to “スリープ復帰を検出しました(” & (current date) & “)” as text
      
tell current application’s NSTextView’s alloc()
        tell initWithFrame_({{0, y2}, {w, titleHeight}})
          insertText_(messageText)
          
setAlignment_(current application’s NSCenterTextAlignment)
          
setDrawsBackground_(false)
          
setEditable_(false)
          
setFont_(current application’s NSFont’s titleBarFontOfSize_(13))
          
setSelectable_(false)
          
setTextColor_(current application’s NSColor’s whiteColor())
          
aView’s addSubview_(it)
        end tell
      end tell
      
      
set y3 to h - titleHeight
      
set y3 to h - y3 - (y3 / 6)
      
      
#メッセージビュー
      
set myName to current application’s NSProcessInfo’s processInfo()’s environment()’s valueForKey_(”LOGNAME”) as text
      
set messageText to myName & “さん” & return & “おかえりなさい”
      
tell current application’s NSTextView’s alloc()
        tell initWithFrame_({{0, y3}, {w, y2}})
          insertText_(messageText)
          
setAlignment_(current application’s NSCenterTextAlignment)
          
setDrawsBackground_(false)
          
setEditable_(false)
          
setFont_(current application’s NSFont’s fontWithName_size_(”HiraMinPro-W3″, 72))
          
setSelectable_(false)
          
setTextColor_(current application’s NSColor’s whiteColor())
          
aView’s addSubview_(it)
        end tell
      end tell
      
      
#ウィンドウの設定
      
setBackgroundColor_(current application’s NSColor’s clearColor())
      
setContentView_(aView)
      
setDelegate_(me)
      
setDisplaysWhenScreenProfileChanges_(true)
      
setHasShadow_(true)
      
setIgnoresMouseEvents_(not false)
      
setLevel_((current application’s NSScreenSaverWindowLevel) + 10000)
      
setOpaque_(false)
      
setReleasedWhenClosed_(true)
      
|center|()
      
makeKeyAndOrderFront_(me)
      
      
return it
    end tell
  end tell
end makeWin

#ウィンドウを閉じる
on closeWin_(aWindow)
  tell aWindow
    repeat with n from 10 to 1 by -1
      setAlphaValue_(n / 10)
      
delay 0.02
    end repeat
    
|close|()
  end tell
end closeWin_

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

スクリプト名:MyView
script MyView
  property parent : class “NSView”
  
  
on drawRect_(rect)
    
    
–log my |bounds|()
    
set {origin:{x:x, y:y}, |size|:{width:w, height:h}} to my |bounds|()
    
set titleHeight to 26
    
    
set thePath to current application’s NSBezierPath’s bezierPath()
    
    
#タイトルバー
    
set aFrame to {{0, h - titleHeight}, {w, titleHeight}}
    
set aPath to current application’s NSBezierPath’s bezierPathWithRect_(aFrame)
    
set strartColor to current application’s NSColor’s blackColor()’s colorWithAlphaComponent_(0.4)
    
set endColor to current application’s NSColor’s blackColor()’s colorWithAlphaComponent_(0.8)
    
tell current application’s NSGradient’s alloc()
      tell initWithStartingColor_endingColor_(strartColor, endColor)
        drawInBezierPath_angle_(aPath, 270)
      end tell
    end tell
    
thePath’s appendBezierPath_(aPath)
    
    
#メッセージ
    
set aFrame to {{0, 0}, {w, h - titleHeight}}
    
set aPath to current application’s NSBezierPath’s bezierPathWithRect_(aFrame)
    
set strartColor to current application’s NSColor’s blueColor()’s colorWithAlphaComponent_(0.4)
    
set endColor to current application’s NSColor’s blueColor()’s colorWithAlphaComponent_(0.8)
    
tell current application’s NSGradient’s alloc()
      tell initWithStartingColor_endingColor_(strartColor, endColor)
        drawInBezierPath_angle_(aPath, 270)
      end tell
    end tell
    
thePath’s appendBezierPath_(aPath)
    
  end drawRect_
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

スクリプト名:CocoaAppletAppDelegate.scpt

– CocoaAppletAppDelegate.applescript
– Cocoa-AppleScript Applet

– Copyright 2011 {Your Company}. All rights reserved.

– This application delegate emulates the OSA script applet by loading “main.scpt” from the
– “Scripts” folder in the application resources and invoking the traditional run/open/reopen/quit
– handlers in response to Cocoa application delegate methods being called.

– This is provided in source form so that you may customize or replace it if your needs go
– beyond the basic applet handlers.

– Some of these methods must guard against re-entrancy, because invoking the main.scpt
– handler may end up invoking the event handler inherited from the current application,
– which calls the application delegate’s method again.

script CocoaAppletAppDelegate
  property parent : class “NSObject”
  
property mainScript : missing value – the applet’s main.scpt
  
property didOpenFiles : false – true = the application opened documents during startup
  
property isOpeningFiles : false – re-entrancy guard: true = in the process of opening files
  
property isReopening : false – re-entrancy guard: true = in the process of re-opening
  
property isQuitting : false – re-entrancy guard: true = in the process of quitting
  
  
on applicationWillFinishLaunching_(aNotification)
    – Insert code here to initialize your application before any files are opened
    
    
– Emulate an OSA Applet: Load the main script from the Scripts resource folder.
    
try
      set my mainScript to load script (path to resource “main.scpt” in directory “Scripts”)
    on error errMsg number errNum
      – Perhaps this should silently fail if it can’t load the script; that way, a Cocoa applet
      
– can just have Cocoa classes and no main.scpt.
      
display alert “Could not load main.scpt” message errMsg & ” (” & errNum & “)” as critical
    end try
  end applicationWillFinishLaunching_
  
  
on applicationDidFinishLaunching_(aNotification)
    – Insert code here to do startup actions after your application has initialized
    
    
if mainScript is missing value then return
    
    
– Emulate an OSA Applet: Invoke the “run” handler.
    
    
– If we have already opened files during startup, don’t invoke the run handler.
    
if didOpenFiles then return
    
    
try
      tell mainScript to run
    on error errMsg number errNum
      if errNum is not -128 then
        display alert “An error occurred while running” message errMsg & ” (” & errNum & “)” as critical
      end if
    end try
    
    
– TODO: Read the applet’s “stay open” flag and quit if it’s false or unspecified.
    
– For now, all Cocoa Applets stay open and require the run handler to explicitly quit,
    
– which is arguably more correct for a Cocoa application, anyway.
    
(* if not shouldStayOpen then
      quit
    end if *)
  end applicationDidFinishLaunching_
  
  
on applicationShouldHandleReopen_hasVisibleWindows_(sender, flag)
    – Insert code here to perform actions in response to a “reopen” event
    
    
if mainScript is missing value then return true
    
    
– Guard against re-entrancy.
    
if not isReopening then
      set isReopening to true
      
      
– Emulate an OSA Applet: Invoke the “reopen” handler. If there isn’t one, let the application object
      
– handle reopen (this is different from an OSA applet, which would do nothing if there is no handler;
      
– this way, the application will perform the usual “create untitled document” behavior by default).
      
try
        tell mainScript to reopen
        
set isReopening to false
        
        
return false
      on error errMsg number errNum
        if errNum is not -128 then
          display alert “An error occurred while reopening” message errMsg & ” (” & errNum & “)” as critical
        end if
      end try
      
      
set isReopening to false
    end if
    
    
return true
  end applicationShouldHandleReopen_hasVisibleWindows_
  
  
on application_openFiles_(sender, filenames)
    – Insert code here to perform actions in response to an “open documents” event
    
    
– Remember that we opened files, to avoid invoking the “run” handler later.
    
set didOpenFiles to true
    
    
– Guard against re-entrancy.
    
if not isOpeningFiles and mainScript is not missing value then
      set isOpeningFiles to true
      
      
try
        – Convert all the filenames from NSStrings to script strings
        
set theFilenameStrings to {}
        
repeat with eachFile in filenames
          set theFilenameStrings to theFilenameStrings & (eachFile as text)
        end repeat
        
        
tell mainScript to open theFilenameStrings
        
set isOpeningFiles to false
        
        
tell sender to replyToOpenOrPrint_(current application’s NSApplicationDelegateReplySuccess)
      on error errMsg number errNum
        if errNum = -128 then
          tell sender to replyToOpenOrPrint_(current application’s NSApplicationDelegateReplyCancel)
        else
          display alert “An error occurred while opening file(s)” message errMsg & ” (” & errNum & “)” as critical
          
tell sender to replyToOpenOrPrint_(current application’s NSApplicationDelegateReplyFailure)
        end if
      end try
      
      
set isOpeningFiles to false
    else
      tell sender to replyToOpenOrPrint_(current application’s NSApplicationDelegateReplyFailure)
    end if
  end application_openFiles_
  
  
on applicationShouldTerminate_(sender)
    – Insert code here to do any housekeeping before your application quits
    
    
– Guard against re-entrancy.
    
if not isQuitting and mainScript is not missing value then
      set isQuitting to true
      
      
– Emulate an OSA Applet: Invoke the “quit” handler; if the handler returns, it has fully
      
– handled the quit message and we should not quit, otherwise, it calls “continue quit”,
      
– which returns error -10000.
      
try
        tell mainScript to quit
        
set isQuitting to false
        
        
return current application’s NSTerminateCancel
      on error errMsg number errNum
        – -128 means there is no quit handler
        
– -10000 means the handler did “continue quit”
        
if errNum is not -128 and errNum is not -10000 then
          display alert “An error occurred while quitting” message errMsg & ” (” & errNum & “)” as critical
        end if
      end try
      
      
set isQuitting to false
    end if
    
    
return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

オリジナルの「おかえり」のコアコードは10行ぐらいで、このサンプルよりもはるかに単純な原理で動いています。
いまから10年近く前にすでに動いていたもので、オリジナルコードはAppleScriptだけで記述。公開版は透明ウィンドウを付けるため(だけ)にAppleScript Studioで開発しました。

「おかえり」のアップデートが止まっていたのは、自分が欲しい機能をてんこ盛りに盛り込んで……画面をInterface Builder上でデザインした時点で「こんなに大量のGUI部品のコードを書くのは大変」なことに気づき……そのまま放置状態に陥ってしまったためでしょう(Piyocastをはじめ、個人的な優先順位の高い自作の未公開アプリがいくつもあるので)。

アプリが自分自身のコード量で自滅した、といえなくもありません。

当時は、Mac AppStoreも存在していませんでしたし、フリーで配布するにはバージョンアップに手がかかりすぎる自作ソフト群にうんざりしていた、ということもあります。

いまだったら、AppleScriptObjCならGUI部品のサポートコードを書くのもそれほど手間ではないので、バージョンアップして公開してみてもよいかもしれません。

2012/03/07 テキストへの色指定サンプル

テキストに色指定を行うサンプルのAppleScriptObjCプログラムです。

textcol.jpg

AppleScriptObjCファイル名:textcolorTestAppDelegate.applescript

– textcolorTestAppDelegate.applescript
– textcolorTest

– Created by 長野谷 隆昌 on 12/02/13.
– Copyright 2012 Piyomaru Software. All rights reserved.

script textcolorTestAppDelegate
  
property parent : class “NSObject”
  
  
property nsc : class “NSColor”
  
property tf : missing value
  
property aTextField : missing value
  
  
on applicationWillFinishLaunching_(aNotification)
    
    
–ひとつめのNSTextField(入力フィールド)
    
set aString to current application’s NSMutableAttributedString’s alloc()’s initWithString_(“これはテスト用の文字列ですよー”)
    
    
set colorArray to current application’s NSArray’s arrayWithObjects_(nsc’s redColor(), nsc’s orangeColor(), nsc’s yellowColor(), nsc’s greenColor(), nsc’s blueColor, nsc’s purpleColor(), missing value)
    
    
repeat with i from 0 to (aString’s |length|()) - 1
      
aString’s addAttribute_value_range_(current application’s NSForegroundColorAttributeName, colorArray’s objectAtIndex_(i mod 6), {i, 1})
    
end repeat
    
    
tf’s setAttributedStringValue_(aString)
    
    
    
–ふたつめのNSTextField(Label)
    
set bString to current application’s NSMutableAttributedString’s alloc()’s initWithString_(“●私のユーザー名”)
    
    
set colorArray to current application’s NSArray’s arrayWithObjects_(nsc’s redColor(), nsc’s blackColor())
    
    
set bLen to bString’s |length|()
    
    
bString’s addAttribute_value_range_(current application’s NSForegroundColorAttributeName, colorArray’s objectAtIndex_(0), {0, 1})
    
bString’s addAttribute_value_range_(current application’s NSForegroundColorAttributeName, colorArray’s objectAtIndex_(1), {1, (bLen - 1)})
    
    
aTextField’s setAttributedStringValue_(bString)
    
  
end applicationWillFinishLaunching_
  
  
  
  
on applicationShouldTerminate_(sender)
    
return current application’s NSTerminateNow
  
end applicationShouldTerminate_
  
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/03/07 指定のRGBカラーをGeneric CMYKプロファイルでCMYKに変換して……RGB値を取得

指定のRGBカラー値をGeneric CMYKプロファイルを用いてCMYK変換し、CMYK値を取り出そうとして……できなかったので仕方なくRGB値を取り出したAppleScriptObjCのプログラムです。

上のColorWellをクリックして任意の色(ここではライトグリーン)を選択。

asoc1.jpg

「Convert RGB to CMYK」ボタンをクリックすると、Mac OS XのGeneric CMYK Profileに基づいてCMYK変換を行い、下のColorWellに色を設定します。

asoc2.jpg

いい感じのCMYKっぽい色に変換されるのですが、ここからCMYK値を取り出すのに失敗(なんでだ〜)。仕方なくRGB値を取り出しています。

→ プロジェクトのダウンロード(Xcode 4.1 on Mac OS X 10.6.8)

AppleScriptObjCファイル名:rgb2cmykAppDelegate.applescript

– rgb2cmykAppDelegate.applescript
– rgb2cmyk

– Created by 長野谷 隆昌 on 12/01/26.
– Copyright 2012 Piyomaru Software. All rights reserved.

– generic CMYK color Spaceを用いて、RGB→CMYK変換を行い、ColorWellにCMYKベースで色をセットしたあとRGB値でその色を取り出す
– 

script rgb2cmykAppDelegate
  
  
property parent : class “NSObject”
  
  
property rgbWell : missing value
  
property rgbR : missing value
  
property rgbG : missing value
  
property rgbB : missing value
  
  
property cmykWell : missing value
  
property cmykC : missing value
  
property cmykM : missing value
  
property cmykY : missing value
  
property cmykK : missing value
  
  
  
on applicationWillFinishLaunching_(aNotification)
    
– Insert code here to initialize your application before any files are opened
  
end applicationWillFinishLaunching_
  
  
on applicationShouldTerminate_(sender)
    
– Insert code here to do any housekeeping before your application quits
    
return current application’s NSTerminateNow
  
end applicationShouldTerminate_
  
  
  
  
on clicked_(sender)
    
    
–RGB Color Wellのカラー値を読み取って、TextFieldに文字を入れる
    
set {rNum, gNum, bNum, aNum} to retColData(rgbWell)
    
    
set rNumStr to (rNum as integer) as string
    
set gNumStr to (gNum as integer) as string
    
set bNumStr to (bNum as integer) as string
    
    
rgbR’s setStringValue_(rNumStr)
    
rgbG’s setStringValue_(gNumStr)
    
rgbB’s setStringValue_(bNumStr)
    
    
    
–RGB Colorwellからカラーを読み取る
    
set tmpColor to rgbWell’s |color|
    
    
–Generic ProfileでRGB to CMYK変換してColorWellに設定
    
set cmykColSpace to current application’s NSColorSpace’s genericCMYKColorSpace
    
set color1 to tmpColor’s colorUsingColorSpace_(cmykColSpace)
    
    
    
–cmykWell’s setColor_(color1)
    
tell cmykWell
      
setColor_(color1)
    
end tell
    
    
    
–とりあえずRGBAでデータを取り出してみる
    
set {temp21, temp22, temp23, temp24} to retColData(cmykWell)
    
    
set temp21 to temp21 as string
    
set temp22 to temp22 as string
    
set temp23 to temp23 as string
    
set temp24 to temp24 as string
    
    
–TextFieldにCMYKデータを入れる
    
cmykC’s setStringValue_(temp21)
    
cmykM’s setStringValue_(temp22)
    
cmykY’s setStringValue_(temp23)
    
cmykK’s setStringValue_(temp24)
    
  
end clicked_
  
  
  
  
–指定オブジェクトのカラー値を取得する
  
on retColData(aObject)
    
    
–色空間のコンバートを行ってカラー値を取得する(強制的にRGB)
    
set tmpColor to aObject’s |color|
    
set color1 to tmpColor’s colorUsingColorSpaceName_(current application’s NSCalibratedRGBColorSpace)
    
    
set temp11 to color1’s redComponent()
    
set temp12 to color1’s greenComponent()
    
set temp13 to color1’s blueComponent()
    
set temp14 to color1’s alphaComponent()
    
    
–RGBAの並びでデータを返す
    
set TheColor to {(temp11 * 255) as integer, (temp12 * 255) as integer, (temp13 * 255) as integer, (temp14 * 255) as integer}
    
    
return TheColor
  
end retColData
  
  
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に