2012-11-15 76 views
1

我創建了我自己的畫布(黑色區域),我在其上繪製不是從Shape派生的元素。相反,我使用DrawingContext在overriden方法Canvas.OnRender中繪製。將視頻渲染到畫布中的特定區域

問題是,我想播放視頻文件並將幀渲染到畫布的特定區域(例如紅色矩形) - 也是在OnRender中。但通常情況下,MediaPlayer直接綁定到填充UIElement的完整背景的畫筆。

任何幫助?

enter image description here

好了,這裏的一些更多的解釋。我可以在任何方向上滾動,平移和縮放畫布,然後使用drawingContext在OnRender中繪製內容。下面的圖片顯示了一張帶有從網絡攝像頭逐幀播放的圖像(門)的畫布。因此,只要我的畫布無效,我就可以在drawingContext.DrawImage中使用BitmapSource。而且我仍然可以畫出我的原始人。 MediaPlayer/MediaElement的問題在於我沒有逐幀獲取它,但我仍想將其渲染爲與畫布內的網絡攝像頭圖像相似。

enter image description here

回答

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> 

User drawn ellipse in front of video

2

嘗試運用夾到你的畫布,就像這樣:

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

你能詳細解釋一下嗎? Canvas.Clip使畫布更小。我需要將視頻作爲形狀或類似的東西直接包含在畫布中。 – Matthias

+0

它的工作方式 - 您的畫布以全尺寸繪製。然後應用剪貼蒙版,並使畫布在「剪輯」屬性中定義的幾何外部不可見。所以,它不會讓您的畫布更小,它只顯示由Clip定義的部分。嘗試不同的幾何圖形和佈局來查看發生了什麼 – Encarmine

+0

是的。我明白。但是我的完整繪圖在畫布上,所以我無法將部件剪掉。我只需要將視頻添加到畫布上。視頻前必須有一些形狀可見。 – Matthias

0

我想通過內存流播放視頻都(帶音頻)播放,這段代碼可以幫助?

+0

它不久前,但我想它不能解決您的問題。我的代碼將圖片渲染到繪圖畫布上。這是關於視頻圖像。但我想也有迴音的問題。 – Matthias