在C#中绘制video

我正在制作一个应用程序,允许用户应用某些工具来分析video和图像。 我需要帮助我如何在我的表单中加载到Windows媒体播放器中的video上绘制/写入并能够保存它。 它需要能够让用户在其上绘制手绘和形状。 提前致谢,

克里斯 :)

对于winforms中的wmp控件来说,这是一项非常重要的任务,如果不是不可能完成的话。

我不知道有什么方法可以实际绘制wmp,但你可以在覆盖wmp的透明面板上绘制。 video正在播放时无效,但您可以在暂停时显示绘图。 我已经使用这种技术来绘制与wmp类似的第三方video控件。 (编辑 – 这似乎不适用于wmp控件)

然而,由于真正的透明面板在winforms中也相当棘手,另一种方法是从video中抓取图像并在覆盖的图像上绘制。 再次,只有当它被暂停时。

此商业控件确实可以绘制video。 它有一个事件可以触发您可以用来绘制的每个帧。 但是,最大的缺点是你不能真正做任何太花哨的事情,因为你的绘图程序需要在绘制下一帧之前完成。

我强烈建议您使用WPF(即使是winforms应用程序中托管的wpf控件)来显示您的video。 在wpf中绘制video(包括播放video)要容易得多。

编辑

我刚刚使用透明面板测试了wmp上的绘图,并且它不像我的第三方控件那样表现,所以我建议你在WPF中进行video播放并在winforms应用程序中托管 。 (我刚刚使用@Callums inkcanvas建议测试它,它就像一个魅力)

如果您使用的是WPF,请尝试在video上放置 InkCanvas并将Background设置为透明。 然后,您可以保存并加载用户在video顶部绘制的形状。

一个小概念validation与图片而不是video:

替代文字

我怀疑你可能正在使用WinForms,这可能会更困难。 如果是这样,学习WPF的好借口!


编辑:使用WinForms,您必须制作自己的自定义控件,作为透明叠加层并添加笔刷笔触。 实现起来非常困难(透明背景,WinForms不能很好地实现)。 如果您仍处于可以更改应用程序UI的阶段,我建议您使用WPF。 WPF适用于XP及以上版本。


编辑2:谷歌搜索后,有一些人们为WinForms做的InkCanvas等价物 ,但我不知道他们有多好,可能不支持透明背景。

您可以随时在新的WPF窗口中使用您需要注释的video,并在WinForms中使用其余的应用程序。

这可以在WinForms中完成,但这并不容易。 在WinForms中有alpha混合的透明表单支持。 使用以下CreateParams作为透明覆盖表单:WS_EX_LAYERED,WS_EX_TRANSPARENT。 检查此类窗口的MSDN参考: http : //msdn.microsoft.com/en-us/library/ms997507.aspx,http : //msdn.microsoft.com/en-us/library/ms632599%28VS。 85%29.aspx#layered 。

在video控件上方放置一个透明表单,您可以在其上绘制任何内容。 移动和resize事件需要在video窗口和其上方的透明表单之间进行协调。 重新绘制叠加层需要在user32.dll中使用UpdateLayeredWindow()。

我从这个例子中学到了很多东西: http : //www.codeproject.com/Articles/13558/AlphaGradientPanel-an-extended-panel 。

您可以查看Microsoft的XNA(www.xna.com)。 它适用于c#等托管语言,应支持video 。

我只用它来绘制c#,但它完成了工作。

我还应该注意,XNA将作为常规Windows窗体应用程序的一部分。 为了它的价值,我还用Flash制作了这样的原型; Flash允许您将影片文件的每个帧导入编辑器,并创建可以响应用户交互的SWF。

但是,如果您需要实时更新电影,这种方法将毫无用处。 Flash(我最后检查过)只能在设计时导入电影。

我发现了如何做到这一点。
这是WPF中使用Canvas的一种方法

 private void buttonPlayVideo_Click(object sender, RoutedEventArgs e) { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); dlg.Filter = "All Files|*.*"; Nullable result = dlg.ShowDialog(); if (result == true) { MediaPlayer mp = new MediaPlayer(); mp.Open(new Uri(filename)); VideoDrawing vd = new VideoDrawing(); vd.Player = mp; vd.Rect = new Rect(0, 0, 960, 540); DrawingBrush db = new DrawingBrush(vd); canvas.Background = db; mp.Play(); } } 

然后为Canvas创建鼠标事件并使用它进行绘制

 Point startPoint, endPoint; private void canvas_MouseDown(object sender, MouseButtonEventArgs e) { startPoint = e.GetPosition(canvas); } private void canvas_MouseUp(object sender, MouseButtonEventArgs e) { endPoint = e.GetPosition(canvas); Line myLine = new Line(); myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue; myLine.X1 = startPoint.X; myLine.Y1 = startPoint.Y; myLine.X2 = endPoint.X; myLine.Y2 = endPoint.Y; myLine.HorizontalAlignment = HorizontalAlignment.Left; myLine.VerticalAlignment = VerticalAlignment.Center; myLine.StrokeThickness = 2; canvas.Children.Add(myLine); } 

好吧,到目前为止,最好的方法是使用Silverlight。 Silverlight支持所有主要的流格式,并提供对帧缓冲区的完全访问。

简单 :-)