视频图像处理系列索引 || Arcgis/Engine/Server开发索引 || Web Map Gis开发索引 || jquery表格组件 JQGrid索引
WPF MVVM模式开发实现简明教程索引 || ArcGIS Runtime WPF(.net C#)开发简明教程索引

C#使用 DirectX SDK 9做视频播放器 并在视频画线添加文字 VMR9

视频图像处理系列 索引

 

VS2013下测试通过。

 

在百度中搜索关键字“DirectX SDk”,或者进入微软官网https://www.microsoft.com/en-us/download/details.aspx?id=6812,

下载最新版本的SDK,即DirectX SDK June10

下载后安装。

 

下载DirectShowLib-2005.dll并引用到工程里。

 

代码如下:

 

using DirectShowLib;

using Microsoft.DirectX.Direct3D; using Microsoft.Win32; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Text; using System.Drawing.Imaging; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Xml; namespace VideoConfig { public partial class frmMain : Form {private Color colorKey = Color.Violet; // The color use as ColorKey for GDI operations private Bitmap alphaBitmap; // A ARGB bitmap used for Direct3D operations // Managed Direct3D magic number to retrieve unmanaged Direct3D interfaces private const int DxMagicNumber = -759872593; private Device device = null; // A Managed Direct3D device private PresentParameters presentParams; private Surface surface = null; // A Direct3D suface filled with alphaBitmap private IntPtr unmanagedSurface; // A pointer on the unmanaged surface private IFilterGraph2 graphBuilder = null; private IMediaControl mediaControl = null; private IBaseFilter vmr9 = null; private IVMRMixerBitmap9 mixerBitmap = null; private IVMRWindowlessControl9 windowlessCtrl = null; private bool handlersAdded = false; // Needed to remove delegates public frmMain() { InitializeComponent();this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); // Init Managed Direct3D InitializeDirect3D(); CloseInterfaces(); BuildGraph(@"F:\测试视频.avi"); RunGraph(); } private void InitializeDirect3D() { Device.IsUsingEventHandlers = false; // Basic Presentation Parameters... presentParams = new PresentParameters(); presentParams.Windowed = true; presentParams.SwapEffect = SwapEffect.Discard; // Assume a hardware Direct3D device is available // Add MultiThreaded to be safe. Each DirectShow filter runs in a separate thread... device = new Device( 0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing | CreateFlags.MultiThreaded, presentParams ); alphaBitmap = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height, PixelFormat.Format24bppRgb); // Create a surface from our alpha bitmap surface = new Surface(device, alphaBitmap, Pool.SystemMemory); // Get the unmanaged pointer unmanagedSurface = surface.GetObjectByValue(DxMagicNumber); } private void CloseInterfaces() { if (mediaControl != null) mediaControl.Stop(); if (handlersAdded) RemoveHandlers(); if (vmr9 != null) { Marshal.ReleaseComObject(vmr9); vmr9 = null; windowlessCtrl = null; mixerBitmap = null; } if (graphBuilder != null) { Marshal.ReleaseComObject(graphBuilder); graphBuilder = null; mediaControl = null; } } private void RemoveHandlers() { // remove handlers when they are no more needed handlersAdded = false; this.pictureBox1.Paint -= new PaintEventHandler(MainForm_Paint); this.pictureBox1.Resize -= new EventHandler(MainForm_ResizeMove); this.pictureBox1.Move -= new EventHandler(MainForm_ResizeMove); this.pictureBox1.MouseDown -= new MouseEventHandler(panel2_MouseDown); this.pictureBox1.MouseUp -= new MouseEventHandler(panel2_MouseUp); this.pictureBox1.MouseMove -= new MouseEventHandler(panel2_MouseMove); SystemEvents.DisplaySettingsChanged -= new EventHandler(SystemEvents_DisplaySettingsChanged); } private void AddHandlers() { // Add handlers for VMR purpose this.pictureBox1.Paint += new PaintEventHandler(MainForm_Paint); // for WM_PAINT this.pictureBox1.Resize += new EventHandler(MainForm_ResizeMove); // for WM_SIZE this.pictureBox1.Move += new EventHandler(MainForm_ResizeMove); // for WM_MOVE this.pictureBox1.MouseDown += new MouseEventHandler(panel2_MouseDown); this.pictureBox1.MouseUp += new MouseEventHandler(panel2_MouseUp); this.pictureBox1.MouseMove += new MouseEventHandler(panel2_MouseMove); SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged); // for WM_DISPLAYCHANGE handlersAdded = true; } private void MainForm_Paint(object sender, PaintEventArgs e) { if (windowlessCtrl != null) { IntPtr hdc = e.Graphics.GetHdc(); int hr = windowlessCtrl.RepaintVideo(this.Handle, hdc); e.Graphics.ReleaseHdc(hdc); System.Drawing.Pen pen = new System.Drawing.Pen(Color.LimeGreen); pen.Width = 2; //实时的画矩形 e.Graphics.DrawRectangle(pen, point1.X, point1.Y, point2.X - point1.X, point2.Y - point1.Y); pen.Dispose(); } } private void MainForm_ResizeMove(object sender, EventArgs e) { if (windowlessCtrl != null) { int hr = windowlessCtrl.SetVideoPosition(null, DsRect.FromRectangle(this.pictureBox1.ClientRectangle)); } } private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) { if (windowlessCtrl != null) { int hr = windowlessCtrl.DisplayModeChanged(); } } private void RunGraph() { if (mediaControl != null) { int hr = mediaControl.Run(); DsError.ThrowExceptionForHR(hr); } } private void StopGraph() { if (mediaControl != null) { int hr = mediaControl.Stop(); DsError.ThrowExceptionForHR(hr); } } private void BuildGraph(string fileName) { int hr = 0; try { graphBuilder = (IFilterGraph2)new FilterGraph(); mediaControl = (IMediaControl)graphBuilder; vmr9 = (IBaseFilter)new VideoMixingRenderer9(); ConfigureVMR9InWindowlessMode(); hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9"); DsError.ThrowExceptionForHR(hr); hr = graphBuilder.RenderFile(fileName, null); DsError.ThrowExceptionForHR(hr); mixerBitmap = (IVMRMixerBitmap9)vmr9; } catch (Exception e) { CloseInterfaces(); MessageBox.Show("An error occured during the graph building : \r\n\r\n" + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void ConfigureVMR9InWindowlessMode() { int hr = 0; IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)vmr9; // Not really needed for VMR9 but don't forget calling it with VMR7 hr = filterConfig.SetNumberOfStreams(1); DsError.ThrowExceptionForHR(hr); // Change VMR9 mode to Windowless hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless); DsError.ThrowExceptionForHR(hr); windowlessCtrl = (IVMRWindowlessControl9)vmr9; // Set "Parent" window hr = windowlessCtrl.SetVideoClippingWindow(this.pictureBox1.Handle); DsError.ThrowExceptionForHR(hr); // Set Aspect-Ratio hr = windowlessCtrl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox); DsError.ThrowExceptionForHR(hr); // Add delegates for Windowless operations AddHandlers(); // Call the resize handler to configure the output size MainForm_ResizeMove(null, null); } .............................. .............................. .............................. ..............................

 

 

在视频画线添加文字参考之前的文章。主要是播放控件的MouseDown,MouseMove,MouseUp事件,把画好的东西记到数组内存里,然后在paint事件里重绘。

 

可以轻松的画线、各种图形、文字及叠加图片等。

 

C# winform开发:Graphics、pictureBox同时画多个矩形

c# winform 动态画矩形 矩形大小可以拖动

GDI画图,判断鼠标点击点在某一画好的多边形、矩形、图形里

平面内,线与线 两条线找交点 两条线段的位置关系(相交)判定与交点求解 C#

 

更多内容可以参考DirectShowLib的例子及DirectX SDK的例子

posted @ 2016-07-14 11:09  jhlong  阅读(2197)  评论(0编辑  收藏  举报
海龙的博客 jhlong@cnblogs 版权所有© 转载请注明链接.有用请推荐一下
代码全部经过本人测试,但不保证复制粘贴就正常运行,更不保证能解决你的问题,请结合前后代码及描述理解后修改和使用