directshow录像和抓图,单独进行都可以,不知道如何在图像同时抓图,望指点。
下面是部分代码
    bool SetupGraph()
    {
        int hr;
        IFileSinkFilter sink;
        IBaseFilter mux;
        try
        {
            hr = capGraph.SetFiltergraph(graphBuilder);
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);            hr = graphBuilder.AddFilter(capFilter, "Ds.NET Video Capture Device");
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);            DsUtils.ShowCapPinDialog(capGraph, capFilter, this.Handle);            AMMediaType media = new AMMediaType();
            media.majorType = MediaType.Video;
            media.subType = MediaSubType.RGB24;
            media.formatType = FormatType.VideoInfo;
            hr = sampGrabber.SetMediaType(media);
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);            hr = graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);
            Guid cat;
            Guid med;            cat = PinCategory.Preview;
            med = MediaType.Video;
            hr = capGraph.RenderStream(ref cat, ref med, capFilter, null, null);  
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);            cat = MediaSubType.Avi;            // hr = capGraph.SetOutputFileName(ref cat, "c:\\323.avi", out baseGrabFlt, out sink);   //当这句运行的话,后面后有异常,看红色字体
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);            cat = PinCategory.Capture;
            med = MediaType.Video;
            hr = capGraph.RenderStream(ref cat, ref med, capFilter, null, baseGrabFlt); 
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);            media = new AMMediaType();
            hr = sampGrabber.GetConnectedMediaType(media);   //当捕获视频录像时,此处会有异常            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);
            if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
                throw new NotSupportedException("Unknown Grabber Media Format");            videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
            Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero;            hr = sampGrabber.SetBufferSamples(false);
            if (hr == 0)
                hr = sampGrabber.SetOneShot(false);
            if (hr == 0)
                hr = sampGrabber.SetCallback(null, 0);
            if (hr < 0)
                Marshal.ThrowExceptionForHR(hr);            return true;
        }
        catch (Exception ee)
        {
            MessageBox.Show(this, "Could not setup graph\r\n" + ee.Message, "test", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            return false;
        }
    }directshow 如何在录像同时抓图directshow 录像同时抓图

解决方案 »

  1.   

    你这个是事先设置好视频录像文件或者抓图文件的。
    如果是触发式的,你这个办法就不行了。
    在 sampGrabber.SetCallback里设置一个回调函数,
    当从摄像头读取数据的时候,会触发这个事件,这个事件里就有你要的图像数据,把它保存了就可以实现抓图的功能了。如果是触发式录像和抓图,都可以在这个回调函数里做。
      

  2.   


    抓图是在回调函数里面做的, /// <summary> buffer callback, COULD BE FROM FOREIGN THREAD. </summary>
    int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
    {
    if( captured || (savedArray == null) )
    {
    Trace.WriteLine( "!!CB: ISampleGrabberCB.BufferCB" );
    return 0;
    } captured = true;
    bufferedSize = BufferLen;
    Trace.WriteLine( "!!CB: ISampleGrabberCB.BufferCB  !GRAB! size = " + BufferLen.ToString() );
    if( (pBuffer != IntPtr.Zero) && (BufferLen > 1000) && (BufferLen <= savedArray.Length) )
    Marshal.Copy( pBuffer, savedArray, 0, BufferLen );
    else
    Trace.WriteLine( "    !!!GRAB! failed " );
    this.BeginInvoke( new CaptureDone( this.OnCaptureDone ) );
    return 0;
    }
    void OnCaptureDone()
    {
    Trace.WriteLine( "!!DLG: OnCaptureDone" );
    try {
    toolBarBtnGrab.Enabled = true;
    int hr;
    if( sampGrabber == null )
    return;
    hr = sampGrabber.SetCallback( null, 0 ); int w = videoInfoHeader.BmiHeader.Width;
    int h = videoInfoHeader.BmiHeader.Height;
    if( ((w & 0x03) != 0) || (w < 32) || (w > 4096) || (h < 32) || (h > 4096) )
    return;
    int stride = w * 3; GCHandle handle = GCHandle.Alloc( savedArray, GCHandleType.Pinned );
    int scan0 = (int) handle.AddrOfPinnedObject();
    scan0 += (h - 1) * stride;
    Bitmap b = new Bitmap( w, h, -stride, PixelFormat.Format24bppRgb, (IntPtr) scan0 );
    handle.Free();
    savedArray = null;
    Image old = pictureBox.Image;
    pictureBox.Image = b;
    if( old != null )
    old.Dispose();
    toolBarBtnSave.Enabled = true;
    }
    catch( Exception ee )
    {
    MessageBox.Show( this, "Could not grab picture\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
    }
    }回调函数中如何录像?请指点
      

  3.   

    Bitmap b = new Bitmap( w, h, -stride, PixelFormat.Format24bppRgb, (IntPtr) scan0 );
    这个就是你已经找到的图片,如果把这个图片每一的张都写入一个avi文件里,就是你的录像了。
    C#把图片生成avi的代码,你在网上找找,有现成。
    以前把C#写avi的代码改成了一个delphi写avi的代码,反而找不到C#的代码了,不然就直接给你发了。利用网上那个代码写成的avi文件很大,需要在写入的时候自己做压缩编码。
    以前使用的是微软的mp4压缩格式免费的编码器,效果不错。
    下面的资源,你看看
    http://download.csdn.net/detail/mjp1234airen4385/3607954