Carregue imagens e ativos sob medida para escala, tema, alto contraste e muito mais

Seu aplicativo pode carregar arquivos de recursos de imagem (ou outros arquivos de ativos) adaptados para fator de escala de exibição, tema, alto contraste e outros contextos de tempo de execução. Essas imagens podem ser referenciadas a partir de código imperativo ou de marcação XAML, por exemplo, como a propriedade Source de uma Image. Eles também podem aparecer no arquivo de origem do manifesto do pacote do aplicativo (o arquivo) — por exemplo, como o Package.appxmanifest valor do Ícone do Aplicativo na guia Ativos Visuais do Designer de Manifesto do Visual Studio — ou em seus blocos e notificações do sistema. Usando qualificadores nos nomes de arquivo de suas imagens e, opcionalmente, carregando-os dinamicamente com a ajuda de um ResourceContext, você pode fazer com que o arquivo de imagem mais apropriado seja carregado que melhor corresponda às configurações de tempo de execução do usuário para escala de exibição, tema, alto contraste, idioma e outros contextos.

Um recurso de imagem está contido em um arquivo de recurso de imagem. Você também pode pensar na imagem como um ativo e no arquivo que a contém como um arquivo de ativo; e você pode encontrar esses tipos de arquivos de recursos na pasta \Assets do seu projeto. Para obter informações básicas sobre como usar qualificadores nos nomes de seus arquivos de recursos de imagem, consulte Personalizar seus recursos para idioma, escala e outros qualificadores.

Alguns qualificadores comuns para imagens são escala, tema, contraste e targetsize.

Qualificar um recurso de imagem para escala, tema e contraste

O valor padrão para o scale qualificador é scale-100. Assim, essas duas variantes são equivalentes (ambas fornecem uma imagem na escala 100, ou fator de escala 1).

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

Você pode usar qualificadores em nomes de pasta em vez de nomes de arquivo. Essa seria uma estratégia melhor se você tiver vários arquivos de ativos por qualificador. Para fins de ilustração, essas duas variantes são equivalentes às duas acima.

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

A seguir está um exemplo de como você pode fornecer variantes de um recurso de imagem — nomeado /Assets/Images/logo.png— para diferentes configurações de escala de exibição, tema e alto contraste. Este exemplo usa a nomeação de pastas.

\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

Fazer referência a uma imagem ou outro ativo a partir de marcação e código XAML

O nome — ou identificador — de um recurso de imagem é seu caminho e nome de arquivo com todo e qualquer qualificador removido. Se você nomear pastas e/ou arquivos como em qualquer um dos exemplos na seção anterior, terá um único recurso de imagem e seu nome (como um caminho absoluto) será /Assets/Images/logo.png. Veja como usar esse nome na marcação XAML.

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

Observe que você usa o ms-appx esquema de URI porque está se referindo a um arquivo que vem do pacote do seu aplicativo. Consulte Esquemas de URI. E aqui está como você se refere ao mesmo recurso de imagem no código imperativo.

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

Você pode usar ms-appx para carregar qualquer arquivo arbitrário do pacote do aplicativo.

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

O ms-appx-web esquema acessa os mesmos arquivos que ms-appxo , mas no compartimento da Web.

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

Para qualquer um dos cenários mostrados nesses exemplos, use a sobrecarga do construtor Uri que infere o UriKind. Especifique um URI absoluto válido, incluindo o esquema e a autoridade, ou apenas deixe a autoridade usar como padrão o pacote do aplicativo, como no exemplo acima.

Observe como nesses URIs de exemplo o esquema ("ms-appx" ou "") é seguido por "ms-appx-web://", que é seguido por um caminho absoluto. Em um caminho absoluto, o ""/ à esquerda faz com que o caminho seja interpretado a partir da raiz do pacote.

Observação

Os ms-resource esquemas de URI (para recursos de cadeia de caracteres) e (para imagens e ms-appx(-web) outros ativos) executam a correspondência automática de qualificadores para localizar o recurso mais apropriado para o contexto atual. O ms-appdata esquema de URI (que é usado para carregar dados do aplicativo) não executa essa correspondência automática, mas você pode responder ao conteúdo de ResourceContext.QualifierValues e carregar explicitamente os ativos apropriados dos dados do aplicativo usando seu nome de arquivo físico completo no URI. Para obter informações sobre dados de aplicativos, consulte Armazenar e recuperar configurações e outros dados de aplicativos. Os esquemas de URI da Web (por exemplo, , httphttpse ftp) também não executam correspondência automática. Para obter informações sobre o que fazer nesse caso, consulte Hospedando e carregando imagens na nuvem.

