A simple snapshot taker application in WPF

The simple application is implemented using media player in WPF. You can also use this code to make preview of video in WPF. Here MediaPlayer is used to play video instead of MediaElement. There is nothing ground breaking here. The overall idea is: as we are playing video in content control which is a visual and we know, we can make image from any visual, so we are just making image from the video content control. The simple snapshot taker application looks like the following:

snapshotTaker

Here an openfiledialog is used to open video file. If you select non-video file, the application will give you the message “invalid file”. Process.Start(filename) starts a viewer by specifying a file name. It is similar to typing the information in the run dialog box of the Windows Start menu. The used c# code for this is in the following:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Windows;
   6: using System.Windows.Media;
   7: using System.Windows.Controls;
   8: using System.Windows.Media.Imaging;
   9: using System.Windows.Shapes;
  10: using System.IO;
  11:  
  12: namespace SnapShotUsingMediaPlayer
  13: {
  14:     public class MediaPlayerControl : ContentControl
  15:     {      
  16:         MediaPlayer _MediaPlayer;
  17:         private Uri _Source = null;
  18:         public Uri Source
  19:         {
  20:             get { return _Source; }
  21:             set
  22:             {
  23:                 _Source = value;
  24:                 Play(value);
  25:             }
  26:         }
  27:  
  28:         public void Play(Uri source)
  29:         {
  30:             if (_MediaPlayer == null)
  31:             {
  32:                 _MediaPlayer = new MediaPlayer();
  33:  
  34:             }
  35:             _MediaPlayer.MediaFailed += new EventHandler<ExceptionEventArgs>(_MediaPlayer_MediaFailed);           
  36:             _MediaPlayer.MediaOpened += new EventHandler(_MediaPlayer_MediaOpened);
  37:             _MediaPlayer.Open(source);     
  38:         }
  39:  
  40:         void _MediaPlayer_MediaOpened(object sender, EventArgs e)
  41:         {
  42:             System.Threading.Thread.Sleep(1000);
  43:             VideoDrawing videoDrawing = new VideoDrawing();
  44:             videoDrawing.Player = _MediaPlayer;
  45:             videoDrawing.Rect = new Rect(0, 0, _MediaPlayer.NaturalVideoWidth, _MediaPlayer.NaturalVideoHeight);
  46:             Rectangle rectangle = new Rectangle();
  47:             rectangle.Height = this.Height;
  48:             rectangle.Width = this.Width;
  49:             Brush brush = new DrawingBrush(videoDrawing);
  50:             rectangle.Fill = brush;
  51:             this.Content = rectangle;
  52:             _MediaPlayer.Play();           
  53:         }
  54:  
  55:         void _MediaPlayer_MediaFailed(object sender, ExceptionEventArgs e)
  56:         {
  57:             MessageBox.Show("Invalid File");
  58:         }
  59:  
  60:         public string Takesnapshot()
  61:         {            
  62:             RenderTargetBitmap renderBitmap = new RenderTargetBitmap(300, 300, 96, 96, PixelFormats.Pbgra32);
  63:             renderBitmap.Render(this);
  64:             string filename = "Temp" + ".gif";
  65:             FileStream fs = new FileStream(filename, FileMode.Create);
  66:             BitmapEncoder encoder = new GifBitmapEncoder();
  67:             encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
  68:             encoder.Save(fs);
  69:             fs.Close();
  70:             return filename;
  71:         }
  72:     }
  73: }

VideoDrawing draws video to the specified rectangle. Here we have used fixed size rectangle with size 300*300 to show the video from VideoDrawing. We have made drawing brush from video drwaing and used this video drwaing to fill the rectangle. As we have not made VideoDrawing freeze, so it will change its content with time when media player is playing. RenderTargetBitmap Class is used to convert the video container element into a bitmap. Then GifBitmapEncoder is used to encode the bitmap into gif format and then the gif file is saved as temp.gif.

The used XAML for this is in the following:

   1: <Window x:Class="SnapShotUsingMediaPlayer.Window1"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:         xmlns:local ="clr-namespace:SnapShotUsingMediaPlayer"
   5:     Title="Window1" Height="500" Width="500">
   6:     <StackPanel>
   7:         <Button FontSize="20"  Margin="0,5,0,0"  HorizontalAlignment="Center" Width="Auto" Name="btnOpenFile" Click="btnOpenFile_Click"  Content="Open Video File"/>
   8:         <Border BorderThickness="2" Margin="0,10,0,0" Height="300" Width="300" BorderBrush="Black">
   9:             <local:MediaPlayerControl x:Name="player" Background="Black"  Width="300" Height="300"  />
  10:             </Border>
  11:         <StackPanel Margin="0,5,0,0"  Orientation="Horizontal" Width="Auto" HorizontalAlignment="Center" VerticalAlignment="Center" >
  12:             <Button FontSize="20" Name="btnTakeSnapShot" Click="btnTakeSnapShot_Click"  Content="Take SnapShot"/>
  13:         </StackPanel>
  14:     </StackPanel>
  15: </Window>

You can download the sample code from here. Hope this will save some of your time.

No Comments