Carga de imágenes y recursos adaptados a escala, tema, contraste alto y mucho más

La aplicación puede cargar archivos de recursos de imagen (u otros archivos de recursos) adaptados para el factor de escala de visualización, el tema, el contraste alto y otros contextos de tiempo de ejecución. Estas imágenes se pueden hacer referencia desde el código imperativo o desde el marcado XAML, por ejemplo, como la propiedad Source de una imagen. También pueden aparecer en el archivo de origen del manifiesto del paquete de la aplicación (el Package.appxmanifest archivo), por ejemplo, como el valor de Icono de aplicación en la pestaña Activos visuales del Diseñador de manifiestos de Visual Studio, o en los iconos y notificaciones del sistema. Mediante el uso de calificadores en los nombres de archivo de las imágenes y, opcionalmente, cargarlos dinámicamente con la ayuda de ResourceContext, puede hacer que se cargue el archivo de imagen más adecuado que mejor coincida con la configuración en tiempo de ejecución del usuario para la escala de visualización, el tema, el contraste alto, el idioma y otros contextos.

Un recurso de imagen se encuentra en un archivo de recursos de imagen. También puede considerar la imagen como un recurso y el archivo que lo contiene como un archivo de recursos; y puede encontrar estos tipos de archivos de recursos en la carpeta \Assets del proyecto. Para obtener información sobre cómo usar calificadores en los nombres de los archivos de recursos de imagen, consulte Personalización de los recursos para lenguaje, escala y otros calificadores.

Algunos calificadores comunes para las imágenes son la escala, el tema, el contraste y los destinos.

Calificar un recurso de imagen para la escala, el tema y el contraste

El valor predeterminado del scale calificador es scale-100. Por lo tanto, estas dos variantes son equivalentes (proporcionan una imagen a escala 100 o factor de escala 1).

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

Puede usar calificadores en nombres de carpeta en lugar de nombres de archivo. Sería una mejor estrategia si tiene varios archivos de recursos por calificador. Para fines de ilustración, estas dos variantes son equivalentes a las dos anteriores.

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

A continuación, se muestra un ejemplo de cómo puede proporcionar variantes de un recurso de imagen ( denominado /Assets/Images/logo.png) para diferentes configuraciones de escala de presentación, tema y contraste alto. En este ejemplo se usa la nomenclatura de carpetas.

\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

Hacer referencia a una imagen u otro recurso desde el marcado y el código XAML

El nombre o el identificador de un recurso de imagen es su ruta de acceso y nombre de archivo con cualquiera y todos los calificadores quitados. Si asigna un nombre a carpetas o archivos como en cualquiera de los ejemplos de la sección anterior, tiene un único recurso de imagen y su nombre (como ruta de acceso absoluta) es /Assets/Images/logo.png. Aquí se muestra cómo se usa ese nombre en el marcado XAML.

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

Ten en cuenta que usas el ms-appx esquema de URI porque estás haciendo referencia a un archivo que procede del paquete de la aplicación. Consulte esquemas de URI. Y aquí se muestra cómo se hace referencia al mismo recurso de imagen en código imperativo.

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

Puedes usar ms-appx para cargar cualquier archivo arbitrario desde el paquete de la aplicación.

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

El ms-appx-web esquema tiene acceso a los mismos archivos que ms-appx, pero en el compartimiento web.

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

Para cualquiera de los escenarios que se muestran en estos ejemplos, use la sobrecarga del constructor URI que deduce el UriKind. Especifique un URI absoluto válido, incluido el esquema y la autoridad, o simplemente deje que la autoridad se ponga de forma predeterminada en el paquete de la aplicación como en el ejemplo anterior.

Observe cómo, en estos URI de ejemplo, el esquema ("ms-appx" o "ms-appx-web") va seguido de "://", seguido de una ruta de acceso absoluta. En una ruta de acceso absoluta, la "/" inicial hace que la ruta de acceso se interprete desde la raíz del paquete.

Nota:

Los ms-resource esquemas de URI (para recursos de cadena) y ms-appx(-web) (para imágenes y otros recursos) realizan la coincidencia automática de calificadores para encontrar el recurso más adecuado para el contexto actual. El ms-appdata esquema de URI (que se usa para cargar datos de la aplicación) no realiza ninguna coincidencia automática, pero puede responder al contenido de ResourceContext.QualifierValues y cargar explícitamente los recursos adecuados de los datos de la aplicación mediante su nombre de archivo físico completo en el URI. Para obtener información sobre los datos de la aplicación, consulta Almacenar y recuperar la configuración y otros datos de la aplicación. Los esquemas de URI web (por ejemplo, http, httpsy ftp) no realizan coincidencias automáticas, tampoco. Para obtener información sobre qué hacer en ese caso, consulte Hospedaje y carga de imágenes en la nube.

