`
jiava9900
  • 浏览: 86556 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

[转]directshow:图片的抓取

    博客分类:
  • java
阅读更多
    <p>本文转自:<font>http://blog.chinaunix.net/u2/63021/showart_492136.html</font></p><p>原文如下:</p><p>在播放媒体文件的过程中,有一个很有用的功能,就是在当前播放的位置抓取图,实现这种图片抓取功能的方法很多,我们这里只介绍常用的两种。<font size="2"> </font></p><p><br><strong>第1种</strong>方法最简单,它使用1basicvideo::getcurrentimage接口方法,代码如下。<br> heel snapshotbitmap(ibasicvideo*pba8icvideo, const char*outfile)<br> if (pbasicvldeo)<br> {<br> long bitmapsize=0;<br> //首先获得图像大小<br> if(succeeded(peasicvidee-&gt;getcurrentimage(&amp;bitmapsize,0)))<br> {<br> bool pass=false;<br> //分配图像帧内存<br> unsigned char*buffer=new unsigned char[bitmapsize];<br> //获取图像帧数据<br> if(succeeded(pbasicvideo-&gt;getcurrentimage(&amp;bitmapsize,(long*)buffer)))<br> {<br> bitmapfileheader hdr;<br> lpbitmapinfoheader ipbi;<br> ipbi=(lpbitmapinfoheader)buffer;<br> int ncolors=1&lt;&lt;ipbi-&gt;bibitcount;<br> if(ncolors&gt;256)<br> //always is”bm”<br> hdr.bftype =((word)(‘m’&lt;&lt;8)|’b’);<br> hdr.bfsize =bitmapsize+sizeof(hdr);<br> hdr.bfreservedl =0;<br> hdr.bfreserved2 =0;<br> hdr.bfoffbits =(dword)<br> (sizeof(bitmapfileheader)+lpbi-&gt;bisize+ncolors*sizeof(rgbquad));<br> cfile bitmapfile(outfile,cfile::modereadwrite |<br> cfile::modecreate | cfile::typebinary);<br> //写入位图文件头<br> bitmapfile.write{&amp;hdr,sizeof【bitmapfileheader));<br> //写入图像帧数据(包括bitmapinfoheader信息)<br> bitmapfile.write(buffer,bitmapsize);<br> bitmapfile.close();<br> pas8=true;<br>}<br> delete[]burfer;<br> return pass;<br> }<br> return false ;</p><p>值得注意的是,ibasievideo接口应该从filtergraphmanager上获得,但真正实现在 <br>rendererfilter上。如果我们使用的是传统的videorenderer,那么使用getcurrentlmage 抓图将是不可靠的。因为如果videorenderer使用了directdraw加速,这个函数调用会失 败;而且调用这个函数,videorenderer必须处于暂停状态。但如果我们使用的是vmr, 则没有上述这些限制。 </p><p><br><strong>第2种</strong>方法比较复杂.它使用samplegrabberfilter。它其实是一个trans-in-place <br>filter,在sdk安装目录下的samples\c++\directshow’filters\grabber提供了源代码。实际 上,samplegrabber可以抓取任何类型的sample。但在这里,我们只介绍使用它抓取视频 帧的方法。步骤如下: <br><br><strong>(1)创建samplegrabber,并将之加入到filtergraph中。</strong> <br>//createthesamplegrabber <br>ibasefilter*pgrabberf=null; <br>hr=cocreateinstanee(clsid_samplegrabber,null,clsctx_inproc_server, <br>iidibasefilter,(void**)&amp;pgrabberf); <br>if(failed(hr)) <br>{<br>//returnanerror<br>}<br>hr=pgraph-&gt;addfilter(pgrabberf,l"samplegrabber"); <br>if(failed(hr) <br>{ <br>//returnanerror <br>} <br>isamplegrabber*pgrabber=null; <br>pgrabberf-&gt;queryinterface(iid_isamplegrabber,(void**)&amp;pgrabber);<br><br><strong>(2)给samplegrabber设置pin上连接用的媒体类型。 <br></strong> 如果我们想抓取24位的rgb图片,如下设置媒体类型: <br>am_media_typemt; <br>zeromemory(&amp;mt,sizeof(am_media_type)); <br>mt.malortype=mediatypevideo; <br>mt.subtype=me:diasubtypergb24; <br>hr=pgrabber-&gt;setmediatype(&amp;mt); <br>也可以根据当前显示器的配置来设置samplegrabber接受的rgb类型,代码如下:<br>//findthecurrentbitdepth <br>hdchdc=getdc(null); <br>intibitdepth=getdevicecaps(hdc,bitspixel); <br>releasedc(null,hdc); <br>//setthemediatype <br>mt.majortype=mediatypevideo; <br>switch(ibitdepth) <br>{ <br>case8: <br>mt.subtype=mediasubtypergb8; <br>break; <br>case16: <br>mt.subtype=mediasubtype_rgb555; <br>break; <br>case24: <br>mt.subtype=mediasubtype_rgb24; <br>break; <br>case32: <br>mt.subtype=mediasubtype_rgb32; <br>break; <br>default: <br>returne_fail; <br>} <br>hr=pgrabber-&gt;setmediatype(&amp;mt);<br><br><strong>(3)完成filtergraph的构建。</strong> <br>因为samplegrabber上已经设置了一个媒体类型,则其他filter必须以这种媒 <br>才能与samplegrabber相连。我们可以使用dimctshow的“智能连接”机制,来 <br>个fitlergraph的创建过程,代码如下。 <br>ibasefiiter*psrc; <br>hr=pgraph-&gt;addsourcefilter(wszfilename,l"source",&amp;psrc};<br>if(failed(hr)) <br>{ <br>//returnanerrorcode <br>} <br>hr=connectfiiters(pgraph,psrc,pgrabberf); <br>其中,connectfilters是我们在5.3节中介绍的自定义函数。 <br>如果我们只是想抓图(不需要对视频预览),则samplegrabber后面可以连接一个null rendererfilter(它的clsid为clsidnullrenderer)。如果要filtergraph中的数据流以最快的速度传送,则filtergraph不要使用参考时钟(调用imediafitter::setsyncsource,参数为null)。 </p><p><font size="2"><strong>(4)运行filtergraph。 <br></strong>samplegrabber可以有如下两种工作模式: <br>缓冲模式将输入的sample进行缓存后,再往下传送。 <br>回调模式当有输入的sample时,调用应用程序设置进来的回调函数。 <br>因为回调模式会影响整个filtergraph的效率,并且容易引起死锁,所以我们推荐使用缓冲模式。另外,我们可以设置isamplegrabber::setoneshot,使得samplegrabber获取一个sample以后,就让filtergraph停止,代码如下:<br>//setone-shotmodeandbuffering. <br>hr=pgrabber-&gt;setoneshot(true); <br>hr=pgrabber-&gt;setbuffersamples(true); <br>pcontrol-&gt;run();//runthegraph. <br>pevent-&gt;waitforcompletion(infinite,&amp;evcode),//waittillit’sdone.<br><br></font><font size="2"><strong>(5)获取抓到的sample数据</strong>。<br></font><font size="2">缓冲模式下,我们可以调用isamplegrabber::getcurrentbuffer来获取sample数据,代码如下: <br>//findtherequiredbuffersize <br>longcbbuffer=0; <br>hr=pgrabber-&gt;getcurrentbuffer(&amp;cbbuffer,null); <br>char*pbuffer=newchar[cbbuffer]; <br>if(!pbuffer) <br>//outofmemory.returnanerrorcode <br>} <br>hr=pgrabber-&gt;getcurrentbuffer(&amp;cbbuffer,(long*)pbuffer); <br>我们也可以将获取的数据使用gdi函数显示出来,代码如下: <br>am_media_typemt; <br>hr=pgrabber-&gt;getconnectedmediatype(&amp;rot); <br>if(failed(hr)) <br>{ <br>//returnerr05code <br>} <br>//examinetheformatblock <br>videoinfoheader*pvih; <br>if((mt.formattype==format_videoinfo)&amp;&amp; <br>(mt.cbformat&gt;=sizeof(videoinfoheader))&amp;&amp; <br>(mt.pbformat!=null)) <br>pvih={videoinfoheader*)mt·pbformat; <br>} <br>else <br>{ <br>//wrongformat.freetheformatblockandreturnanerror‘ <br>freemedlatype(mt); <br>returnvfw_e_invalidmediatype; <br>//youcanusethemediatypetoaccessthebitmapinfoheafreinformation, <br>//forexample,thefollowingcodedrawsthebitmapusinggdi <br>setdibitstodevice( <br>hdc,0,0, <br>pvih-&gt;bmiheader.biwidth, <br>pvih-&gt;bmiheader.biheight, <br>o,o, <br>0, <br>pvih-&gt;bmiheader.biheight, <br>pbuffer, <br>(bitmapinfo*)&amp;pvih-&gt;bmiheader, <br>dibrgbcolors <br>), <br>//freetheformatblockwhenyouaredone: <br>freemediatype(mt);<br></font></p> 
分享到:
评论

相关推荐

    DirectShow 9.0 摄像头抓取图片

    实现摄像头抓取图片的基本步骤如下: 1. **初始化DirectShow**: 创建并初始化一个CoInitializeEx,以启动COM线程模型。 2. **创建过滤器图**: 使用IAMFilterGraph接口的AddSourceFilter方法添加视频捕获设备作为源...

    DirectShow抓取图片的几个方法

    ### DirectShow抓取图片的几种方法 #### 一、引言 DirectShow是Microsoft Windows操作系统中的一个组件,主要用于处理多媒体数据流,如音频和视频。它提供了强大的功能来捕获、压缩、播放以及编辑多媒体数据。本文...

    C# WinForm DirectShow视频采集及图片抓取实例DxSnap(绝对源码)

    在C# WinForm环境中,我们可以利用DirectShow库来实现视频采集和图片抓取功能。这个实例项目"DxSnap"提供了一个完整的解决方案,帮助开发者了解如何在Windows桌面应用程序中集成视频捕获和图像保存的能力。 首先,...

    Directshow 抓取图像

    在Directshow中,图像抓取是指从视频流中捕获单帧图片并保存为图像文件的过程,这对于视频分析、监控系统或者视频处理应用是非常有用的。 首先,理解Directshow的基本架构至关重要。它由两部分组成:过滤器(Filter...

    DirectShow实现视频采集与视频数据的抓取

    在这个主题中,我们将深入探讨如何利用DirectShow来实现视频采集与视频数据的抓取。 首先,理解DirectShow的基本结构至关重要。DirectShow由许多组件(filters)组成,每个组件负责特定的媒体处理任务,如捕获设备...

    Directshow利用SampleGrabber截取图片示例

    SampleGrabber是Directshow中一个非常重要的过滤器,它的主要功能是在视频流通过它的时候抓取一帧数据。这个过程通常用于捕获视频帧进行处理,例如分析、截图或者转码。下面我们将详细介绍如何实现这个功能。 首先...

    基于Directshow的视频抓图在车牌识别系统中的应用

    ### 基于Directshow的视频抓图在车牌识别系统中的应用 #### 一、Directshow原理 ##### 1.1 Directshow系统概述 Directshow是Microsoft提供的多媒体框架,用于在Windows平台上处理音频和视频流。它采用了一种称为...

    Get_Movie_Frame.zip_CRAWL_DirectShow_Directshow avi_avi direct

    这个压缩包“Get_Movie_Frame.zip”似乎包含了一个关于如何使用DirectShow从AVI视频文件中抓取帧的示例项目或教程,特别适用于Visual C++开发者。在本文中,我们将深入探讨DirectShow、AVI格式以及如何利用...

    DirectShow实现视频的实时显示并抓图,可以设置视频参数

    DirectShow是微软开发的一种多媒体框架,用于处理视频和音频流。在本文中,我们将深入探讨如何使用DirectShow在Visual Studio 2013环境下实现视频的实时显示,并进行抓图功能,同时允许用户自定义图像参数和视频格式...

    directshow视频加入文字信息

    用directshow写视频获取图片抓拍和显示程序,有分辨率设置,文字信息加入视频和抓拍的图片,设置文字信息的颜色和大小,这里给出单行,自己可以改成多行或者鼠标定点加入文字信息,其中也用到GDI+对多种图片格式的显示...

    directshow 读取摄像头图像

    4. **跨滤镜**:如Sample Grabber,用于在数据流中抓取单个图像帧,这对于需要保存或处理单个图片的应用非常有用。 实现“自动检测电脑挂载的摄像头”功能,需要调用DirectShow的枚举设备接口,例如`...

    directshow实现抓图效果(不过有点慢)

    在描述中提到的代码封装了DirectShow播放视频并进行图片抓取的功能。这意味着代码中可能包含了初始化DirectShow过滤器图形、创建播放器以及设置回调函数来捕获帧的关键步骤。通常,这个过程会涉及以下几个关键知识点...

    从摄像头抓取图片

    总结起来,从摄像头抓取图片涉及的关键技术有C++编程、OpenCV或DirectShow库的使用、DIB位图的处理以及Win32 API的调用。对于想要深入学习这一领域的开发者,了解这些知识点并掌握其应用是至关重要的。通过编写和...

    C#调用摄像头保存图片

    4. 实现拍照功能:当用户点击Button时,调用VideoCaptureDevice的Start方法开始捕获视频流,然后使用Snapshot方法抓取一帧图片,并保存为本地文件。以下是一个简单的事件处理函数: ```csharp private void ...

    利用微软提供的directshow从视屏流中每隔0.3秒连续抓取图像帧,并自动按顺序保存成BMP格式FrameseriesGrabber.rar

    在这个场景中,我们将探讨如何利用DirectShow从视频流中连续抓取图像帧,并将它们保存为BMP格式的图片。 首先,我们要了解DirectShow的工作原理。DirectShow基于COM(Component Object Model)组件模型,它包含了一...

    Directshow VMR9播放器

    在DirectShow中,实现截图通常涉及到创建一个图像抓取滤镜,该滤镜可以捕获VMR9输出的帧数据并将其保存为图片文件。开发者只需稍微调整代码,就能实现在播放过程中动态捕获视频帧,生成静态图像,这对于视频分析、...

    directshow视频通信

    7. **图像抓拍**:在视频通信中,有时需要抓取远端的视频帧作为静态图片。DirectShow提供了抓图功能,通过调用特定接口,可以在任何时候捕获当前的视频帧。 8. **音视频同步**:为了提供良好的用户体验,视频和音频...

    c++写的DirectShow视频连续截图

    这个类可能包含了设置截图参数、启动截图、保存图片等功能。对于初学者来说,通过研究这个项目,不仅可以理解DirectShow的基本工作原理,还能学习到如何在C++中处理多媒体数据。 文件名"VMR9Teset"很可能是一个测试...

    Window下通过DirectShow控制USB摄像头抓拍照片

    本教程将深入讲解如何使用DirectShow来实现USB摄像头的图像抓取。 首先,了解DirectShow的基本概念。DirectShow是基于COM(Component Object Model)组件模型的,它由一系列滤镜(Filter)组成,这些滤镜负责不同的...

    Windows下通过DirectShow控制USB摄像头,捕获视频流

    5. **实时抓拍图片**:如果需要在捕获视频流的同时抓取BMP格式的图片,你可以使用`ICaptureGraphBuilder2`接口。通过设置图像渲染器(例如`SampleGrabber`过滤器)和回调函数,可以在每帧视频数据到达时捕获并保存为...

Global site tag (gtag.js) - Google Analytics