25

DirectX ウィンドウの視覚的な出力 (スクリーンショットなど) をキャプチャする必要があります。現在、私はこのアプローチを使用しています。
ただし、ウィンドウがバックグラウンドにある場合は、その前にあるものをすべてキャプチャします。

最小化またはバックグラウンドでも DirectX ウィンドウがレンダリングされることがわかったので、これは可能であるはずです。
しかし、どうやって?(また、高速である必要があり、残念ながら Windows XP でも動作する必要があります...)

編集: 私は最近とても忙しいです... 心配しないでください。有効期限が切れたら賞金を元に戻します。

4

3 に答える 3

25

バックグラウンドにある (または画面外に移動した) Direct3D ウィンドウをキャプチャするには、次のオプションがあると思います。

  1. 既に投稿したリンクまたはこの最新の例(EasyHook はセットアップが難しい場合がありますが、非常にうまく機能します)を介して、ターゲット アプリケーション内に Direct3D を挿入してフックします。動作させるためのヘルプをいつでも求めることができます. 私はこの手法を使用して、多くのゲームを問題なくキャプチャしました (最近では ambilight-clone プロジェクトで使用しました)。このアプローチの問題点は、禁止を引き起こすゲーム保護についてのあなたの懸念ですが、FRAP はこれを達成するためにフッキングも使用するので、あなたの懸念は誇張されているのではないでしょうか? ゲーマーがスクリーンショットを理由に追放されるのは、それを知るための高価な方法だと思います。

  2. Vista/Win 7 のウィンドウ化されたアプリケーションの場合、DWM を挿入してフックし、その共有サーフェスを介してキャプチャ リクエストを行うことができます。私はこれを Vistaで動作させましたが、Windows 7 での動作を完了していません。Windows 7 で動作する例を次に示しますhttp://www.youtube.com/watch?v=G75WKeXqXkc このアプローチの主な問題は、文書化されていない API を使用していることです。これは、Windows パッチのリリース時に警告なしにアプリケーションが壊れることを意味する可能性があります。また、新しい主要な Windows フレーバーごとに手法をやり直す必要があります。これは、Windows XP でのキャプチャの必要性にも対応していません。

  3. また、DWM 内には、サムネイル API があります。これには、何をしようとしているかに応じて制限があります。この API に関する情報は、他の DWM API とともにhttp://blogs.msdn.com/b/greg_schechter/archive/2006/09/14/753605.aspxにあります。

  4. さまざまな DLL をラッパーに置き換えるなど、EasyHook を使用せずに Direct3D 呼び出しをインターセプトする手法は他にもあります。他のさまざまなゲームのフック/インターセプト テクニックは、 http ://www.gamedeception.net/ で見つけることができます。

  5. Direct3D アプリケーションをフォアグラウンドに移動するだけです (これは、あなたの状況では望ましくないと思います)。これは、ウィンドウも移動しない限り、オフスクリーン ウィンドウでは機能しません。

  6. 残念ながら、私が考えることができる Windows XP の唯一の解決策は、何らかの形で Direct3D API をインターセプトすることです。

最小化中の Direct3D レンダリングについての説明です。この問題に関するかなり限定的なテスト中に、これはアプリケーションに依存することがわかりました。通常、アプリケーションが最小化されているときにレンダリングを行うことはお勧めしません(このリファレンスも参照)。ただし、バックグラウンドでレンダリングを続行します。

UPDATED : ポイント 1 の最新のインジェクションの例への追加のリンクを提供しました。

于 2012-04-11T10:47:24.863 に答える
6

簡単なグーグルで、Windows XPに関連するこのコードプロジェクトを見つけました。この知識を Windows Vista および 7 に適用できるかどうかわかりません??

http://www.codeproject.com/Articles/5051/Various-methods-for-capturing-the-screen

編集:

こんな記事も見つけました。

http://www.codeproject.com/Articles/20651/Capturing-Minimized-Window-A-Kid-s-Trick

これは、ジャスティンのブログ投稿のコメントからリンクされています。彼は誰かと一緒にこれに取り組んでいるようです(あなたのリンクについてです)。

http://spazzarama.com/2009/02/07/screencapture-with-direct3d/

于 2012-04-10T15:58:31.137 に答える
2

プロジェクトで使用していると言った (spazzarama から) リンクしたコードは、DirectX デバイスのフロント バッファーをキャプチャします。代わりにバック バッファーをキャプチャしようとしましたか? リンクされたサイトのコードから、90 行目を次のように変更します。

device.GetFrontBufferData(0, surface);

Surface backbuffer = device.GetBackBuffer(0, 0, BackBufferType.Mono);
SurfaceLoader.Save("Screenshot.bmp", ImageFileFormat.Bmp, backbuffer);

これには、リンクされた例の 96 ~ 98 行目の削除も含まれます。バックバッファは、邪魔になるウィンドウなしで生成される場合があります。

編集

そのすべてを気にしないでください。リンクされたサンプル コードは、ウィンドウ ハンドルを使用して画面の領域を定義していて、実際には DirectX ウィンドウで何もしていないことに気付きました。あなたのサンプル コードは障害物を回避することはできません。これは、領域にアクセスするまでに、その領域の前に別のウィンドウが既に描画されているためです。

アプリケーションを救済するための最善の策は、コードを実行して画像をキャプチャする前に、DirectX ウィンドウを画面の上部に表示することです。Wind32API BringWindowToTop関数を使用してそれを行うことができます( http://msdn.microsoft.com/en-us/library/ms632673%28VS.85%29.aspx )。

于 2012-04-10T21:56:11.193 に答える