DirectShowLib-使用覆盖文本保存视频

本文关键字:保存 视频 文本 覆盖 DirectShowLib- | 更新日期: 2023-09-27 18:22:41

如何在avi文件中保存处理后获得的图形。设法获得了带有覆盖文本的图片。我知道有一个方法SetOutputFileName(),但如何在这里使用它?

private Bitmap bitmapOverlay;
private IFilterGraph2 m_FilterGraph;

 void GO()
        {
        SetupGraph("C:''Export.avi");
        SetupBitmap();
        IMediaControl mediaCtrl = m_FilterGraph as IMediaControl;
        int hr = mediaCtrl.Run();
        DsError.ThrowExceptionForHR( hr );
        }

 private void SetupGraph(string FileName)
                {
                    int hr;
                IBaseFilter ibfRenderer = null;
                ISampleGrabber sampGrabber = null;
                IBaseFilter capFilter = null;
                IPin iPinInFilter = null;
                IPin iPinOutFilter = null;
                IPin iPinInDest = null;
                // Get the graphbuilder object
                m_FilterGraph = new FilterGraph() as IFilterGraph2;
                    // Get the SampleGrabber interface
                 sampGrabber = new SampleGrabber() as ISampleGrabber;
                    // Add the video source
                 hr = m_FilterGraph.AddSourceFilter(FileName, "Ds.NET FileFilter", out capFilter);
                 DsError.ThrowExceptionForHR( hr );
                    // Hopefully this will be the video pin
                 IPin iPinOutSource = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0);
                 IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter;
                 ConfigureSampleGrabber(sampGrabber);
                 iPinInFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);
                 iPinOutFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0);
                    // Add the frame grabber to the graph
                 hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" );
                 DsError.ThrowExceptionForHR( hr );
                 hr = m_FilterGraph.Connect(iPinOutSource, iPinInFilter);
                 DsError.ThrowExceptionForHR( hr );
                    // Get the default video renderer
                 ibfRenderer = (IBaseFilter) new VideoRendererDefault();
                    // Add it to the graph
                 hr = m_FilterGraph.AddFilter( ibfRenderer, "Ds.NET VideoRendererDefault" );
                 DsError.ThrowExceptionForHR( hr );
                 iPinInDest = DsFindPin.ByDirection(ibfRenderer, PinDirection.Input, 0);
                    // Connect the graph.  Many other filters automatically get added here
                 hr = m_FilterGraph.Connect(iPinOutFilter, iPinInDest);
                 DsError.ThrowExceptionForHR( hr );
                 SaveSizeInfo(sampGrabber);
            }

处理视频-在每帧文本上绘制。cc.Save("C:''''Test''''img"+m_Count+".jpg")-因此可以使用叠加文本进行拍摄。如何将处理后的视频文件保存在avi文件中?


int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
            {
            Graphics g;
            String s;
            float sLeft;
            float sTop;
            SizeF d;
            g = Graphics.FromImage(bitmapOverlay);
            g.Clear(System.Drawing.Color.Transparent);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
            // Prepare to put the specified string on the image
            g.DrawRectangle(System.Drawing.Pens.Blue, 0, 0, m_videoWidth - 1, m_videoHeight - 1);
            g.DrawRectangle(System.Drawing.Pens.Blue, 1, 1, m_videoWidth - 3, m_videoHeight - 3);
            d = g.MeasureString(m_String, fontOverlay);
            sLeft = (m_videoWidth - d.Width) / 2;
            sTop = (m_videoHeight - d.Height ) / 2;
            g.DrawString(m_String, fontOverlay, System.Drawing.Brushes.Red, 
                sLeft, sTop, System.Drawing.StringFormat.GenericTypographic);
            g.Dispose();

            Bitmap v;
            v = new Bitmap(m_videoWidth, m_videoHeight, m_stride,
                PixelFormat.Format32bppArgb, pBuffer);
            v.RotateFlip(RotateFlipType.Rotate180FlipX);
            g = Graphics.FromImage(v);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            // draw the overlay bitmap over the video's bitmap
            g.DrawImage(bitmapOverlay, 0, 0, bitmapOverlay.Width, bitmapOverlay.Height);
        Bitmap cc = new Bitmap(v);
            cc.Save("C:''Test''img" + m_Count + ".jpg");
        g.Dispose();
        v.Dispose();
        m_Count++;
        return 0;
        }

DirectShowLib-使用覆盖文本保存视频

通常它应该看起来像:

[File reader] -> [AVI Demuxer] -> (video pin) -> [Video decoder] -> [Sample grabber] -> [Video encoder] -> [AVI Muxer] -> [File writer]
                      |->                                             (audio pin)                             ->|

AVI文件是一个媒体容器,因此您需要将其多路分解以分离流,并在最后将(修改的)流多路复用回AVI容器。当你得到视频流时,它(通常)包含编码的视频。所以要修改它,你需要对它进行解码,然后在修改后将其编码回相同的格式。您不需要对音频流做任何操作,只需将其从解复用器直接引导到复用器即可。[文件写入器]过滤器允许您指定输出文件名。

我不知道什么是"Ds.NET FileFilter",也不知道它如何对视频进行解复用和解码,但似乎可以,因为你可以看到修改后的图片。AVI Muxer是一个标准的MS过滤器,我只是不记得它的名字。您需要选择一个视频编码器。我建议首先在GraphEditor中构建一个简单的图,它不修改图片,只需读取->demux->decod->encode->mux->write即可验证您是否拥有所需的一切,并且它们运行良好。只需尝试播放生成的AVI文件。