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

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

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"/>

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

Определение ресурса изображения для целевых объектов

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

add resource, english

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

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

См . изображения зеркального отображения.

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

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

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);

Обновление изображений в ответ на события изменения значения квалификатора

Работающее приложение может реагировать на изменения в системных параметрах, влияющих на значения квалификатора в контексте ресурса по умолчанию. Любой из этих системных параметров вызывает событие MapChanged в ResourceContext.QualifierValues.

В ответ на это событие можно перезагрузить изображения с помощью 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