加载在比例、主题、高对比度和其他方面进行了定制的图像和资产

应用可以加载为 显示比例系数、主题、高对比度和其他运行时上下文定制的图像资源文件(或其他资产文件)。 可以从命令性代码或 XAML 标记中引用这些图像,例如图像的 Source 属性。 它们还可以显示在应用包清单源文件(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 访问的文件与 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");

对于这些示例中所示的任何方案,请使用推断 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 对语言、缩放和高对比度的支持。

限定目标大小的图像资源

可以在 scale 同一图像资源的不同变体上使用限定 targetsize 符,但不能在资源的单个变体上使用它们。 此外,需要定义至少一个没有限定符的 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 方案。

添加资源,英语

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

限定图像资源进行布局目录

请参阅 镜像映像

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

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

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

但是,有时你可能希望应用重写系统设置,并在查找要加载的匹配图像时显式显示语言、缩放或其他限定符值。 例如,你可能想要准确控制加载高对比度图像的时间和时间。

为此,可以构造新的 ResourceContext(而不是使用默认资源),重写其值,然后在 ResourceMap 图像查找中使用该上下文对象和 GetValueTryGetValue

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

另请参阅