載入根據縮放比例、主題、高對比等量身打造的影像和資源

您的應用程式載入的影像資源 (或其他資產檔案) 可針對顯示比例因素、主題、高對比和其他執行階段內容而量身打造。 這類影像可從命令式程式碼或 XAML 標記中參照,例如當作 ImageSource 屬性。 它們也可能顯示在應用程式套件資訊清單來源檔 (Package.appxmanifest 檔案),例如在 Visual Studio 資訊清單設計工具的 [視覺資產] 索引標籤中顯示為應用程式的值,或者顯示在圖磚或快顯中。 在影像檔案名稱中使用限定詞,以及選擇性地透過 ResourceContext 協助來動態載入檔案,您可以讓最合適的影像檔案載入,以便與使用者的顯示比例、主題、高對比、語言和其他內容的執行階段設定達成契合。

影像資源檔案包含影像資源。 您可以將影像視為資產,而包含資產的檔案就是資產檔案;您可以在專案的 \Assets 資料夾找到這類資源檔案。 如需了解在影像資源檔案的名稱中使用限定詞的背景資訊,請參閱量身打造語言、比例和其他限定詞適用的資源

影像的一些常見限定詞是縮放比例主題對比目標大小

限定影像資源的比例、主題和對比

scale 限定詞的預設值為 scale-100。 因此,這兩種變數是相等的 (它們都以比例 100 或比例因數 1 來提供影像)。

\Assets\Images\logo.png
\Assets\Images\logo.scale-100.png

您使用限定詞的位置可以從檔案名稱改為資料夾名稱。 如果您有數個限定詞的資產檔案,那將會是更好的策略。 基於說明的目的,這兩種變數與上述兩者相同。

\Assets\Images\logo.png
\Assets\Images\scale-100\logo.png

下個範例會說明如何針對不同的顯示縮放比例、主題和高對比設定來提供影像資源變數 (名稱為 /Assets/Images/logo.png)。 此範例使用資料夾命名。

\Assets\Images\contrast-standard\theme-dark
	\scale-100\logo.png
	\scale-200\logo.png
\Assets\Images\contrast-standard\theme-light
	\scale-100\logo.png
	\scale-200\logo.png
\Assets\Images\contrast-high
	\scale-100\logo.png
	\scale-200\logo.png

參照 XAML 標記和程式碼的影像或其他資產

影像資源的名稱或識別碼就是將所有限定詞都移除之後的路徑和檔案名稱。 如果您按照上一節的任何範例來命名資料夾和/或檔案,就會得到單一影像資源,其名稱 (等同於絕對路徑) 為 /Assets/Images/logo.png。 以下為在 XAML 標記使用該名稱的方式。

<Image x:Name="myXAMLImageElement" Source="ms-appx:///Assets/Images/logo.png"/>

請注意,由於您參照的檔案來自應用程式套件,您使用的是 ms-appx URI 配置。 請參閱 URI 配置。 而這是您在命令式程式碼參照相同影像資源的方式。

this.myXAMLImageElement.Source = new BitmapImage(new Uri("ms-appx:///Assets/Images/logo.png"));

您可以使用 ms-appx 來載入應用程式套件中的任何任意檔案。

var uri = new System.Uri("ms-appx:///Assets/anyAsset.ext");
var storagefile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);

ms-appx-web 配置會存取與 ms-appx 一樣的檔案,但位置是在網路區間。

<WebView x:Name="myXAMLWebViewElement" Source="ms-appx-web:///Pages/default.html"/>
this.myXAMLWebViewElement.Source = new Uri("ms-appx-web:///Pages/default.html");

在這些範例示範的任何情境中,請使用 URI 建構函式多載來推論出 UriKind。 請指定有效的絕對 URI,包括配置和授權,或按照上述範例,讓授權設為應用程式套件的預設值。

請注意,這些範例 URI 中的配置 (「ms-appx」或「ms-appx-web」) 後方銜接的是「://」,亦即銜接絕對路徑。 在絕對路徑中,開頭的「/」會使系統從套件跟目錄來解譯路徑。

注意

ms-resource (適用於字串資源) 和 ms-appx(-web) (適用於影像和其他資產) URI 配置會執行自動限定詞比對,找出目前的內容最合適的資源。 ms-appdata URI 配置 (用於載入應用程式資料) 完全不會執行這類自動比對,但您可以回應 ResourceContext.QualifierValues 的內容,從在 URI 使用完整實體檔案名稱的應用程式資料中,明確載入合適的資產。 如需應用程式資料的相關資訊,請參閱存放與擷取設定和其他應用程式資料。 Web URI 配置 (例如 httphttpsftp) 也不會執行自動比對。 如需參考這類案例的執行方式,請參閱在雲端主控與載入影像

如果影像檔案維持在專案架構中的原有位置,絕對路徑就是好選擇。 如果您想要轉移影像檔案,但又希望它維持在與參照的 XAML 標記檔案相對的相同位置,那與其使用絕對路徑,建議您改用與內含的標記檔案相對的路徑。 這麼做的話,您就不需要使用 URI 配置。 您在此案例中仍會得益於自動限定詞比對,但完全是因為您在 XAML 標記使用相對路徑。

<Image Source="Assets/Images/logo.png"/>

另請參閱支援語言、比例和高對比的圖磚和快顯

限定影像資源的 targetsize

您可以對相同影像資源的不同變數使用 scaletargetsize 限定詞,但不能將兩者同時使用在單一資源變數。 此外,您至少必須定義一個沒有 TargetSize 限定詞的變數。 該變數必須定義 scale 的值,或預設為 scale-100。 因此,/Assets/Square44x44Logo.png 資源的這兩個變數皆有效。

\Assets\Square44x44Logo.scale-200.png
\Assets\Square44x44Logo.targetsize-24.png

這兩個變數也有效。

\Assets\Square44x44Logo.png // defaults to scale-100
\Assets\Square44x44Logo.targetsize-24.png

但此變數無效。

\Assets\Square44x44Logo.scale-200_targetsize-24.png

從應用程式套件資訊清單參照影像檔案

如果您按照上一節兩個有效範例之一來命名資料夾和/或檔案,就會得到單一應用程式圖示影像資源,其名稱 (等同於相對路徑) 為 Assets\Square44x44Logo.png。 在應用程式套件資訊清單中,僅需依照名稱參照資源。 您不需要使用任何 URI 配置。

add resource, english

您僅需採取上述動作,作業系統會執行自動限定詞比對,找出目前的內容最合適的資源。 如需應用程式套件資訊清單的完整項目清單,以便您按照此方法來當地語系化或加以限定,請參閱可當地語系化的資訊清單項目

限定影像資源的 layoutdirection

請參閱鏡像影像

載入特定語言或其他內容的影像

如需有關將您的應用程式當地語系化的價值主張的詳細資訊,請參閱全球化和當地語系化

預設 ResourceContext (從ResourceContext.GetForCurrentView 取得) 包含每個限定詞名稱的限定詞值,表示預設執行階段內容 (也就是目前使用者和電腦的設定)。 系統會依據影像檔案名稱中的限定詞比對執行階段脈絡中的限定詞值。

但有些時候,您可能想在尋找要載入的比對影像時,讓應用程式覆寫系統設定,並明確指定要使用的語言、比例或其他限定詞值。 舉例來說,您可能想要確切控制高對比影像的載入時機和選擇。

您可以透過建構一個新的 ResourceContext (而不是使用預設的)、覆寫其值,然後在影像查詢中使用該內容物件來達成。

var resourceContext = new Windows.ApplicationModel.Resources.Core.ResourceContext(); // not using ResourceContext.GetForCurrentView 
resourceContext.QualifierValues["Contrast"] = "high";
var namedResource = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap[@"Files/Assets/Logo.png"];
var resourceCandidate = namedResource.Resolve(resourceContext);
var imageFileStream = resourceCandidate.GetValueAsStreamAsync().GetResults();
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
bitmapImage.SetSourceAsync(imageFileStream);
this.myXAMLImageElement.Source = bitmapImage;

若要在全域層級達到相同的效果,您可以覆寫預設 ResourceContext 中的限定詞值。 但建議您改為呼叫 ResourceContext.SetGlobalQualifierValue。 您可以使用對 SetGlobalQualifierValue 的呼叫來設定值一次,然後在每次用於查詢時,這些值都會在預設 ResourceContext 上生效。 預設情況下,ResourceManager 類別會使用預設的 ResourceContext

Windows.ApplicationModel.Resources.Core.ResourceContext.SetGlobalQualifierValue("Contrast", "high");
var namedResource = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap[@"Files/Assets/Logo.png"];
this.myXAMLImageElement.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(namedResource.Uri);

更新影像以回應限定詞值變更事件

您正在執行的應用程式可以回應影響預設資源內容中限定詞值的系統設定變更。 這些系統設定中的任何一個都會呼叫 ResourceContext.QualifierValues 上的 MapChanged 事件。

為了回應此事件,您可以藉助預設 ResourceContext (ResourceManager 預設使用該資源內容) 重新載入影像。

public MainPage()
{
    this.InitializeComponent();

    ...

    // Subscribe to the event that's raised when a qualifier value changes.
    var qualifierValues = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().QualifierValues;
    qualifierValues.MapChanged += new Windows.Foundation.Collections.MapChangedEventHandler<string, string>(QualifierValues_MapChanged);
}

private async void QualifierValues_MapChanged(IObservableMap<string, string> sender, IMapChangedEventArgs<string> @event)
{
    var dispatcher = this.myImageXAMLElement.Dispatcher;
    if (dispatcher.HasThreadAccess)
    {
        this.RefreshUIImages();
    }
    else
    {
        await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => this.RefreshUIImages());
    }
}

private void RefreshUIImages()
{
    var namedResource = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap[@"Files/Assets/Logo.png"];
    this.myImageXAMLElement.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(namedResource.Uri);
}

重要 API