Webカメラなどの画像を読み込み、ウィンドウ上に表示する方法について解説します。
using System; using System.Runtime.InteropServices; using System.Windows.Forms; using DirectShowLib; public class VideoCaptureForm : System.Windows.Forms.Form { }
/// <summary> /// フィルタ グラフ構築用のインターフェイス /// </summary> IGraphBuilder graphBuilder = null; /// <summary> /// ビデオキャプチャ用のフィルタ グラフ構築用のインターフェイス /// </summary> ICaptureGraphBuilder2 captureGraphBuilder = null;
/// <summary> /// コンストラクタ /// </summary> private VideoCaptureForm() { this.graphBuilder = ( IGraphBuilder )new FilterGraph(); this.captureGraphBuilder = ( ICaptureGraphBuilder2 )new CaptureGraphBuilder2(); // フィルタグラフを構築する SetupFilterGraph( this.graphBuilder, this.captureGraphBuilder ); // ビデオ ウィンドウを構築する SetupVideoWindow( this.graphBuilder, this ); // ビデオデータのプレビューを開始する int hr = ( ( IMediaControl )this.graphBuilder ).Run(); DsError.ThrowExceptionForHR( hr ); }
/// <summary> /// リソースの解放 /// </summary> /// <param name="disposing"></param> protected override void Dispose( bool disposing ) { if( disposing ) { // DirectShowのインターフェイスを解放する Marshal.ReleaseComObject( this.graphBuilder ); Marshal.ReleaseComObject( this.captureGraphBuilder ); this.graphBuilder = null; this.captureGraphBuilder = null; } base.Dispose( disposing ); }
/// <summary> /// フィルタ グラフの構築 /// </summary> /// <param name="graphBuilder"></param> /// <param name="captureGraphBuilder"></param> private void SetupFilterGraph( IGraphBuilder graphBuilder, ICaptureGraphBuilder2 captureGraphBuilder ) { int hr = 0; // キャプチャ グラフが使用するフィルタ グラフを指定する hr = captureGraphBuilder.SetFiltergraph( graphBuilder ); DsError.ThrowExceptionForHR( hr ); // ビデオキャプチャ フィルタを取得する IBaseFilter videoCaptureFilter = GetCaptureDevice( 0 ); // フィルタ グラフにビデオキャプチャ フィルタを追加する hr = graphBuilder.AddFilter( videoCaptureFilter, "Video Capture" ); DsError.ThrowExceptionForHR( hr ); // ビデオキャプチャ フィルタをレンダリング フィルタに接続する hr = captureGraphBuilder.RenderStream( PinCategory.Preview, MediaType.Video, videoCaptureFilter, null, null ); DsError.ThrowExceptionForHR( hr ); // ビデオキャプチャ フィルタを解放する Marshal.ReleaseComObject( videoCaptureFilter ); }
/// <summary> /// キャプチャ デバイスの取得 /// </summary> /// <param name="deviceIndex">キャプチャ デバイスのインデックス</param> /// <returns></returns> private IBaseFilter GetCaptureDevice( int deviceIndex ) { // ビデオ デバイスのリストを取得する DsDevice[] devices = DsDevice.GetDevicesOfCat( FilterCategory.VideoInputDevice ); if( devices.Length <= deviceIndex ) { throw new Exception( "指定インデックスのビデオ キャプチャ デバイスは存在しない。" ); } else { DsDevice device = devices[ deviceIndex ]; object source; Guid filterId = typeof( IBaseFilter ).GUID; // モニカ (Moniker) を使用して、デバイスをフィルタ オブジェクトに結びつける device.Mon.BindToObject( null, null, ref filterId, out source ); return ( IBaseFilter )source; } }
/// <summary> /// ビデオ ウィンドウの構築 /// <param name="graphBuilder"></param> /// <param name="owner"></param> /// </summary> private void SetupVideoWindow( IGraphBuilder graphBuilder, Control owner ) { int hr = 0; IVideoWindow videoWindow = ( IVideoWindow )graphBuilder; // ビデオ ウィンドウのオーナーに このウィンドウを設定する hr = videoWindow.put_Owner( owner.Handle ); DsError.ThrowExceptionForHR( hr ); // ウィンドウのスタイルを設定する hr = videoWindow.put_WindowStyle( WindowStyle.Child | WindowStyle.ClipChildren ); DsError.ThrowExceptionForHR( hr ); // ビデオ ウィンドウを親ウィンドウのサイズに一致させる hr = videoWindow.SetWindowPosition( 0, 0, owner.ClientSize.Width, owner.ClientSize.Height ); }
/// <summary> /// アプリケーションのエントリ ポイント /// </summary> [STAThread] static void Main() { Application.Run( new VideoCaptureForm() ); }