Media Foundation ⑥ WebCam + WPF XAMLとC#の実装
それでは XAMLとC#を実装しましょう。次のようにビデオ画像と、スライダーで回転・スケールを行うので、XAMLではD3DImageと2つのスライダー(とラベル)を宣言します。一つのスライダーはD3DImageの回転角度に、もう一つはD3DImageのXScaleとYScaleにバインディングします。
D3DImageはSystem.Windows.Interop名前空間にあるので、名前空間の追加に注意してください。
C#の実装
D3DImage チュートリアルとの違いは、初期化時にビデオのサイズを取得していることと、Rendering イベントハンドラーとコールバックを宣言する代わりに、Windows メッセージを処理するためのコールバック(ここではBltVideo)を HWndSourceクラスのAddHookメソッドを使って宣言することです。そのあとで一回目の非同期サンプリング命令(Sample)を呼び出します。
private readonly D3DWrapper myD3DScene = new D3DWrapper();
private HwndSource source;
private const int WM_PAINT = 0x000F;
private int videoWidth = 0;
private int videoHeight = 0;
...
private void StartDXRendering()
{
if (!myD3DImage.IsFrontBufferAvailable)
return;
IntPtr scene = myD3DScene.Initialize(
new WindowInteropHelper(this).Handle,
ref videoWidth,
ref videoHeight);
myD3DImage.Lock();
myD3DImage.SetBackBuffer(
D3DResourceType.IDirect3DSurface9, scene);
myD3DImage.Unlock();
source = HwndSource.FromHwnd(
new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(BltVideo));
myD3DScene.Sample();
}
BltVideo では WM_PAINT メッセージかどうかを確認して、D3DImageの内容を更新します。そのあとで、メッセージの処理完了を示す handled を true にし、次の非同期サンプリング命令を呼び出します。
private IntPtr BltVideo( IntPtr hwnd, int msg, IntPtr wParam,
IntPtr lParam, ref bool handled)
{
if (msg == WM_PAINT)
{
myD3DImage.Lock();
myD3DImage.AddDirtyRect(
new Int32Rect(0, 0, videoWidth, videoHeight));
myD3DImage.Unlock();
handled = true;
myD3DScene.Sample();
}
return IntPtr.Zero;
}
ソリューションを添付するので、WebCam のついた PC でビルド・実行してみてください。動作環境は以下の通りです。
- Windows 7 (RC)
- Windows 7 SDK (RC)
- Visual Studio 2008 SP1
- DirectX SDK (Mar 2009)