iOS/iPhone/iPad/MacOSX プログラミング, Objective-C, Cocoaなど
2011年2月4日金曜日 | Published in Objective-C, Xcode 3.2.5 | 6 コメント
shizaru says: 2011年2月14日 21:13
最新の記事にコメントをつけさせてもらおうと思ったら、すごい力作まとめの記事だったのでちょっと前の記事にコメントさせてもらいます。いつもSimpleCapにお世話になってます。また、「(旧)Cocoaの日々」の2008年初頭あたりの記事からじっくり読ませてもらって、プログラミングの勉強をしているため、もっぱらxcatsanさんは私にとって「師匠」にあたる存在であります。ここまでがごあいさつ。さて本題。CGWindowListCreateImage()だと、「アクティブでないSpacesのWorkspaceにあるアプリケーション」をキャプチャできない、が正解でしょうか。自作プログラムでどうしてもできないので、SimpleCapの「アプリケーション」メニューからキャプチャの動作を調べたところ、SimpleCapでもキャプチャできない現象が起きました。つまり、1,Spacesの「2」をアクティブにした状態で、2,Spacesの「1」にあるアプリを3,SimpleCapのメニューの「アプリケーション」からキャプチャしようとすると4,キャプチャに失敗するという現象です。これは私の環境(iMac27inch 2010late、OSX10.6.6)でだけの現象でありましょうか。
xcatsan says: 2011年2月15日 17:17
こんにちは shizaru さん。橋口です。2008年初頭からというと旧ブログが始まって間もないころで、ちょうど SimpleCap 開発が始まる前ぐらいですね。ありがとうございますwさて質問の件ですが SimpleCap の場合、CGWindowListCreateImage() の第2引数に kCGWindowListOptionOnScreenOnly を指定しています。これが為に指摘された動きになっています。つまり Spaces で非アクティブなスクリーンにあるウィンドウは Off Screen 扱いになる為、上記オプション(On Screen Only)指定時にはキャプチャができません。なので、もし kCGWindowListOptionOnScreenOnly を指定している場合はそれを外してみてください。Spaces で非アクティブなスクリーン上にあるウィンドウもキャプチャできると思います。#ただ Off Screen にあるウィンドウは見えないことをいいことに(?)#ちゃんと描画されていないかもしれません。この辺りは試したことが#無いのでちょっとわかりません。結果が出たら是非教えてくださいね。では。
shizaru says: 2011年2月15日 19:16
ど素人のくだらない質問に親切に答えていただいてありがとうございます。手元で試したところ、非アクティブなWorkspaceのアプリは第2引数になにを指定してもだめなようです。アクテイブなWorkspaceの該当rectをキャプチャするか、空のイメージしかできない模様。勉強になりました。ありがとうございました。早く新Cocoaの日々のお世話になれるよう、精進したいと思います。
xcatsan says: 2011年2月16日 14:44
shizaru さん、こんにちは。駄目でしたか。。私の方でも気になって SimpleCap をいじって少し試してみました。結果、できました。ただ SimpleCapでは CGWindowListCreateImage ではなく、CGWindowListCreateImageFromArray を使っています。SimpleCap のアプリケーションキャプチャは次のような動きになっています。1. CGWindowListCopyWindowInfo でウィンドウ一覧を取得2. タイマー起動3. カウント0になったら CGWindowListCreateImageFromArray で1.のウィンドウをキャプチャCGWindowListCreateImageFromArray にはキャプチャしたいウィンドウのCGWindowID 配列を渡します。アプリケーションキャプチャの場合は、1. の CGWindowListCopyWindowInfo で一旦すべてのウィンドウのリストを取得した後、対象のアプリケーションのウィンドウだけに絞り込んでおきます。タイマー終了時にこれを 3 の関数へ渡して最終的なキャプチャ画像を作ります(実際には複数のイメージを重ねて加工していますが、基本は上記の動きです)。この 1. のCGWindowListCopyWindowInfoは次のような呼び出しになっています。 CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListOptionOnScreenOnly|kCGWindowListOptionOnScreenBelowWindow|kCGWindowListExcludeDesktopElements), window_id);ここに昨日話しました kCGWindowListOptionOnScreenOnly を使っています。kCGWindowListOptionOnScreenBelowWindow も on screen 指定の一種ですね。そこで試しにそれらを外してリストを作るようにしてみました。 CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListExcludeDesktopElements), window_id);するとアプリケーションキャプチャで非アクティブなワークスペース上にあるウィンドウをキャプチャすることができました。- - - -なお CGWindowListCreateImage の場合でも非アクティブなワークスペースにあるウィンドウの CGWIndowID が取れて"OnScreen"系のオプションを外せばキャプチャできるかもしれません。参考までに。では。
shizaru says: 2011年2月16日 20:02
うわー、師匠の貴重な時間をとってもらってすみません。ていねいな説明ありがとうございます。私の場合はCFArrayRef list =CGWindowListCopyWindowInfo( kCGWindowListOptionAll , kCGNullWindowID);で作ったリストを、if (CFDictionaryContainsKey(w, kCGWindowWorkspace)) でオンスクリーンの証拠であるWorkspace番号があるもので絞り、取得したいアプリのPIDでウィンドウを検索してwindowIDを得て、CGImageRef cgimage = CGWindowListCreateImage(rect, kCGWindowListOptionIncludingWindow ,spot_window_id, kCGWindowImageDefault);としています。で、師匠の教えの通りに現在試行中ですが、やっぱ素人なのでまだ成功していません。もう少しがんばってみます。
xcatsan says: 2011年2月18日 6:42
おはようございます。アプローチは間違ってないと思います。CGWindowListCopyWindowInfo で非アクティブな Workspace にあるウィンドウの WindowID が取れていればキャプチャできそうです。SimpleCap との違いは CGWindowListCreateImage を使っているか、CGWindowListCreateImageFromArray を使っているかの違いぐらいですね。原因はなんだろ。
shizaru says:
2011年2月14日 21:13
最新の記事にコメントをつけさせてもらおうと思ったら、すごい力作まとめの記事だったのでちょっと前の記事にコメントさせてもらいます。
いつもSimpleCapにお世話になってます。また、「(旧)Cocoaの日々」の2008年初頭あたりの記事からじっくり読ませてもらって、プログラミングの勉強をしているため、もっぱらxcatsanさんは私にとって「師匠」にあたる存在であります。ここまでがごあいさつ。
さて本題。CGWindowListCreateImage()だと、「アクティブでないSpacesのWorkspaceにあるアプリケーション」をキャプチャできない、が正解でしょうか。自作プログラムでどうしてもできないので、SimpleCapの「アプリケーション」メニューからキャプチャの動作を調べたところ、SimpleCapでもキャプチャできない現象が起きました。
つまり、
1,Spacesの「2」をアクティブにした状態で、
2,Spacesの「1」にあるアプリを
3,SimpleCapのメニューの「アプリケーション」からキャプチャしようとすると
4,キャプチャに失敗する
という現象です。これは私の環境(iMac27inch 2010late、OSX10.6.6)でだけの現象でありましょうか。
shizaru says:
2011年2月14日 21:13
最新の記事にコメントをつけさせてもらおうと思ったら、すごい力作まとめの記事だったのでちょっと前の記事にコメントさせてもらいます。
いつもSimpleCapにお世話になってます。また、「(旧)Cocoaの日々」の2008年初頭あたりの記事からじっくり読ませてもらって、プログラミングの勉強をしているため、もっぱらxcatsanさんは私にとって「師匠」にあたる存在であります。ここまでがごあいさつ。
さて本題。CGWindowListCreateImage()だと、「アクティブでないSpacesのWorkspaceにあるアプリケーション」をキャプチャできない、が正解でしょうか。自作プログラムでどうしてもできないので、SimpleCapの「アプリケーション」メニューからキャプチャの動作を調べたところ、SimpleCapでもキャプチャできない現象が起きました。
つまり、
1,Spacesの「2」をアクティブにした状態で、
2,Spacesの「1」にあるアプリを
3,SimpleCapのメニューの「アプリケーション」からキャプチャしようとすると
4,キャプチャに失敗する
という現象です。これは私の環境(iMac27inch 2010late、OSX10.6.6)でだけの現象でありましょうか。
xcatsan says:
2011年2月15日 17:17
こんにちは shizaru さん。
橋口です。
2008年初頭からというと旧ブログが始まって間もないころで、
ちょうど SimpleCap 開発が始まる前ぐらいですね。
ありがとうございますw
さて質問の件ですが SimpleCap の場合、CGWindowListCreateImage() の
第2引数に kCGWindowListOptionOnScreenOnly を指定しています。
これが為に指摘された動きになっています。つまり Spaces で非アクティブな
スクリーンにあるウィンドウは Off Screen 扱いになる為、上記
オプション(On Screen Only)指定時にはキャプチャができません。
なので、もし kCGWindowListOptionOnScreenOnly を指定している場合は
それを外してみてください。Spaces で非アクティブなスクリーン上に
あるウィンドウもキャプチャできると思います。
#ただ Off Screen にあるウィンドウは見えないことをいいことに(?)
#ちゃんと描画されていないかもしれません。この辺りは試したことが
#無いのでちょっとわかりません。
結果が出たら是非教えてくださいね。
では。
xcatsan says:
2011年2月15日 17:17
こんにちは shizaru さん。
橋口です。
2008年初頭からというと旧ブログが始まって間もないころで、
ちょうど SimpleCap 開発が始まる前ぐらいですね。
ありがとうございますw
さて質問の件ですが SimpleCap の場合、CGWindowListCreateImage() の
第2引数に kCGWindowListOptionOnScreenOnly を指定しています。
これが為に指摘された動きになっています。つまり Spaces で非アクティブな
スクリーンにあるウィンドウは Off Screen 扱いになる為、上記
オプション(On Screen Only)指定時にはキャプチャができません。
なので、もし kCGWindowListOptionOnScreenOnly を指定している場合は
それを外してみてください。Spaces で非アクティブなスクリーン上に
あるウィンドウもキャプチャできると思います。
#ただ Off Screen にあるウィンドウは見えないことをいいことに(?)
#ちゃんと描画されていないかもしれません。この辺りは試したことが
#無いのでちょっとわかりません。
結果が出たら是非教えてくださいね。
では。
shizaru says:
2011年2月15日 19:16
ど素人のくだらない質問に親切に答えていただいてありがとうございます。
手元で試したところ、非アクティブなWorkspaceのアプリは第2引数になにを指定してもだめなようです。アクテイブなWorkspaceの該当rectをキャプチャするか、空のイメージしかできない模様。
勉強になりました。ありがとうございました。早く新Cocoaの日々のお世話になれるよう、精進したいと思います。
shizaru says:
2011年2月15日 19:16
ど素人のくだらない質問に親切に答えていただいてありがとうございます。
手元で試したところ、非アクティブなWorkspaceのアプリは第2引数になにを指定してもだめなようです。アクテイブなWorkspaceの該当rectをキャプチャするか、空のイメージしかできない模様。
勉強になりました。ありがとうございました。早く新Cocoaの日々のお世話になれるよう、精進したいと思います。
xcatsan says:
2011年2月16日 14:44
shizaru さん、こんにちは。
駄目でしたか。。
私の方でも気になって SimpleCap をいじって少し試してみました。
結果、できました。ただ SimpleCapでは CGWindowListCreateImage ではなく、
CGWindowListCreateImageFromArray を使っています。
SimpleCap のアプリケーションキャプチャは次のような動きになっています。
1. CGWindowListCopyWindowInfo でウィンドウ一覧を取得
2. タイマー起動
3. カウント0になったら CGWindowListCreateImageFromArray で1.のウィンドウをキャプチャ
CGWindowListCreateImageFromArray にはキャプチャしたいウィンドウの
CGWindowID 配列を渡します。アプリケーションキャプチャの場合は、
1. の CGWindowListCopyWindowInfo で一旦すべてのウィンドウの
リストを取得した後、対象のアプリケーションのウィンドウだけに
絞り込んでおきます。タイマー終了時にこれを 3 の関数へ渡して最終的なキャプチャ画像を
作ります(実際には複数のイメージを重ねて加工していますが、基本は
上記の動きです)。
この 1. のCGWindowListCopyWindowInfoは次のような呼び出しになっています。
CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListOptionOnScreenOnly|kCGWindowListOptionOnScreenBelowWindow|kCGWindowListExcludeDesktopElements), window_id);
ここに昨日話しました kCGWindowListOptionOnScreenOnly を使っています。kCGWindowListOptionOnScreenBelowWindow も on screen 指定の一種ですね。
そこで試しにそれらを外してリストを作るようにしてみました。
CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListExcludeDesktopElements), window_id);
するとアプリケーションキャプチャで非アクティブなワークスペース上にあるウィンドウをキャプチャすることができました。
- - - -
なお CGWindowListCreateImage の場合でも非アクティブなワークスペースにあるウィンドウの CGWIndowID が取れて"OnScreen"系のオプションを外せばキャプチャできるかもしれません。
参考までに。
では。
xcatsan says:
2011年2月16日 14:44
shizaru さん、こんにちは。
駄目でしたか。。
私の方でも気になって SimpleCap をいじって少し試してみました。
結果、できました。ただ SimpleCapでは CGWindowListCreateImage ではなく、
CGWindowListCreateImageFromArray を使っています。
SimpleCap のアプリケーションキャプチャは次のような動きになっています。
1. CGWindowListCopyWindowInfo でウィンドウ一覧を取得
2. タイマー起動
3. カウント0になったら CGWindowListCreateImageFromArray で1.のウィンドウをキャプチャ
CGWindowListCreateImageFromArray にはキャプチャしたいウィンドウの
CGWindowID 配列を渡します。アプリケーションキャプチャの場合は、
1. の CGWindowListCopyWindowInfo で一旦すべてのウィンドウの
リストを取得した後、対象のアプリケーションのウィンドウだけに
絞り込んでおきます。タイマー終了時にこれを 3 の関数へ渡して最終的なキャプチャ画像を
作ります(実際には複数のイメージを重ねて加工していますが、基本は
上記の動きです)。
この 1. のCGWindowListCopyWindowInfoは次のような呼び出しになっています。
CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListOptionOnScreenOnly|kCGWindowListOptionOnScreenBelowWindow|kCGWindowListExcludeDesktopElements), window_id);
ここに昨日話しました kCGWindowListOptionOnScreenOnly を使っています。kCGWindowListOptionOnScreenBelowWindow も on screen 指定の一種ですね。
そこで試しにそれらを外してリストを作るようにしてみました。
CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListExcludeDesktopElements), window_id);
するとアプリケーションキャプチャで非アクティブなワークスペース上にあるウィンドウをキャプチャすることができました。
- - - -
なお CGWindowListCreateImage の場合でも非アクティブなワークスペースにあるウィンドウの CGWIndowID が取れて"OnScreen"系のオプションを外せばキャプチャできるかもしれません。
参考までに。
では。
shizaru says:
2011年2月16日 20:02
うわー、師匠の貴重な時間をとってもらってすみません。ていねいな説明ありがとうございます。私の場合は
CFArrayRef list =CGWindowListCopyWindowInfo( kCGWindowListOptionAll , kCGNullWindowID);
で作ったリストを、
if (CFDictionaryContainsKey(w, kCGWindowWorkspace))
でオンスクリーンの証拠であるWorkspace番号があるもので絞り、取得したいアプリのPIDでウィンドウを検索してwindowIDを得て、
CGImageRef cgimage = CGWindowListCreateImage(rect, kCGWindowListOptionIncludingWindow ,spot_window_id, kCGWindowImageDefault);
としています。
で、師匠の教えの通りに現在試行中ですが、やっぱ素人なのでまだ成功していません。もう少しがんばってみます。
shizaru says:
2011年2月16日 20:02
うわー、師匠の貴重な時間をとってもらってすみません。ていねいな説明ありがとうございます。私の場合は
CFArrayRef list =CGWindowListCopyWindowInfo( kCGWindowListOptionAll , kCGNullWindowID);
で作ったリストを、
if (CFDictionaryContainsKey(w, kCGWindowWorkspace))
でオンスクリーンの証拠であるWorkspace番号があるもので絞り、取得したいアプリのPIDでウィンドウを検索してwindowIDを得て、
CGImageRef cgimage = CGWindowListCreateImage(rect, kCGWindowListOptionIncludingWindow ,spot_window_id, kCGWindowImageDefault);
としています。
で、師匠の教えの通りに現在試行中ですが、やっぱ素人なのでまだ成功していません。もう少しがんばってみます。
xcatsan says:
2011年2月18日 6:42
おはようございます。
アプローチは間違ってないと思います。
CGWindowListCopyWindowInfo で非アクティブな Workspace にあるウィンドウの WindowID が取れていればキャプチャできそうです。
SimpleCap との違いは CGWindowListCreateImage を使っているか、CGWindowListCreateImageFromArray を使っているかの違いぐらいですね。
原因はなんだろ。
xcatsan says:
2011年2月18日 6:42
おはようございます。
アプローチは間違ってないと思います。
CGWindowListCopyWindowInfo で非アクティブな Workspace にあるウィンドウの WindowID が取れていればキャプチャできそうです。
SimpleCap との違いは CGWindowListCreateImage を使っているか、CGWindowListCreateImageFromArray を使っているかの違いぐらいですね。
原因はなんだろ。