我正在制作一个应用程序,允许用户应用某些工具来分析视频和图像。我需要帮助我如何在我的表单中加载到 Windows 媒体播放器中的视频上实际绘制/写入并能够保存它。它需要能够让用户在其上徒手绘制和绘制形状。提前致谢,
克里斯 :)
这是使用 winforms 中的 wmp 控件完成的一项重要任务,如果不是不可能的话。
我不知道实际在 wmp 上绘制的任何方法,但您可以在覆盖在 wmp 上的透明面板上绘制。如果视频正在播放,这将不起作用,但您可以在暂停时显示绘图。我已经使用这种技术绘制了一个与 wmp 类似的第 3 方视频控件。(编辑 - 这似乎不适用于 wmp 控件)
然而,由于真正的透明面板在 winforms 中也相当棘手,另一种方法是从视频中抓取图像并在覆盖的图像上绘制。同样,仅当它暂停时。
这种商业控制确实可以在视频上绘图。它有一个事件可以触发您可以用来进行绘图的每一帧。但是,最大的缺点是您不能真正做任何太花哨的事情,因为您的绘图程序需要在绘制下一帧之前完成。
我强烈建议您使用 WPF(即使它是在 winforms 应用程序中托管的 wpf 控件)来显示您的视频。在 wpf 中绘制视频(包括播放视频)要容易得多。
编辑
我刚刚测试了使用透明面板在 wmp 上绘图,它的行为不像我的第 3 方控件那样,所以我建议你在 WPF 中播放视频并将其托管在你的 winforms 应用程序中。(我刚刚也使用@Callums inkcanvas 建议对其进行了测试,它就像一个魅力)
This can be done in WinForms but it is not easy. There is transparent form support with alpha blending in WinForms. Use the following CreateParams for the transparent overlay form: WS_EX_LAYERED, WS_EX_TRANSPARENT. Check the MSDN references for this type of window: http://msdn.microsoft.com/en-us/library/ms997507.aspx, http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#layered.
Put a transparent form above your video control and you can draw anything you want on it. Move and resize events need to be coordinated between your video window and the transparent form above it. Redrawing the overlay needs to use UpdateLayeredWindow() in user32.dll.
I learned quite a bit from this example: http://www.codeproject.com/Articles/13558/AlphaGradientPanel-an-extended-panel.
我已经找到了如何做到这一点。
这是在 WPF 中使用 Canvas 的一种方式
private void buttonPlayVideo_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "All Files|*.*";
Nullable<bool> 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);
}
如果您使用的是 WPF,请尝试在视频顶部放置 InkCanvas并将其 设置为透明。然后,您可以保存并加载用户在视频顶部绘制的形状。Background
带有图片而不是视频的一点概念验证:
我怀疑您可能正在使用 WinForms,但这可能会更困难。如果是这样,学习 WPF 的好借口!
编辑:使用 WinForms,您必须制作自己的自定义控件,充当透明叠加层并向其添加画笔描边。很难很好地实现(具有透明背景,与 WinForms 不兼容)。如果您仍处于可以更改应用程序 UI 的阶段,我建议您使用 WPF。WPF 适用于 XP 及更高版本。
EDIT2:谷歌搜索后,人们为 WinForms 制作了一些InkCanvas 等价物,但我不知道它们有多好,并且可能不支持透明背景。
您始终可以在新的 WPF 窗口中添加要注释的视频,并在 WinForms 中添加应用程序的其余部分。
您可以查看 Microsoft 的 XNA (www.xna.com)。它是为 c# 等托管语言制作的,应该支持 video。
我只用它在 c# 中绘图,但它完成了工作。
我还应该注意,XNA 将作为常规 Windows 窗体应用程序的一部分运行。值得一提的是,我还用 Flash 制作了类似的原型;Flash 允许您将电影文件的每一帧导入到编辑器中,并创建一个可以响应用户交互的 SWF。
但是,如果您需要实时更新电影,这种方法是没有用的。Flash(我最后一次检查)只能在设计时导入电影。
好的,到目前为止,最好的方法是使用 Silverlight。Silverlight 支持所有主要的流格式,还提供对帧缓冲区的完整访问。
简单的 :-)