如何保存在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;
}
答案 0 :(得分:0)
通常情况应该如下:
[File reader] -> [AVI Demuxer] -> (video pin) -> [Video decoder] -> [Sample grabber] -> [Video encoder] -> [AVI Muxer] -> [File writer]
|-> (audio pin) ->|
AVI文件是一个媒体容器,因此您需要将其解复用为单独的流,最后将多路复用(已修改)的流解复用回AVI容器。获得视频流时(通常)包含编码视频。因此,要修改它,您需要对其进行解码,然后在修改后将其编码回相同的格式。你不需要对音频流做任何事情,只需将它从解复用器直接转到muxer。 [文件编写器]过滤器允许您指定输出文件名。
我不知道" Ds.NET FileFilter"以及它如何解复,然后解码视频,但似乎可以,因为你可以看到你修改过的图片。 AVI Muxer是标准的MS滤波器,我只是不记得它的名字。您需要选择视频编码器。我建议先在GraphEditor中构建一个简单的图形,它不会修改图片,只需读取> demux-> decod-> encode-> mux-> write来验证你有你需要的一切,他们工作正常。只是尝试播放生成的AVI文件。