AppleScriptを使って、Illustratorに貼られた画像の拡大縮小率を得るには
ある掲示板に「Illustratorに張られている画像の縮小拡大率をAppleScriptで得るにはどうしたらいいのでしょうか?」という質問が書き込まれていた。
私がみたときはすでにその質問にはほかの方によって回答されていて、問題は解決済みだったのだけど、以前私も同じ問題でつまずいたことがあり、これに引っかかる人は結構多いのかもしれない。
何かの参考になるかもしれないので、私が引っかかったときの経緯と解決方法を記事にしておこうと思う。
あらかじめ申し上げると、私はこの問題の数学的な解決法の部分についてはすべて人から教えてもらった(感謝)。が、私自身は数学はおろか算数ですらおぼつかないレベルであるため、教えていただいた数式について「どうしてそうなるのか」はまったく理解していない(笑)なので、この件について「もっと(数学的に)詳しい説明を!」などと求めないでほしい。
AppleScriptを使って、Illustratorに貼られた画像の拡大縮小率を得るにはどうしたらいいのか?
まずサイズの情報がどこにあるのか考える。サイズの情報は配置画像のpropertiesの中にありそうだ...が、配置画像のpropertiesにはhorizontal scaleといったようなそれらしい値がない。
唯一、サイズに関連しそうなのはMatrixという値。
--配置された画像のmatrixを得る
tell application "Adobe Illustrator"
get matrix of placed item 1 of layer 1 of document 1
end tell
ところがこれがくせ者で、例えば縦80%、横50%、回転-10度の縮小画像のMatrixを得ると、次のような値が返ってくる。
{class:matrix, mvalue_a:0.787846207619, mvalue_b:0.138918548822, mvalue_c:-0.086824089289, mvalue_d:0.492403864861, mvalue_tx:458.30810546875, mvalue_ty:376.57421875}
...なんじゃこりゃ。
Adobeのスクリプトマニュアルには 「変換マトリックスは、線形代数という分野から生まれた、数学的な概念です」とあるので、なにか計算すればここから倍率や回転度数を得られるのだろうけど、...難しい。
こりゃ私には無理だわと、お手上げ状態で頭をかかえてしまったのですが、親切な方から「これはアフィン変換ではないか」との助言とそこから倍率を得る公式を教えていただいた。
mvalue_aが「横方向倍率 × cosθ」
mvalue_bが「横方向倍率 × sinθ」
(cosθ)^2 + (sinθ)^2 = 1
これをExcelの関数で計算すると
横方向倍率=SQRT((mvalue_a)^2+(mvalue_b)^2)
AppleScriptではExcelも制御できるので、この計算もExcelでやらせてもよいのだけれど、Mac OS XならPerlやRuby、JavaScriptを使った方が簡単。
例えばRubyでこの計算を行うと
horizontal_scale = Math.sqrt((mv_a.to_f**2) + (mv_b.to_f**2))##横方向倍率
verticality_scale = Math.sqrt((mv_c.to_f**2) + (mv_d.to_f**2))##縦方向倍率
という感じになる。
これをAppleScriptと組み合わせると
--選択している配置画像の縮小率をとる
tell application "Adobe Illustrator"
set Placed_Item to item 1 of selection
set mv_a to mvalue_a of matrix of Placed_Item
set mv_b to mvalue_b of matrix of Placed_Item
set mv_c to mvalue_c of matrix of Placed_Item
set mv_d to mvalue_d of matrix of Placed_Item
do shell script "ruby -e ' print Math.sqrt((ARGV[0].to_f**2) + (ARGV[1].to_f**2))' " & (mv_a & " " & mv_b)
do shell script "ruby -e ' print Math.sqrt((ARGV[0].to_f**2) + (ARGV[1].to_f**2))' " & (mv_c & " " & mv_d)
end tell
こんな感じ。