Take Snapshots of Videos with WPF
With WPF’s Imaging-Classes you can take snapshots of any Visual. The snapshot can be saved in any common Image-Format, like e.g. JPG. Let’s take a look at a pretty short example, that shows how easy this can be done. The example takes snapshots of a Video.
The following Window contains a MediaElement and a Button. The MediaElement plays the Video thomasOnBoard.wmv. The Button defines an Eventhandler for the Click-Event. It takes a snapshot of the video, when you click it.
<Window x:Class="SnapShots.Window1" xmlns=http://schemas.microsoft.com/winfx/2006/xaml/… xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" ResizeMode="NoResize"> <StackPanel> <MediaElement x:Name="media" Height="200" Stretch="Fill"> <MediaElement.Triggers> <EventTrigger RoutedEvent="MediaElement.Loaded"> <BeginStoryboard> <Storyboard> <MediaTimelineSource="thomasOnBoard.wmv" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </MediaElement.Triggers> </MediaElement> <Button Click="Button_Click" Content="Snapshot"/> </StackPanel> </Window>
Let’s look at the Eventhandler of the Button. An instance of the RenderTargetBitmap-class is created with some parameters about image-size, dots per inch (dpi) and Pixelformat. The Render-Method gets the MediaElement as a parameter, so MediaElements visual appearance is stored in the RenderTargetBitmap in memory. With a JpegBitmapEncoder and a FileStream the Image is written as a JPG to disk. That’s it.
void Button_Click(object sender, RoutedEventArgs e) { Size dpi = new Size(96,96); RenderTargetBitmap bmp = new RenderTargetBitmap(300, 200, dpi.Width, dpi.Height, PixelFormats.Pbgra32); bmp.Render(media); JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmp)); string filename = Guid.NewGuid().ToString()+".jpg"; FileStream fs = new FileStream(filename,FileMode.Create); encoder.Save(fs); fs.Close(); Process.Start(filename); }
Instead of taking the picture in the Button_Click eventhandler, you could create a Timer and take an Image every 0.1s. That allows you to extract an image-sequence of your videos. As it works for any Visual, and everything that’s on the screen in a WPF-Application is a visual, there are many things you can do with it. You could create a snapshot of an Image drawn to an inkCanvas, upload it to a webserver to display it on a webpage etc.



April 6th, 2008 at 10:48 pm
Thomas,
Nice, very nice!
Cheers,
Karl
April 9th, 2008 at 10:38 pm
Hi Karl,
thanks.
Thomas