首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 Store Apps 開發實戰(6):媒體控件 — Image 圖片九宮格與 MediaElement 影音播放全解析

     編輯:關於.NET

前言

媒體呈現是 App 體驗核心。WinRT 提供 Image(靜態圖片)與 MediaElement(影音播放)兩大控件。本文深入解析 Image 的四種拉伸模式、九宮格 防止邊框變形、多種圖片來源載入方式;以及 MediaElement 的豐富播放控制、狀態監聽、串流來源指定、倍速播放、多音軌切換等進階功能。

一、Image — 圖片顯示與九宮格

Stretch 四種拉伸模式

模式行為保留比例
Fill填滿容器,可能變形否
None原始尺寸,超出容器被裁剪是
Uniform等比縮放至容器內(預設)是
UniformToFill等比縮放填滿容器,超出部分裁剪是

範例:四種模式並列對比(原圖 150×150,容器 200×100)

<StackPanel Orientation="Horizontal" Margin="120 0 0 0">
    <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100">
        <Image Source="/Assets/Logo.png" Stretch="Fill" Width="200" Height="100"/>
    </Border>
    <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100" Margin="20 0 0 0">
        <Image Source="/Assets/Logo.png" Stretch="None" Width="200" Height="100"/>
    </Border>
    <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100" Margin="20 0 0 0">
        <Image Source="/Assets/Logo.png" Stretch="Uniform" Width="200" Height="100"/>
    </Border>
    <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100" Margin="20 0 0 0">
        <Image x:Name="myImage" Stretch="UniformToFill" Width="200" Height="100"/>
    </Border>
</StackPanel>

後台指定圖片來源

private void ImageDemo_Loaded(object sender, RoutedEventArgs e)
{
    // 方式 1:BitmapImage + ms-appx URI
    myImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute));

    // 方式 2:RandomAccessStreamReference + IRandomAccessStream
    // var streamRef = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute));
    // var stream = await streamRef.OpenReadAsync();
    // var bitmap = new BitmapImage();
    // bitmap.SetSource(stream);
    // myImage.Source = bitmap;
}

九宮格 — 保護邊框不變形

NineGrid 以 Thickness 格式指定四條切割線(左、上、右、下),四角不縮放、邊緣單向縮放、中心雙向縮放。適用於按鈕背景、對話框邊框、進度條軌道等。

範例:原圖 16×16,放大至 200×200

<StackPanel Orientation="Horizontal" Margin="0 50 0 0">
    <!-- 無九宮格:邊框被拉伸變粗 -->
    <Image Source="/Assets/NineGrid/Demo.png" Width="200" Height="200"/>

    <!-- 九宮格 1,1,1,1:四邊各保留 1 像素不縮放 -->
    <Image Source="/Assets/NineGrid/Demo.png" Width="200" Height="200"
           NineGrid="1 1 1 1" Margin="20 0 0 0"/>
</StackPanel>

二、MediaElement — 影音播放瑞士刀

核心播放控制

  • Source / SetSource(stream, mimeType):本地檔案或網路串流
  • AutoPlay:載入後自動播放(預設 true)
  • Play()、Pause()、Stop()
  • Position:目前播放位置(TimeSpan,可設定 Seek)
  • CanSeek、CanPause:媒體能力查詢

進階播放速率控制

場景DefaultPlaybackRatePlaybackRate
正常播放11
2 倍速快轉02
1 倍速倒轉0-1

💡 規則:PlaybackRate != 1 時,必須先將 DefaultPlaybackRate = 0。

音訊屬性

  • Volume (0~1)、Balance (-1~1)、IsMuted
  • AudioCategory:ForegroundOnlyMedia(前台)、BackgroundCapableMedia(支援背景播放)
  • AudioStreamCount、AudioStreamIndex、GetAudioStreamLanguage(index):多音軌切換
  • AudioDeviceType:輸出裝置類型

視訊屬性

  • NaturalVideoWidth/Height、AspectRatioWidth/Height:原始解析度與比例
  • PosterSource:影片載入前顯示的佔位圖(同 HTML5 video poster)
  • IsAudioOnly:純音訊為 true

進度與緩衝監聽

  • DownloadProgress (0~1):下載進度
  • DownloadProgressOffset:Seek 後重新連線的偏移比例
  • BufferingProgress (0~1):緩衝進度,達 1 可播放

事件

  • MediaOpened、MediaEnded、MediaFailed
  • CurrentStateChanged:Closed/Opening/Buffering/Playing/Paused/Stopped
  • DownloadProgressChanged、BufferingProgressChanged
  • RateChanged、VolumeChanged、MarkerReached(時間標記)

完整範例:檔案選擇器 + 網路影片 + 即時狀態顯示

<StackPanel Orientation="Horizontal" Margin="120 0 0 0">
    <StackPanel>
        <Button x:Name="btnPickFile" Content="播放本地影音" Click="btnPickFile_Click"/>
        <Button x:Name="btnPlayUrl" Content="播放網路影片" Click="btnPlayUrl_Click" Margin="0 10 0 0"/>
        <StackPanel Orientation="Horizontal" Margin="0 10 0 0">
            <Button x:Name="btnPlay" Content="播放" Margin="0 0 10 0" Click="btnPlay_Click"/>
            <Button x:Name="btnPause" Content="暫停" Margin="0 0 10 0" Click="btnPause_Click"/>
            <Button x:Name="btnStop" Content="停止" Margin="0 0 10 0" Click="btnStop_Click"/>
        </StackPanel>
        <MediaElement x:Name="mediaElement" AutoPlay="True"
                      PosterSource="/Assets/Logo.png"
                      Width="480" Height="320"
                      HorizontalAlignment="Left" VerticalAlignment="Top"
                      Margin="0 10 0 0"/>
    </StackPanel>
    <TextBlock x:Name="lblMsg" FontSize="14.667" Margin="10 0 0 0"/>
