--- name: integrating-wpf-media description: Integrates multimedia content in WPF including MediaElement video/audio playback, Image control display, and SoundPlayerAction effects. Use when building media players, galleries, or multimedia UIs. --- # WPF Media Integration Patterns Integrating multimedia content such as images, video, and audio in WPF. ## 1. Image Control ### 1.1 Basic Image Display ```xml ``` ### 1.2 Stretch Options ```xml ``` ### 1.3 Dynamic Image Loading ```csharp namespace MyApp.Helpers; using System; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; public static class ImageHelper { /// /// Load image from file /// public static BitmapImage LoadFromFile(string filePath) { var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.UriSource = new Uri(filePath, UriKind.Absolute); bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); // Can be used outside UI thread return bitmap; } /// /// Load image from stream /// public static BitmapImage LoadFromStream(Stream stream) { var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = stream; bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); return bitmap; } /// /// Load thumbnail (memory optimization) /// public static BitmapImage LoadThumbnail(string filePath, int maxWidth, int maxHeight) { var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.UriSource = new Uri(filePath, UriKind.Absolute); bitmap.DecodePixelWidth = maxWidth; bitmap.DecodePixelHeight = maxHeight; bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); return bitmap; } /// /// Load image from Base64 /// public static BitmapImage LoadFromBase64(string base64) { var bytes = Convert.FromBase64String(base64); using var stream = new MemoryStream(bytes); return LoadFromStream(stream); } } ``` ### 1.4 Image Load Events ```csharp // XAML // private void LoadImageAsync(string url) { var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.UriSource = new Uri(url); bitmap.EndInit(); // Loading complete event bitmap.DownloadCompleted += (s, e) => { // Image load complete }; // Loading failed event bitmap.DownloadFailed += (s, e) => { // Error handling }; // Loading progress bitmap.DownloadProgress += (s, e) => { var progress = e.Progress; // 0-100 }; DynamicImage.Source = bitmap; } ``` --- ## 2. MediaElement (Video/Audio) ### 2.1 Basic Usage ```xml ``` ### 2.2 LoadedBehavior Options | Value | Description | |-------|-------------| | **Play** | Auto-play | | **Pause** | Pause after load | | **Stop** | Stop after load | | **Manual** | Control via code | | **Close** | Close media | ### 2.3 Video Player Implementation ```csharp namespace MyApp.Controls; using System; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; public sealed partial class VideoPlayerControl : UserControl { private readonly DispatcherTimer _positionTimer; private bool _isDragging; public VideoPlayerControl() { InitializeComponent(); _positionTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) }; _positionTimer.Tick += OnPositionTimerTick; } private void OnMediaOpened(object sender, RoutedEventArgs e) { // Display total duration if (VideoPlayer.NaturalDuration.HasTimeSpan) { var duration = VideoPlayer.NaturalDuration.TimeSpan; PositionSlider.Maximum = duration.TotalSeconds; TotalTimeText.Text = FormatTime(duration); } _positionTimer.Start(); } private void OnMediaEnded(object sender, RoutedEventArgs e) { _positionTimer.Stop(); VideoPlayer.Stop(); VideoPlayer.Position = TimeSpan.Zero; } private void OnMediaFailed(object sender, ExceptionRoutedEventArgs e) { // Media load failed MessageBox.Show($"Media load failed: {e.ErrorException.Message}"); } private void OnPositionTimerTick(object? sender, EventArgs e) { if (!_isDragging) { PositionSlider.Value = VideoPlayer.Position.TotalSeconds; CurrentTimeText.Text = FormatTime(VideoPlayer.Position); } } private void PlayButton_Click(object sender, RoutedEventArgs e) { VideoPlayer.Play(); _positionTimer.Start(); } private void PauseButton_Click(object sender, RoutedEventArgs e) { VideoPlayer.Pause(); } private void StopButton_Click(object sender, RoutedEventArgs e) { VideoPlayer.Stop(); _positionTimer.Stop(); } private void PositionSlider_DragStarted(object sender, EventArgs e) { _isDragging = true; } private void PositionSlider_DragCompleted(object sender, EventArgs e) { _isDragging = false; VideoPlayer.Position = TimeSpan.FromSeconds(PositionSlider.Value); } private void VolumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { VideoPlayer.Volume = e.NewValue; } private static string FormatTime(TimeSpan time) { return time.Hours > 0 ? $"{time:hh\\:mm\\:ss}" : $"{time:mm\\:ss}"; } } ``` ### 2.4 VideoPlayerControl XAML ```xml ``` --- ## 4. Image Gallery & Performance For gallery implementation and optimization, see [references/media-gallery.md](references/media-gallery.md): - **Gallery ViewModel**: MVVM pattern with thumbnail loading - **Gallery View**: ListBox with virtualization - **Performance Optimization**: DecodePixelWidth, Freeze(), lazy loading --- ## 5. References - [Image Class - Microsoft Docs](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.image) - [MediaElement Class - Microsoft Docs](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.mediaelement) - [Multimedia Overview - Microsoft Docs](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/multimedia-overview)