我创建了自己的画布(黑色区域),我绘制的元素不是从Shape派生的。相反,我使用覆盖方法Canvas.OnRender中的DrawingContext绘制。
问题是,我想播放视频文件并将帧渲染到我画布的特定区域(例如红色矩形) - 也在OnRender中。但通常MediaPlayer直接绑定到一个刷子,它填充了UIElement的完整背景。
任何帮助?
好的,这里有更多解释。我可以向任何方向滚动,平移和缩放画布,然后使用drawingContext影响我在OnRender中绘制的内容。下图显示了一个带有图像(门)的画布,它是从网络摄像头逐帧出现的。因此,只要我的画布无效,我就可以在drawingContext.DrawImage中使用BitmapSource。我仍然可以画出我的原语。 MediaPlayer / MediaElement的问题在于我没有逐帧获取它,但我仍想将其渲染为类似于画布中的网络摄像头图像。
答案 0 :(得分:2)
尝试将Clip应用到您的Canvas,如下所示:
<Canvas Width="800" Height="600" Background="Black">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,10,10" />
<!-- whatever you want -->
</Canvas.Clip>
</Canvas>
答案 1 :(得分:1)
最后,我想出了如何实现这一目标。您只需要一个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>
答案 2 :(得分:0)
我想通过内存流播放视频(带音频)播放,此代码有帮助吗?