/// <summary> /// サンプルグラバを作成する /// </summary> private DSInterface.IBaseFilter CreateSampleGrabber() { var filter = DSUtility.CreateFilter(DSConst.FilterGUID.CLSID_SampleGrabber); DSInterface.ISampleGrabber i_grabber = (DSInterface.ISampleGrabber)filter; // サンプル グラバを最初に作成したときは、優先メディア タイプは設定されていない。 // これは、グラフ内のほぼすべてのフィルタに接続はできるが、受け取るデータ タイプを制御できないとうことである。 // したがって、残りのグラフを作成する前に、ISampleGrabber::SetMediaType メソッドを呼び出して、 // サンプル グラバに対してメディア タイプを設定すること。 // サンプル グラバは、接続した時に他のフィルタが提供するメディア タイプとこの設定されたメディア タイプとを比較する。 // 調べるフィールドは、メジャー タイプ、サブタイプ、フォーマット タイプだけである。 // これらのフィールドでは、値 GUID_NULL は "あらゆる値を受け付ける" という意味である。 // 通常は、メジャー タイプとサブタイプを設定する。 // https://msdn.microsoft.com/ja-jp/library/cc370616.aspx // https://msdn.microsoft.com/ja-jp/library/cc369546.aspx // サンプル グラバ フィルタはトップダウン方向 (負の biHeight) のビデオ タイプ、または // FORMAT_VideoInfo2 のフォーマット タイプのビデオ タイプはすべて拒否する。 var mt = new DSStructure.AM_MEDIA_TYPE(); mt.majorType = new Guid(DSConst.MediaTypeGUID.MEDIATYPE_Video); mt.subType = new Guid(DSConst.MediaTypeGUID.MEDIASUBTYPE_RGB24); i_grabber.SetMediaType(mt); return(filter); }
private Bitmap GetBitmapMain(DSInterface.ISampleGrabber i_grabber, int width, int height, int stride) { try { return(GetBitmapMainMain(i_grabber, width, height, stride)); } catch (COMException ex) { if (ex.ErrorCode == (int)DSConst.DirectShowHRESULT.VFW_E_WRONG_STATE) { // image data is not ready yet. // returns empty bitmap. return(new Bitmap(width, height)); } throw; } }
/// <summary>サンプルグラバから画像を取得する。</summary> private Bitmap GetBitmapMainMain(DSInterface.ISampleGrabber i_grabber, int width, int height, int stride) { // サンプルグラバから画像を取得するためには // まずサイズ0でGetCurrentBufferを呼び出しバッファサイズを取得し // バッファ確保して再度GetCurrentBufferを呼び出す。 // 取得した画像は逆になっているので反転させる必要がある。 int sz = 0; i_grabber.GetCurrentBuffer(ref sz, IntPtr.Zero); // IntPtr.Zeroで呼び出してバッファサイズ取得 if (sz == 0) { return(null); } // メモリ確保し画像データ取得 var ptr = Marshal.AllocCoTaskMem(sz); i_grabber.GetCurrentBuffer(ref sz, ptr); // 画像データをbyte配列に入れなおす var data = new byte[sz]; Marshal.Copy(ptr, data, 0, sz); // 画像を作成 var result = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); var bmp_data = result.LockBits(new Rectangle(Point.Empty, result.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); // 上下反転させながら1行ごとコピー for (int y = 0; y < height; y++) { var src_idx = sz - (stride * (y + 1)); // 最終行から var dst = new IntPtr(bmp_data.Scan0.ToInt32() + (stride * y)); Marshal.Copy(data, src_idx, dst, stride); } result.UnlockBits(bmp_data); Marshal.FreeCoTaskMem(ptr); return(result); }