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

Seu aplicativo pode carregar arquivos de recurso de imagem (ou outros arquivos de ativo) personalizados 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 imagem. Eles também podem aparecer no arquivo de origem do manifesto do pacote do aplicativo (o Package.appxmanifest arquivo), por exemplo, como o 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 seja carregado o arquivo de imagem mais apropriado 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 sobre como usar qualificadores nos nomes de seus arquivos de recurso de imagem, consulte Personalizar seus recursos para idioma, escala e outros qualificadores.

Alguns qualificadores comuns para imagens são escala, tema, contraste e tamanho de destino.

Qualificar um recurso de imagem para escala, tema e contraste

O valor padrão para o scale qualificador é scale-100. Portanto, 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 pastas em vez de nomes de arquivos. Essa seria uma estratégia melhor se você tivesse 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, um exemplo de como você pode fornecer variantes de um recurso de imagem, chamado /Assets/Images/logo.png—para diferentes configurações de escala de exibição, tema e alto contraste. Este exemplo usa nomenclatura de pasta.

\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 da marcação e do 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 da seção anterior, terá um único recurso de imagem e seu nome (como um caminho absoluto) será /Assets/Images/logo.png. Veja como você usa 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 o pacote do aplicativo como padrão, como no exemplo acima.

Observe como nesses URIs de exemplo o esquema ("ms-appx" ou "ms-appx-web") é seguido por "://", que é seguido por um caminho absoluto. Em um caminho absoluto, o "/" inicial 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 ms-appx(-web) (para imagens e outros ativos) executam a correspondência automática de qualificador para encontrar o recurso mais apropriado para o contexto atual. O ms-appdata esquema de URI (que é usado para carregar dados do aplicativo) não executa nenhuma 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 o nome completo do arquivo físico 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, http, https, e ftp) também não executam a correspondência automática. Para obter informações sobre o que fazer nesse caso, consulte Hospedando e carregando imagens na nuvem.

Os caminhos absolutos são uma boa opção se os 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, talvez você queira usar um caminho relativo ao arquivo de marcação que o contém. Se você fizer isso, não precisará usar um esquema de URI. Você ainda se beneficiará da correspondência automática de qualificador nesse caso, mas apenas porque está 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 targetsize em diferentes variantes do mesmo recurso de imagem; mas não pode usá-los em uma única variante de um recurso. Além disso, você precisa definir pelo menos uma variante sem um TargetSize qualificador. Essa variante deve definir um valor para scale, ou deixá-la padronizada para scale-100. Portanto, 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 esta 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 qualquer 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 consultar o recurso pelo nome. Não há necessidade de usar nenhum esquema de URI.

Adicionar recurso, inglês

Isso é tudo o que você precisa fazer, e o sistema operacional executará a correspondência automática de qualificadores 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 ao criar um ResourceContext.GetForCurrentView) contém um valor de qualificador para cada nome de qualificador, representando o contexto de runtime padrão (em outras palavras, as configurações do usuário atual e do computador). Os arquivos de imagem são comparados, 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 do qualificador no ResourceContext padrão. Mas, em vez disso, recomendamos que chame ResourceContext.SetGlobalQualifierValue. Você define valores uma vez com uma chamada para SetGlobalQualifierValue e então esses valores entram em vigor no ResourceContext padrão sempre que você o usa 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