【问题标题】:Render video to specific region in a canvas将视频渲染到画布中的特定区域
【发布时间】:2012-11-15 12:15:02
【问题描述】:

我创建了自己的画布(黑色区域),我在上面绘制了不是从 Shape 派生的元素。相反,我使用覆盖方法 Canvas.OnRender 中的 DrawingContext 进行绘制。

问题是,我想播放视频文件并将帧渲染到画布的特定区域(例如红色矩形) - 也在 OnRender 中。但通常 MediaPlayer 直接绑定到填充 UIElement 的完整背景的画笔。

有什么帮助吗?

好的,这里有更多的解释。我可以在任何方向滚动、平移和缩放我的画布,然后影响我使用绘图上下文在 OnRender 中绘制的内容。下图显示了带有图像(门)的画布,该图像(门)逐帧来自网络摄像头。因此,只要我的画布失效,我就可以在 drawingContext.DrawImage 中使用 BitmapSource。我仍然可以画出我的图元。 MediaPlayer/MediaElement 的问题是我没有逐帧获取它,但我仍然希望将其渲染为类似于画布中的网络摄像头图像。

【问题讨论】:

    标签: wpf video wpf-controls media-player render


    【解决方案1】:

    尝试将 Clip 应用到您的 Canvas,如下所示:

    <Canvas Width="800" Height="600" Background="Black">
        <Canvas.Clip>
            <RectangleGeometry Rect="0,0,10,10" />
                 <!-- whatever you want -->    
        </Canvas.Clip>
    </Canvas>
    

    【讨论】:

    • 你能详细解释一下吗? Canvas.Clip 使画布变得更小。我需要将视频作为形状或类似的东西直接包含在画布中。
    • 它就是这样工作的——你的画布被绘制成全尺寸。然后应用剪贴蒙版,并使画布在几何外部不可见,在 Clip 属性中定义。所以,它不会让你的画布变小,它只显示 Clip 定义的部分。尝试不同的几何形状和位置,看看会发生什么。
    • 是的。我明白。但是我的完整画在画布上,所以我不能把部分剪掉。我只需要将视频添加到画布上。并且某些形状必须在视频前面可见。
    • 那你为什么不能把你的画布和视频放到普通的画布上,以及你需要的任何形状?如果你能澄清你的问题会更好。
    • 因为我的画布是在 OnRender 中使用 DrawContext 而不是使用形状绘制的。如果我将另一个画布放入我的画布中,这将在我的绘图前面隐藏所有其他内容。
    【解决方案2】:

    最后我想出了如何实现这一点。您只需要一个 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>
    

    【讨论】:

      【解决方案3】:

      我想通过内存流同时播放视频(带音频)播放,这段代码有帮助吗?

      【讨论】:

      • 前一阵子,但我想这并不能解决您的问题。我的代码将图片渲染到绘图画布上。所以这是关于视频图像的。但我想也有音频回调。
      猜你喜欢
      • 2019-04-16
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 2012-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-04
      相关资源
      最近更新 更多