最后我想出了如何实现这一点。您只需要一个 MediaPlayer 并将其输入到每个 Canvas.OnRender 循环中的 drawingContext.DrawVideo 中。示例图片和代码如下。我还包括了从视频中捕获帧(BitmapSource)的方法,以及如何将其转换为旧的 System.Drawing.Bitmap)。
public partial class RenderCanvas : UserControl
{
readonly MediaPlayer player;
public RenderCanvas()
{
InitializeComponent();
player = new MediaPlayer();
player.Open(new Uri(@"test.avi", UriKind.Relative));
player.Play();
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
if (player != null && player.Source != null)
drawingContext.DrawVideo(player, new Rect(0, 0, 200, 150));
// draw any shape in front of the video
drawingContext.DrawEllipse(Brushes.Blue, new Pen(Brushes.Red, 5), new Point(150, 150), 60, 60);
}
BitmapSource GetBitmapSourceFromVideo()
{
var drawingVisual = new DrawingVisual();
var renderTargetBitmap = new RenderTargetBitmap(player.NaturalVideoWidth, player.NaturalVideoHeight, 96, 96, PixelFormats.Default);
using (var drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawVideo(player, new Rect(0, 0, player.NaturalVideoWidth, player.NaturalVideoHeight));
}
renderTargetBitmap.Render(drawingVisual);
return renderTargetBitmap;
}
System.Drawing.Bitmap GetBitmapFromVideo()
{
BitmapSource bitmapSource = GetBitmapSourceFromVideo();
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
stream.Seek(0, SeekOrigin.Begin);
return (System.Drawing.Bitmap)System.Drawing.Image.FromStream(stream);
}
}
}
这里是示例应用程序的 XAML 代码。RenderCanvas 的 XAML 没有变化。
<Window x:Class="CanvasTest_OnRender.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CanvasTest_OnRender="clr-namespace:CanvasTest_OnRender" Title="MainWindow" Height="350" Width="525">
<Grid>
<CanvasTest_OnRender:RenderCanvas />
</Grid>
</Window>