Las rutas de acceso absolutas son una buena opción si los archivos de imagen permanecen donde se encuentran en la estructura del proyecto. Si quieres poder mover un archivo de imagen, pero tienes cuidado de que permanezca en la misma ubicación con respecto a su archivo de marcado XAML de referencia, en lugar de una ruta de acceso absoluta que quieras usar una ruta de acceso relativa al archivo de marcado contenedor. Si lo hace, no necesita usar un esquema de URI. Todavía te beneficiarás de la coincidencia automática de calificadores en este caso, pero solo porque estás usando la ruta de acceso relativa en el marcado XAML.

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

Consulte también Compatibilidad con iconos y notificaciones del sistema para el idioma, la escala y el contraste alto.

Calificar un recurso de imagen para destinos

Puede usar los scale calificadores y targetsize en variantes diferentes del mismo recurso de imagen, pero no puede usarlos en una sola variante de un recurso. Además, debe definir al menos una variante sin calificador TargetSize . Esa variante debe definir un valor para scaleo dejar que tenga como valor predeterminado scale-100. Por lo tanto, estas dos variantes del /Assets/Square44x44Logo.png recurso son válidas.

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

Y estas dos variantes son válidas.

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

Pero esta variante no es válida.

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

Consulte un archivo de imagen desde el manifiesto del paquete de la aplicación.

Si asigna un nombre a carpetas o archivos como en cualquiera de los dos ejemplos válidos de la sección anterior, tiene un único recurso de imagen de icono de aplicación y su nombre (como ruta de acceso relativa) es Assets\Square44x44Logo.png. En el manifiesto del paquete de la aplicación, simplemente haga referencia al recurso por su nombre. No es necesario usar ningún esquema de URI.

add resource, english

Eso es todo lo que necesita hacer y el sistema operativo realizará la coincidencia automática de calificadores para encontrar el recurso más adecuado para el contexto actual. Para obtener una lista de todos los elementos del manifiesto del paquete de aplicación que se pueden localizar o calificar de esta manera, consulte Elementos de manifiesto localizables.

Calificar un recurso de imagen para layoutdirection

Consulte Creación de reflejo de imágenes.

Cargar una imagen para un idioma específico u otro contexto

Para más información sobre la propuesta de valor de localizar la aplicación, consulta Globalización y localización.

ResourceContext predeterminado (obtenido de ResourceContext.GetForCurrentView) contiene un valor de calificador para cada nombre de calificador, que representa el contexto en tiempo de ejecución predeterminado (es decir, la configuración del usuario y la máquina actuales). Los archivos de imagen coinciden(basados en los calificadores de sus nombres) con los valores de calificador de ese contexto en tiempo de ejecución.

Pero puede haber ocasiones en las que quieras que la aplicación invalide la configuración del sistema y sea explícita sobre el idioma, la escala u otro valor de calificador que se usará al buscar una imagen coincidente para cargarla. Por ejemplo, es posible que quiera controlar exactamente cuándo y qué imágenes de contraste alto se cargan.

Para ello, puede crear un nuevo ResourceContext (en lugar de usar el predeterminado), invalidar sus valores y, a continuación, usar ese objeto de contexto en las búsquedas de imágenes.

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;

Para lograr el mismo efecto en un nivel global, puedeinvalidar los valores de calificador en resourceContext predeterminado. Pero en su lugar le recomendamos que llame a ResourceContext.SetGlobalQualifierValue. Los valores se establecen una vez con una llamada a SetGlobalQualifierValue y, a continuación, esos valores están en vigor en resourceContext predeterminado cada vez que se usa para búsquedas. De forma predeterminada, la clase ResourceManager usa resourceContext predeterminado.

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

Actualización de imágenes en respuesta a eventos de cambio de valor calificador

La aplicación en ejecución puede responder a los cambios en la configuración del sistema que afectan a los valores de calificador en el contexto de recursos predeterminado. Cualquiera de estas opciones de configuración del sistema invoca el evento MapChanged en ResourceContext.QualifierValues.

En respuesta a este evento, puede volver a cargar las imágenes con la ayuda de ResourceContext predeterminado, que ResourceManager usa de forma predeterminada.

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 importantes