</StackPanel>

後台:DispatcherTimer 每 100ms 更新狀態顯示

public sealed partial class MediaElementDemo : Page
{
    public MediaElementDemo()
    {
        this.InitializeComponent();
        var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
        timer.Tick += dTimer_Tick;
        timer.Start();
    }

    void dTimer_Tick(object sender, object e)
    {
        lblMsg.Text = "Source: " + mediaElement.Source + "\n";
        lblMsg.Text += "PosterSource: " + mediaElement.PosterSource + "\n";
        lblMsg.Text += "CurrentState: " + mediaElement.CurrentState + "\n";
        lblMsg.Text += "Position: " + mediaElement.Position + "\n";
        lblMsg.Text += "DownloadProgress: " + mediaElement.DownloadProgress + "\n";
        lblMsg.Text += "DownloadProgressOffset: " + mediaElement.DownloadProgressOffset + "\n";
        lblMsg.Text += "BufferingProgress: " + mediaElement.BufferingProgress + "\n";
        lblMsg.Text += "DefaultPlaybackRate: " + mediaElement.DefaultPlaybackRate + "\n";
        lblMsg.Text += "PlaybackRate: " + mediaElement.PlaybackRate + "\n";
        lblMsg.Text += "CanSeek: " + mediaElement.CanSeek + "\n";
        lblMsg.Text += "CanPause: " + mediaElement.CanPause + "\n";
        lblMsg.Text += "NaturalDuration: " + mediaElement.NaturalDuration + "\n";
        lblMsg.Text += "NaturalVideoWidth: " + mediaElement.NaturalVideoWidth + "\n";
        lblMsg.Text += "NaturalVideoHeight: " + mediaElement.NaturalVideoHeight + "\n";
        lblMsg.Text += "AspectRatioWidth: " + mediaElement.AspectRatioWidth + "\n";
        lblMsg.Text += "AspectRatioHeight: " + mediaElement.AspectRatioHeight + "\n";
        lblMsg.Text += "AutoPlay: " + mediaElement.AutoPlay + "\n";
        lblMsg.Text += "IsLooping: " + mediaElement.IsLooping + "\n";
        lblMsg.Text += "Volume: " + mediaElement.Volume + "\n";
        lblMsg.Text += "Balance: " + mediaElement.Balance + "\n";
        lblMsg.Text += "IsMuted: " + mediaElement.IsMuted + "\n";
        lblMsg.Text += "IsAudioOnly: " + mediaElement.IsAudioOnly + "\n";
        lblMsg.Text += "AudioCategory: " + mediaElement.AudioCategory + "\n";
        lblMsg.Text += "AudioStreamCount: " + mediaElement.AudioStreamCount + "\n";
        lblMsg.Text += "AudioStreamIndex: " + mediaElement.AudioStreamIndex + "\n";
        lblMsg.Text += "AudioDeviceType: " + mediaElement.AudioDeviceType + "\n";
    }

    private async void btnPickFile_Click(object sender, RoutedEventArgs e)
    {
        var picker = new FileOpenPicker
        {
            SuggestedStartLocation = PickerLocationId.VideosLibrary
        };
        picker.FileTypeFilter.Add(".wmv");
        picker.FileTypeFilter.Add(".mp4");
        picker.FileTypeFilter.Add(".mp3");
        picker.FileTypeFilter.Add(".wma");

        var file = await picker.PickSingleFileAsync();
        if (file != null)
        {
            var stream = await file.OpenAsync(FileAccessMode.Read);
            mediaElement.SetSource(stream, file.ContentType);
        }
    }

    private void btnPlayUrl_Click(object sender, RoutedEventArgs e)
    {
        mediaElement.Source = new Uri("https://media.w3.org/2010/05/sintel/trailer.mp4", UriKind.Absolute);
    }

    private void btnPlay_Click(object sender, RoutedEventArgs e) => mediaElement.Play();
    private void btnPause_Click(object sender, RoutedEventArgs e) => mediaElement.Pause();
    private void btnStop_Click(object sender, RoutedEventArgs e) => mediaElement.Stop();
}

CanPlayType 偵測格式支援度

// 回傳 "Probably" / "Maybe" / ""
var likelihood = mediaElement.CanPlayType("video/mp4");

三、小結

  1. Image:四種 Stretch 模式按需選擇,NineGrid 完美解決邊框縮放變形,支援 ms-appx/ms-appdata/http/串流多種來源
  2. MediaElement:功能極其完整,涵蓋播放控制、倍速/倒轉、Seek、多音軌、音訊類別(背景播放)、緩衝監聽、佔位圖、格式偵測
  3. 效能提示:大量圖片使用虛擬化面板、釋放未顯示 Image.Source、MediaElement 釋放時呼叫 Stop() 並設 Source=null

掌握這兩大控件,即可構建圖文並茂、影音豐富的現代化 App 體驗。


原始碼下載:https://files.cnblogs.com/webabcd/Windows8.rar

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved