加载为比例、主题、高对比度和其他定制的图像和资产

你的应用可以加载为显示比例系数、主题、高对比度和其他运行时上下文定制的图像资源文件(或其他资产文件)。 这些图像可以从强制性代码或 XAML 标记引用,如作为 ImageSource 属性。 它们还可以显示在应用包清单源文件(Package.appxmanifest 文件)中 - 例如,作为 Visual Studio 清单设计器的“视觉对象资产”选项卡上应用图标的值 - 或显示在磁贴和 toast 上。 通过在图像的文件名称中使用限定符,并选择性地在 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 方案,因为你引用的是来自应用包的文件。 请参阅 UWP 文档中的 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 访问相同的文件,但是前者在 Web 隔离舱中访问。

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

对于这些示例中所示的任何方案,请使用推断 UriKindUri 构造函数重载。 指定一个包括方案和颁发机构的有效的绝对 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"/>

另请参阅磁贴和 toast 的语言、比例和高对比度支持

限定目标大小的图像资源

你可以对相同图像资源的不同变体使用 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 方案。

添加资源,英语

这就是你需要执行的所有操作,操作系统会执行自动限定符匹配,以查找最适合当前上下文的资源。 有关你可以本地化或以这种方式进行限定的应用包清单中的所有项目的列表,请参阅可本地化清单项目

限定布局方向的图像资源

请参阅镜像图像

为特定语言或其他上下文加载图像

有关对应用进行本地化的价值主张的详细信息,请参阅全球化和本地化

默认 ResourceContext 包含每个限定符名称的限定符值,表示默认运行时上下文 (换言之,当前用户和计算机) 的设置。 根据该运行时上下文中的限定符值匹配图像文件 - 基于其名称中的限定符。

但在有些时候,你可能想要你的应用覆盖系统设置,并明确当查找要加载的匹配图像时要使用的语言、比例或其他限定符值。 例如,你可能想要精确控制何时加载哪个高对比度图像。

为此,可以构造一个新的 ResourceContext (,而不是使用默认的 resourceContext) ,重写其值,然后使用 GetValueTryGetValueResourceMap 图像查找中使用该上下文对象。

var resourceManager = new Microsoft.Windows.ApplicationModel.Resources.ResourceManager();
var resourceContext = resourceManager.CreateResourceContext();
resourceContext.QualifierValues["Contrast"] = "high";
var resourceMap = resourceManager.MainResourceMap;
var namedResource = resourceMap.TryGetValue(@"Files/Assets/Logo.png", resourceContext);
var imageFileBytes = namedResource.ValueAsBytes;

using (var ms = new InMemoryRandomAccessStream())
{
    using (var writer = new DataWriter(ms.GetOutputStreamAt(0)))
    {
        writer.WriteBytes(imageFileBytes);
        writer.StoreAsync().GetResults();
    }
    var image = new BitmapImage();
    image.SetSource(ms);
    this.myXAMLImageElement.Source = image;
}

默认情况下,ResourceManager 类使用默认 ResourceContext

重要的 API

另请参阅