mikebai.com

  • Home
  • dev
  • DotNET
  • M365
  • 搞笑
  • 杂七杂八
  • FocusDict
個人BLOG
it developer
  1. Main page
  2. dev
  3. Main content

图像捕获[转载]

2008-01-17 151hotness 0likes 0comments

视频截图也不是一个什么新概念,早期的播放器如金山影霸就支持视频截图。视频截图有其应用的需求,影片播放过程中有些精彩的画面,用户可能想保留下来。普通的print screen按钮不一定有用,因为启用DX加速,使用printf screen捕捉不到屏幕信息。
  DShow里头有三种类型的filter:source filter | trasform filter | render filter。三种filter贯穿了整个播放过程。多个filter连接在一起,构成一个filter graph。创建graph,然后通过graph来查询一些接口,获取到视频流每一帧数据,保存成一帧帧图片。借助于DShow,实现视频截图应该说非常容易,而且DShow可以截获视频的方法还不少呢。下面就简单介绍一两个方法。
  方法一:利用IBasicVideo接口获取视频帧数据
  IBasicVideo接口提供了一个方法GetCurrentImage()获取视频帧的数据。使用此方法不是特别可靠。在Render是Video Render的时候,如果采取的DirectDraw,就会失败。另外,使用GetCurrentImage()方法获取视频帧数据,需要确定媒体类型,不同的媒体类型,获取的数据结构和内容都不尽相同,这也是保存图片的一个麻烦所在。下面说说如何使用IBasicVideo来获取视频帧。
  (1) 创建FilterGraph [CoCreateInstance]
  (2) 调用IGraphBuilder::RenderFile()打开文件
  (3) 通过IGraphBuilder查询出接口IBasicVideo
  (4) 通过调用IBasicVideo::GetCurrentImage()获取图片信息捕获图片
 
 
  方法二:利用IMediaDet接口获取视频帧数据
  优点:相对于IBasicVideo接口捕获视频图像而言,使用IMediaDet更加专业也更加方便。举个例子:调用IBasicVideo获取视频数据的时机?如果我想捕获某一时刻的某一帧图像,用IBasicVideo能做得到吗?用IMediaDet就不一样了,调用GetBitmapBits可以获取指定时间的帧数据。而且,用IMediaDet获取数据的格式是固定的RGB24。这样一来,获取到的数据,保存到图像就方便多了,不用担心不同的杂乱格式带来的烦恼。
  使用IMediaDet接口获取视频数据方法如下:
  (1) 创建MediaDet对象 [CoCreateInstance(CLSID_MediaDet...)]
  (2) 调用IMediaDet::put_Filename() 指定要打开的源文件的名称
  (3) 调用IMediaDet::GetBitmapBits获取视频帧数据
/////////////////////////////////////////////////////////////
// Sample Code:
long size;
hr = pDet->GetBitmapBits(0, &size, 0, width, height);
if (SUCCEEDED(hr))
{
    char *pBuffer = new char[size];
    if (!pBuffer)
        return E_OUTOFMEMORY;
    try {
        hr = pDet->GetBitmapBits(0, 0, pBuffer, width, height);
    }
    catch (...) {
        delete [] pBuffer;
        throw;
    }
    if (SUCCEEDED(hr))
    {
        BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)pBuffer;
        HDC hdcDest = GetDC(0);
       
        // Find the address of the start of the image data.
        void *pData = pBuffer + sizeof(BITMAPINFOHEADER);
       
        // Note: In general a BITMAPINFOHEADER can include extra color
        // information at the end, so calculating the offset to the image
        // data is not generally correct. However, the IMediaDet interface
        // always returns an RGB-24 image with no extra color information.
       
        BITMAPINFO bmi;
        ZeroMemory(&bmi, sizeof(BITMAPINFO));
        CopyMemory(&(bmi.bmiHeader), bmih, sizeof(BITMAPINFOHEADER));
        HBITMAP hBitmap = CreateDIBitmap(hdcDest, bmih, CBM_INIT,
            pData, &bmi, DIB_RGB_COLORS);
    }
    delete[] pBuffer;
}
////////////////////////////////////////

Tag: Nothing
Last updated:2008-01-17

mikebai

This person is a lazy dog and has left nothing

Like
< Last article
Next article >

COPYRIGHT © 2025 mikebai.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang