Поделиться через


Загрузка изображений и ресурсов, адаптированных по масштабу, теме, высокой контрастности и другим аспектам

Приложение может загружать файлы ресурсов изображения (или другие файлы ресурсов), предназначенные для коэффициента масштабирования, темы, высокой контрастности и других контекстов среды выполнения. На эти изображения можно ссылаться из императивного кода или разметки XAML, например как свойство Source изображения. Они также могут отображаться в исходном файле манифеста пакета приложения ( 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 в документации для UWP. Вот как вы ссылаетесь на тот же ресурс изображения в императивном коде.

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 Схемы URI (для строковых ресурсов и ms-appx(-web) для изображений и других ресурсов) выполняют автоматическое сопоставление квалификаторов, чтобы найти ресурс, наиболее подходящий для текущего контекста. ms-appdata Схема URI (которая используется для загрузки данных приложения) не выполняет такого автоматического сопоставления, но вы можете реагировать на содержимое ResourceContext.QualifierValues и явно загружать соответствующие ресурсы из данных приложения с помощью полного физического имени файла в URI. Чтобы узнать о данных приложения, см. Хранение и получение настроек и других данных приложения. Схемы веб-URI (например, http, httpsи ftp) не выполняют автоматическое сопоставление. Сведения о том, что делать в этом случае, см. в разделе "Размещение и загрузка образов в облаке".

Абсолютные пути являются хорошим выбором, если файлы изображений остаются там, где они находятся в структуре проекта. Если вы хотите переместить файл изображения, но хотите, чтобы он остался в том же месте относительно файла разметки XAML, ссылающегося на него, вместо абсолютного пути лучше использовать путь, относительный к содержащему файлу разметки. Если это сделать, вам не нужно использовать схему URI. В этом случае вы по-прежнему будете извлекать выгоду из автоматического сопоставления квалификаторов, но только потому, что используете относительный путь в разметке XAML.

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

Также см поддержку плиток и всплывающих элементов для языка, масштаба и высокой контрастности.

Ссылка на изображение или другой ресурс из библиотеки классов

Образы и другие ресурсы можно загрузить из проекта библиотеки классов (WinUI в Desktop), ссылаясь на ресурс в URI, использующем схему ms-appx. URI должен содержать имя проекта библиотеки классов и путь к ресурсу в проекте библиотеки классов. Например, если у вас есть проект библиотеки классов с именем MyClassLibrary , содержащий изображение с именем logo.png в папке с именем Assets, можно ссылаться на изображение в проекте приложения следующим образом:

<Image Source="ms-appx:///MyClassLibrary/Assets/logo.png"/>

Этот же формат URI будет использоваться для ссылки на ресурсы в библиотеке классов из разметки XAML или из кода. Например, можно использовать следующий код, чтобы загрузить образ из библиотеки классов и поместить его в объект StorageFile :

private async Task<DateTimeOffset> GetLogoCreatedDateAsync()
{
    Uri uri = new($"ms-appx:///MyClassLibrary/Assets/logo.png");
    Windows.Storage.StorageFile file =
        await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);

    return file.DateCreated;
}

Обратите внимание, что можно ссылаться на изображения из библиотеки классов как из проекта приложения, так и самого проекта библиотеки классов.

Определение ресурса изображения для параметра targetsize.

Вы можете использовать квалификаторы 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.

добавить ресурс, английский

Это все, что нужно сделать, и ОС автоматически выполнит сравнение квалификаторов, чтобы найти ресурс, наиболее подходящий для текущего контекста. Список всех элементов в манифесте пакета приложения, который можно локализовать или иначе квалифицировать таким образом, см. в разделе "Локализуемые элементы манифеста".

Квалификация ресурса изображения для направления компоновки

См. отражение изображений.

Загрузка изображения для определенного языка или другого контекста

Дополнительные сведения о преимуществах локализации приложений см. в разделе Глобализация и локализация.

ResourceContext по умолчанию содержит значение квалификатора для каждого имени квалификатора, представляющего контекст среды выполнения по умолчанию (другими словами, параметры текущего пользователя и компьютера). Файлы изображений сопоставляются на основе квалификаторов в их именах с значениями квалификатора в этом контексте среды выполнения.

Может быть необходимо, чтобы ваше приложение переопределяло системные настройки и явно задавало язык, масштаб или другое значение квалификатора для поиска и загрузки подходящего изображения. Например, вам может потребоваться управлять именно тем, когда и какие изображения высокой контрастности загружаются.

Это можно сделать, создав новый ResourceContext (вместо использования по умолчанию), переопределив его значения, а затем используя этот объект контекста для поиска изображений в ResourceMap с помощью GetValue или TryGetValue.

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

При работе с ресурсами изображений используются следующие API: