Menü 1 für Einsteiger: Webcam Snapshot als JPEG
Der Webcam-Support von Silverlight 4 besitzt eine Funktion zum Erstellen von Schnappschüssen (Snapshots). Diese werden asynchron an den Webcam-Treiber gestellt. Das Ergebnis ist eine rohe Bitmap-Datei. Jedoch verbrauchen Bitmap-Dateien enorm viel Speicher. Silverlight 4 bietet leider keine fertigen Möglichkeiten zum Konvertieren des Bitmap-Streams zu anderen Grafikformaten. Diese müssen mühselig selbst geschrieben werden, oder man verwendet die fertigen Libraries des Open-Source-Projekts ImageTools for Silverlight. Ein Beispielprojekt soll den einfachen Einsatz der ImageTools demonstrieren. Dazu wurde ein neues Silverlight-4-Projekt WebcamSnapshotAsJpeg angelegt. Die Oberfläche (MainPage.xaml) erhält ein StackPanel mit einem Rectangle für das Webcam-Bild und einem Button zum Auslösen des Schnappschusses (Listing 1).
Listing 1: MainPage.xaml mit Webcam-Screen und Auslöser-Button
In der Code-Behind-Datei (MainPage.xaml.cs) wird ein Loaded Event abonniert, sodass beim fertigen Laden der Oberfläche die Webcam durch eine Instanz von CaptureSource gestartet wird. Beim Klick auf den Button wird eine asynchrone Anfrage mit CaptureSource gestellt. Erhalten wir die Antwort im CaptureImageCompleted-Event, bieten uns die CaptureImageCompletedEventArgs eine WriteableBitmap-Instanz, worin der Snapshot im Bitmap-Format enthalten ist.
Nach dem Herunterladen und Entpacken von ImageTools for Silverlight müssen folgende Assemblies referenziert werden: ICSharpCode.SharpZipLib.Silverlight.dll, ImageTools.dll, ImageTools.IO.Jpeg.dll, ImageTools.Utils.dll. Daraufhin kann die WriteableBitmap-Instanz mittels JpegEncoder-Instanz zu einem JPEG-Format konvertiert werden (Listing 2).
Listing 2: MainPage.xaml.cs – Snapshot als JPEG-Datei abspeichern
public partial class MainPage : UserControl { private CaptureSource _captureSource; public MainPage() { InitializeComponent(); Loaded += MainPageLoaded; } private void MainPageLoaded(object sender, RoutedEventArgs e) { if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess()) { _captureSource = new CaptureSource(); _captureSource.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice(); _captureSource.AudioCaptureDevice = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice(); VideoBrush videoBrush = new VideoBrush(); videoBrush.SetSource(_captureSource); videoBrush.Stretch = Stretch.UniformToFill; Screen.Fill = videoBrush; _captureSource.Start(); } } private void BtnTakeSnapshot_Click(object sender, RoutedEventArgs e) { SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.Filter = "JPG Files (*.jpg, *.jpeg)|*.jpg;*.jpeg|All Files (*.*)|*.*"; saveDialog.DefaultExt = ".jpg"; saveDialog.FilterIndex = 1; bool saveStateReady = (bool) saveDialog.ShowDialog(); _captureSource.CaptureImageCompleted += (s, eventArgs) => { WriteableBitmap snapshot = eventArgs.Result; if (snapshot != null) { if (saveStateReady) { using (Stream stream = saveDialog.OpenFile()) { var image = snapshot.ToImage(); var encoder = new JpegEncoder(); encoder.Quality = 90; encoder.Encode(image, stream); stream.Close(); _captureSource.Stop(); } } } }; _captureSource.CaptureImageAsync(); } }