Caminhos absolutos são uma boa opção se seus arquivos de imagem permanecerem onde estão na estrutura do projeto. Se você quiser mover um arquivo de imagem, mas tiver cuidado para que ele permaneça no mesmo local em relação ao arquivo de marcação XAML de referência, em vez de um caminho absoluto, convém usar um caminho relativo ao arquivo de marcação que contém. Se você fizer isso, não precisará usar um esquema de URI. Nesse caso, você ainda se beneficiará da correspondência automática de qualificadores, mas apenas porque estiver usando o caminho relativo na marcação XAML.

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

Consulte também Suporte a blocos e notificações do sistema para idioma, escala e alto contraste.

Qualificar um recurso de imagem para targetsize

Você pode usar os scale qualificadores e em diferentes variantes do mesmo recurso de imagem, mas não pode usá-los em uma única variante targetsize de um recurso. Além disso, você precisa definir pelo menos uma variante sem um TargetSize qualificador. Essa variante deve definir um valor para , ou deixá-la padrão para scalescale-100. Então, essas duas variantes do /Assets/Square44x44Logo.png recurso são válidas.

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

E essas duas variantes são válidas.

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

Mas essa variante não é válida.

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

Consulte um arquivo de imagem do manifesto do pacote do aplicativo

Se você nomear pastas e/ou arquivos como em um dos dois exemplos válidos na seção anterior, terá um único recurso de imagem de ícone de aplicativo e seu nome (como um caminho relativo) será Assets\Square44x44Logo.png. No manifesto do pacote do aplicativo, basta fazer referência ao recurso pelo nome. Não há necessidade de usar nenhum esquema de URI.

add resource, english

Isso é tudo o que você precisa fazer, e o sistema operacional executará a correspondência automática de qualificador para encontrar o recurso mais apropriado para o contexto atual. Para obter uma lista de todos os itens no manifesto do pacote do aplicativo que você pode localizar ou qualificar dessa maneira, consulte Itens de manifesto localizáveis.

Qualificar um recurso de imagem para layoutdirection

Consulte Espelhamento de imagens.

Carregar uma imagem para um idioma específico ou outro contexto

Para obter mais informações sobre a proposta de valor de localização do aplicativo, consulte Globalização e localização.

O ResourceContext padrão (obtido de ResourceContext.GetForCurrentView) contém um valor de qualificador para cada nome de qualificador, representando o contexto de tempo de execução padrão (em outras palavras, as configurações para o usuário e a máquina atuais). Os arquivos de imagem são correspondidos — com base nos qualificadores em seus nomes — com os valores do qualificador nesse contexto de tempo de execução.

Mas pode haver momentos em que você deseja que seu aplicativo substitua as configurações do sistema e seja explícito sobre o idioma, a escala ou outro valor de qualificador a ser usado ao procurar uma imagem correspondente para carregar. Por exemplo, talvez você queira controlar exatamente quando e quais imagens de alto contraste são carregadas.

Você pode fazer isso construindo um novo ResourceContext (em vez de usar o padrão), substituindo seus valores e, em seguida, usando esse objeto de contexto em suas pesquisas de imagem.

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 obter o mesmo efeito em um nível global, você pode substituir os valores de qualificador no ResourceContext padrão. Mas, em vez disso, recomendamos que você chame ResourceContext.SetGlobalQualifierValue. Você define valores uma vez com uma chamada para SetGlobalQualifierValue e, em seguida, esses valores estão em vigor no ResourceContext padrão cada vez que você usá-lo para pesquisas. Por padrão, a classe ResourceManager usa o ResourceContext padrão.

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

Atualizando imagens em resposta a eventos de alteração de valor do qualificador

Seu aplicativo em execução pode responder a alterações nas configurações do sistema que afetam os valores do qualificador no contexto de recurso padrão. Qualquer uma dessas configurações do sistema invoca o evento MapChanged em ResourceContext.QualifierValues.

Em resposta a esse evento, você pode recarregar suas imagens com a ajuda do ResourceContext padrão, que o ResourceManager usa por padrão.

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

APIs importantes