スクリプトで「特定ウィンドウのスクリーン・ショット」を取る
iPhone 5s, OS X Mavericks (10.9.3), Mac mini(mid 2011), iMac(late 2009)
AppleScript to take screenshot of a specific area and save to desktop
https://discussions.apple.com/thread/5641587
Mavericks まではリンク先のスクリプトで大丈夫だと思います。
Yosemite では RubyCocoa がなくなった模様。別途インストールする必要があるようです。PyObjC に翻訳する手もありますが Yosemite で動くかは不明。ASOC は全く分かりません。また、Cocoa な部分での仕様がどうなってるかも分かりません。
Hiro.Sさん、
拝見しました。やはり苦手なAppleScriptで困ったと思いましたが、このスクリプトは不思議と解りやすいので、しばし格闘してみます。
# 参考書は中古で入手はしてますので……。
ご教示、有難うございました。
追伸:Yosemite情報も感謝します。ヨウスミテからトライして見ます。
取り敢えず、そのまま動かしてみました 。
なにかスクリーン・ショットは出てきましたが、エラーがでました。
AppleScript Error
/System/Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc/oc_import.rb:192:in `const_missing': uninitialized constant EOF (NameError)
from -:14
上記ディレクトリは存在しているようです;
u1@MmM11:~ $ ll /System/Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc
total 56
-rw-r--r-- 1 root wheel compressed 18K 6 19 01:23 active_record.rb
-rw-r--r-- 1 root wheel compressed 939B 6 19 01:23 application.rb
-rw-r--r-- 1 root wheel compressed 431B 6 19 01:23 cocoa.rb
-rw-r--r-- 1 root wheel compressed 3.3K 6 19 01:23 cocoa_macros.rb
-rw-r--r-- 1 root wheel compressed 1.0K 6 19 01:23 cocoa_macros_appkit.rb
-rw-r--r-- 1 root wheel compressed 576B 6 19 01:23 foundation.rb
-rw-r--r-- 1 root wheel compressed 476B 6 19 01:23 oc_all.rb
-rw-r--r-- 1 root wheel compressed 51K 6 19 01:23 oc_attachments.rb
-rw-r--r-- 1 root wheel compressed 420B 6 19 01:23 oc_attachments_appkit.rb
-rw-r--r-- 1 root wheel compressed 1.4K 6 19 01:23 oc_bundle_support.rb
-rw-r--r-- 1 root wheel compressed 825B 6 19 01:23 oc_exception.rb
-rw-r--r-- 1 root wheel compressed 25K 6 19 01:23 oc_import.rb
-rw-r--r-- 1 root wheel compressed 3.1K 6 19 01:23 oc_types.rb
-rw-r--r-- 1 root wheel compressed 2.1K 6 19 01:23 oc_types_appkit.rb
-rw-r--r-- 1 root wheel compressed 5.0K 6 19 01:23 oc_wrapper.rb
-rw-r--r-- 1 root wheel compressed 3.1K 6 19 01:23 ruby_addition.rb
u1@MmM11:~ $
ご報告まで。
ブラウザは Firefox ですか?であれば Safari でコピーしてみてください。
シェルスクリプト部分を抜き出すとこんな感じ
#!/bin/bash /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby <<'EOF' - "$@" require 'osx/cocoa' include OSX raise AugumentError, "Usage: #{File.basename($0)} x, y, w, h" unless ARGV.length == 4 x, y, w, h = ARGV.map {|a| a.to_f} outfile = File.expand_path(%x[date +'%F %H.%M.%S.png'].chomp, '~/Desktop') img = CGDisplayCreateImageForRect(CGMainDisplayID(), CGRectMake(x, y, w, h)) brep = NSBitmapImageRep.alloc.initWithCGImage(img) data = brep.objc_send( :representationUsingType, NSPNGFileType, :properties, {}) data.objc_send( :writeToFile, outfile, :atomically, false) EOF
実行は
$ ./screenshot x y w h
例
$ ./screenshot 0 0 600 400
ーーーーー
さらに Ruby の部分を抜き出すと
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby require 'osx/cocoa' include OSX raise AugumentError, "Usage: #{File.basename($0)} x, y, w, h" unless ARGV.length == 4 x, y, w, h = ARGV.map {|a| a.to_f} outfile = File.expand_path(%x[date +'%F %H.%M.%S.png'].chomp, '~/Desktop') img = CGDisplayCreateImageForRect(CGMainDisplayID(), CGRectMake(x, y, w, h)) brep = NSBitmapImageRep.alloc.initWithCGImage(img) data = brep.objc_send( :representationUsingType, NSPNGFileType, :properties, {}) data.objc_send( :writeToFile, outfile, :atomically, false)
実行は
$ ./screenshot x y w h
済みません。
修正前
raise AugumentError, "Usage: #{File.basename($0)} x, y, w, h" unless ARGV.length == 4
修正後
raise ArgumentError, "Usage: #{File.basename($0)} x, y, w, h" unless ARGV.length == 4
Hiro.Sさん、
はい、Safari経由でコピペしたら動きました。有難うございました。テキストなのに不思議ですね、
なお、向こうのディスカッションはとても面白かったです。私の好みは「bash&ruby」なので、これもトライしたいです。
AppleScriptの詳しいご説明はこれから拝見します、悪しからず。
Hiro.Sさん、
いろいろな注釈有難うございました。
本家での「bash&ruby」版;
https://discussions.apple.com/thread/5641587
Hiroto Dec 9, 2013 12:28 PM
Re: AppleScript to take screenshot of a specific area and
and save to desktop in response to Tony T1
も触ってみました。
ヒア・ドキュメントの末尾、「END 」から空白x2を削除して「END」とすることで目出度く動作するようになりました。
「bash&ruby」がこのような形式で使えるのは嬉しいです。ここに利用されている「ruby script」からrubyにアプローチしたいと思います。
ご指導に多謝。
ヒア・ドキュメントの末尾、「END 」から空白x2を削除して「END」とすることで目出度く動作するようになりました。
このボードの困った仕様なんですよね。フィードバックはしたんですが、なかなか修正してくれません...。
ところで、スクリーンショットですが、簡単に済ませるなら、screencapture コマンドってのもあります。ご存知かもしれませんが一応。
$ screencapture screenshot.png
$ screencapture -w screenshot.png
$ screencapture -s screenshot.png
Shell Script、Ruby、Ruby Cocoa、AppleScript が使えると可能性は無限大です。頑張ってください。
このボードの困った仕様なんですよね。フィードバックはしたんですが、なかなか修正してくれません...。
このフォーラムに来る人々は「Appleから見ると、釣り上げた魚なので、過剰な餌は控える」のでしょうかね。
私の常用ブラウザではこのフォーラムに書き込めないので、一々、Safariを立ち上げています。まさにシュールな光景です。
ところで、スクリーンショットですが、簡単に済ませるなら、screencapture コマンドってのもあります。ご存知かもしれませんが一応。
そうですね、忘れていました。殆ど「⇧⌘4」を常用しているので、今回のスクリプトをgssとして整備する所存です。
Shell Script、Ruby、Ruby Cocoa、AppleScript が使えると可能性は無限大です。頑張ってください。
「Ruby Cocoa」はX11のRuby版なのでしょうか。すこし探してみます。
AppleScriptはまだ鬼門です、笑い。
# 最近、ネットワークの状態変数をコンパクトに表示するのをbashで作りました。
# grepに正規表現が使えるのを知ったのと、全て関数で書けるようになったので、bashは自称中級になりました。
# 次は、目指せruby初級、です。
追伸:
「ruby script」から
のは、原理的に可能でしょうか?
「Ruby Cocoa」はX11のRuby版なのでしょうか。
違います。
すこし探してみます。
探すも何も Leopard から Mavericks までは標準で入ってます。というか、今回のスクリプトが RubyCocoa ですよ。Yosemite 以降は自分でインストールする必要がありますが、専用のパッケージは未だリリースされてないようです。ちなみに入手は下のリンク先から。
RubyCocoa - A Ruby/Objective-C Bridge
http://rubycocoa.sourceforge.net/
「ruby script」から
- 「System Preferences → Network」を開けて、
- ある(x, y)の位置にそのウインドウの左上端を配置させること。
のは、原理的に可能でしょうか?
やり方はいくつかありますが、AppleScript を呼び出すのが簡単かなと。
RubyCocoa なら NSAppleScript でこんな感じ。
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby require 'osx/cocoa' include OSX cmd = <<'EOS' tell application "System Preferences" activate set current pane to pane "com.apple.preference.network" set {x1, y1, x2, y2} to bounds of window 1 set bounds of window 1 to {0, 22, x2 - x1, y2 - y1 + 22} end tell EOS script = NSAppleScript.alloc.initWithSource(NSString.stringWithCString(cmd)) desc = script.executeAndReturnError(nil)
シェルスクリプトなら osascript でこうでしょうか。
#!/bin/bash osascript <<'OSA' tell application "System Preferences" activate set current pane to pane "com.apple.preference.network" set {x1, y1, x2, y2} to bounds of window 1 set bounds of window 1 to {0, 22, x2 - x1, y2 - y1 + 22} end tell OSA
Snow Leopard では大丈夫ですが、Lion 以降で動くかは全く分かりません。ダメな場合はほかの方の回答を待ってください。
Hiro.Sさん、
詳細なご説明ありがとうございました。
RubyCocoa - A Ruby/Objective-C Bridge
そうですか、存じませんでしたがトライしたいです。
・RubyCocoa なら NSAppleScript でこんな感じ。
・シェルスクリプトなら osascript でこうでしょうか。
なるほど両者同じ雰囲気で利用できるのですね。
ユーザ・インターフェイスに慣れているシェルスクリプトから手をつけてみます。
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.network"
う〜む、このような親子関係が用意されているのか、感動。
こうなってくると現金なもので、AppleScriptの解説本をパラっと拝見すると、とても親しみやすく感じるようになりました。
では、修行に踏み出してみまする。
Hiro.Sさん:
Snow Leopard では大丈夫ですが、Lion 以降で動くかは全く分かりません。ダメな場合はほかの方の回答を待ってください。
Bash版ですが、Mavericksで動きました;
で、パラメータ「0 -> 100」とすると;
となりました。入れ物は右にシフトするのに、内部の部品はとりのこされているようです。面白いことに、この状態でも「Wi-Fi on」にすると、左ペインの表示は追従します。
旨くすると、アプリケーションの内の必要な部分だけを出来るかなあと感じました。
俄然、AppleScriptに興味が湧いてきました。参考図書で良い物が見当たりませんでしたが、有料pdfが判りやすそうなのでトライしてみます。
中間報告まで。
確認ありがとうございます。
旨くすると、アプリケーションの内の必要な部分だけを出来るかなあと感じました。
違います。不正なパラメータを与えたので UI が壊れただけです。正しくはこうです。Y座標も同様。
set bounds of window 1 to {100, 22, x2 - x1 + 100, y2 - y1 + 22}
現在の bounds 値を調べるのは下記。System Preferences のウインドウを移動し、都度 bounds 値を取得すると感覚がつかめると思います。bounds 値とは何かはご自分で調べてください。
tell application "System Preferences" get bounds of window 1 end tell
ちなみに「22」はメニューバーの高さです。自動取得する方法もありますが面倒なので定数扱いとしました。Yosemite では変更されてるような記事をどこかで見かけたので、アップグレードする際は注意してください。
あと、パラメータの正当性をチェックするコードを追加した方が良いのかもしれませんが、本件では System Preferences のウインドウを左上に固定すれば良いわけで、そこまでは必要ないような気がします。
Hiro.Sさん:
確認ありがとうございます。
むしろ弟子の一人として、フィードバックさせていただいているだけです。
違います。不正なパラメータを与えたので UI が壊れただけです。正しくはこうです。Y座標も同様。
set bounds of window 1 to {100, 22, x2 - x1 + 100, y2 - y1 + 22}
よく判りました。何となく、( x1, x2 )=( 10, 22 )と誤解をしていました。早く文法を体で覚える必要がありますね。むしろ、必要な情報は自らグラフィカルに生成できるようになりたいものです。
現在の bounds 値を調べるのは下記。System Preferences のウインドウを移動し、都度 bounds 値を取得すると感覚がつかめると思います。bounds 値とは何かはご自分で調べてください。
はい、承知いたしました。躓くまで、修行に励みます。
スクリプトで「特定ウィンドウのスクリーン・ショット」を取る