Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        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;
            }
        }
Exemplo n.º 3
0
        /// <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);
        }