新聞速報

        

2017年2月17日 星期五

DirectSHOW 播放中 抓圖

怎麼為電影抓圖?辦法似乎很多,我曉得的有用Video Render抓圖(Null Render、VMR7/9抓圖、Sample Grabber抓圖)。但是,這三種方式我都沒有試過。

  偶然間發現:IBasicVideo.GetCurrentImage函數。按字面意思,這個東西可以用來抓圖了。我找到了這個函數的vc版的使用示例,點此處查看。

  我依照它,費了老大的勁才寫出了如下代碼:

        /// <summary>

        /// 抓取當前的圖像

        /// </summary>

        public Bitmap CurrentImage

        {

            get

            {

                if (basicVideo == null) return null;

                int buffersize=0;

                IntPtr currentImage=IntPtr.Zero;

                Bitmap bmp = null;



                int hr = basicVideo.GetCurrentImage(ref buffersize, IntPtr.Zero);

                DsError.ThrowExceptionForHR(hr);

                currentImage=Marshal.AllocCoTaskMem(buffersize);



                hr = basicVideo.GetCurrentImage(ref buffersize, currentImage);

                BitmapInfoHeader structure = new BitmapInfoHeader();

                Marshal.PtrToStructure(currentImage, structure);



                bmp = new Bitmap(structure.Width, structure.Height, (structure.BitCount / 8) * structure.Width, System.Drawing.Imaging.PixelFormat.Format32bppArgb, currentImage);

                bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);



                Marshal.FreeCoTaskMem(currentImage);

                return bmp;

            }

        }

  這是我的播放器控件中關於取當前圖像的一個屬性,它在捕獲圖像時會自動暫停一下。我推測,它應當是調用當前Render的API實現的。只是這個過程對我們透明而己。使用方法如下:

  cp1.CurrentImage.Save("c:\\aa.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);

  這段代碼,我還參考了DirectShowLib的示例代碼(VMR9Snap)。通過這個示例,我加深了對Marshal類的映像。

沒有留言:

張貼留言