Immagini in Xamarin.Forms

Le immagini possono essere condivise tra piattaforme con Xamarin.Forms, possono essere caricate in modo specifico per ogni piattaforma oppure possono essere scaricate per la visualizzazione.

Le immagini sono una parte fondamentale dello spostamento, dell'usabilità e della personalizzazione delle applicazioni. Xamarin.Forms le applicazioni devono essere in grado di condividere immagini in tutte le piattaforme, ma possono anche visualizzare immagini diverse in ogni piattaforma.

Sono necessarie anche immagini specifiche della piattaforma per le icone e le schermate iniziali; questi devono essere configurati per ogni piattaforma.

Visualizzare immagini

Xamarin.Forms usa la Image visualizzazione per visualizzare le immagini in una pagina. Ha diverse proprietà importanti:

  • SourceImageSource- Istanza di File, Uri o Risorsa, che imposta l'immagine da visualizzare.
  • Aspect - Come ridimensionare l'immagine all'interno dei limiti in cui viene visualizzata (per estendere, ritagliare o casella di lettere).

ImageSource Le istanze possono essere ottenute usando metodi statici per ogni tipo di origine immagine:

  • FromFile - Richiede un nome file o un percorso file che può essere risolto in ogni piattaforma.
  • FromUri - Richiede un oggetto Uri, ad esempio. new Uri("http://server.com/image.jpg") .
  • FromResource - Richiede un identificatore di risorsa per un file di immagine incorporato nell'applicazione o nel progetto di libreria .NET Standard, con un'azione di compilazione:EmbeddedResource.
  • FromStream - Richiede un flusso che fornisce i dati dell'immagine.

La Aspect proprietà determina il modo in cui l'immagine verrà ridimensionata per adattarsi all'area di visualizzazione:

  • Fill - Estende completamente l'immagine e riempie esattamente l'area di visualizzazione. Ciò può comportare la distorsione dell'immagine.
  • AspectFill - Ritaglia l'immagine in modo che riempia l'area di visualizzazione mantenendo l'aspetto (ad esempio, nessuna distorsione).
  • AspectFit - Letterboxes l'immagine (se necessario) in modo che l'intera immagine si adatti all'area di visualizzazione, con spazio vuoto aggiunto ai lati superiore/inferiore o inferiore a seconda che l'immagine sia larga o alta.

Le immagini possono essere caricate da un file locale, da una risorsa incorporata, scaricata o caricata da un flusso. Inoltre, le icone dei tipi di carattere possono essere visualizzate dalla Image visualizzazione specificando i dati dell'icona del carattere in un FontImageSource oggetto . Per altre informazioni, vedere Visualizzare le icone dei tipi di carattere nella guida Tipi di carattere .

Immagini locali

I file di immagine possono essere aggiunti a ogni progetto di applicazione e a cui si fa riferimento dal Xamarin.Forms codice condiviso. Questo metodo di distribuzione delle immagini è necessario quando le immagini sono specifiche della piattaforma, ad esempio quando si usano risoluzioni diverse su piattaforme diverse o progettazioni leggermente differenti.

Per usare una singola immagine in tutte le app, lo stesso nome file deve essere usato in ogni piattaforma e deve essere un nome di risorsa Android valido (ad esempio, solo lettere minuscole, numeri, caratteri di sottolineatura e punto consentiti).

  • iOS : il modo preferito per gestire e supportare le immagini da iOS 9 consiste nell'usare i set di immagini del catalogo di asset, che devono contenere tutte le versioni di un'immagine necessarie per supportare vari dispositivi e fattori di scala per un'applicazione. Per altre informazioni, vedere Aggiunta di immagini a un set di immagini del catalogo di asset.
  • Android : posizionare le immagini nella directory Resources/drawable con Azione di compilazione: AndroidResource. È anche possibile specificare versioni con valori DPI alti e bassi di un'immagine (in sottodirectory risorse denominate in modo appropriato, ad esempio drawable-ldpi, drawable-hdpi e drawable-xhdpi).
  • piattaforma UWP (Universal Windows Platform) (UWP): per impostazione predefinita, le immagini devono essere inserite nella directory radice dell'applicazione con Azione di compilazione: Contenuto. In alternativa, le immagini possono essere inserite in una directory diversa, che viene quindi specificata con una piattaforma specifica. Per altre informazioni, vedere Directory di immagini predefinite in Windows.

Importante

Prima di iOS 9, le immagini venivano in genere inserite nella cartella Risorse con Azione di compilazione: BundleResource. Tuttavia, questo metodo di utilizzo delle immagini in un'app iOS è stato deprecato da Apple. Per altre informazioni, vedere Image Sizes and Filenames .For more information, see Image Sizes and Filenames.

L'adesione a queste regole per la denominazione e il posizionamento dei file consente al codice XAML seguente di caricare e visualizzare l'immagine in tutte le piattaforme:

<Image Source="waterfront.jpg" />

Il codice C# equivalente è il seguente:

var image = new Image { Source = "waterfront.jpg" };

Gli screenshot seguenti mostrano il risultato della visualizzazione di un'immagine locale in ogni piattaforma:

Applicazione di esempio che visualizza un'immagine locale

Per una maggiore flessibilità, è possibile usare la Device.RuntimePlatform proprietà per selezionare un file o un percorso di immagine diverso per alcune o tutte le piattaforme, come illustrato in questo esempio di codice:

image.Source = Device.RuntimePlatform == Device.Android
                ? ImageSource.FromFile("waterfront.jpg")
                : ImageSource.FromFile("Images/waterfront.jpg");

Importante

Per usare lo stesso nome di immagine in tutte le piattaforme, il nome deve essere valido in tutte le piattaforme. I drawable Android hanno restrizioni di denominazione, ovvero sono consentite solo lettere minuscole, numeri, caratteri di sottolineatura e periodo, e per la compatibilità multipiattaforma è necessario seguire anche queste altre piattaforme. Il nome file di esempio waterfront.png segue le regole, ma esempi di nomi file non validi includono "water front.png", "WaterFront.png", "water-front.png" e "wåterfront.png".

Risoluzioni native (retina e DPI elevato)

iOS, Android e UWP includono il supporto per risoluzioni delle immagini diverse, in cui il sistema operativo sceglie l'immagine appropriata in fase di esecuzione in base alle funzionalità del dispositivo. Xamarin.Forms usa le API delle piattaforme native per il caricamento di immagini locali, quindi supporta automaticamente risoluzioni alternative se i file sono denominati correttamente e che si trovano nel progetto.

Il modo preferito per gestire le immagini da iOS 9 consiste nel trascinare le immagini per ogni risoluzione necessaria per il set di immagini del catalogo di asset appropriato. Per altre informazioni, vedere Aggiunta di immagini a un set di immagini del catalogo di asset.

Prima di iOS 9, le versioni retina dell'immagine potrebbero essere inserite nella cartella Risorse , due e tre volte la risoluzione con un @2x o @3x suffissi sul nome file prima dell'estensione del file (ad esempio myimage@2x.png). Tuttavia, questo metodo di utilizzo delle immagini in un'app iOS è stato deprecato da Apple. Per altre informazioni, vedere Image Sizes and Filenames .For more information, see Image Sizes and Filenames.

Le immagini di risoluzione alternativa Android devono essere inserite in directory denominate appositamente nel progetto Android, come illustrato nello screenshot seguente:

Posizione dell'immagine a risoluzione multipla Android

I nomi dei file di immagine UWP possono essere suffissi con .scale-xxx prima dell'estensione del file, dove xxx è la percentuale di ridimensionamento applicata all'asset, ad esempio myimage.scale-200.png. È quindi possibile fare riferimento alle immagini nel codice o nel codice XAML senza il modificatore di scala, ad esempio solo myimage.png. La piattaforma selezionerà la scala degli asset più vicina in base alla dpi corrente dello schermo.

Controlli aggiuntivi che visualizzano immagini

Alcuni controlli hanno proprietà che visualizzano un'immagine, ad esempio:

  • Button dispone di una ImageSource proprietà che può essere impostata su un'immagine bitmap da visualizzare in Button. Per altre informazioni, vedere Uso di bitmap con pulsanti.

  • ImageButton dispone di una Source proprietà che può essere impostata sull'immagine da visualizzare in ImageButton. Per altre informazioni, vedere Impostazione dell'origine dell'immagine.

  • ToolbarItem ha una IconImageSource proprietà che può essere impostata su un'immagine caricata da un file, una risorsa incorporata, un URI o un flusso.

  • ImageCell ha una ImageSource proprietà che può essere impostata su un'immagine recuperata da un file, una risorsa incorporata, un URI o un flusso.

  • Page. Qualsiasi tipo di pagina che deriva da Page ha IconImageSource proprietà e BackgroundImageSource , a cui è possibile assegnare un file, una risorsa incorporata, un URI o un flusso. In determinate circostanze, ad esempio quando un oggetto NavigationPage visualizza un ContentPageoggetto , l'icona verrà visualizzata se supportata dalla piattaforma.

    Importante

    In iOS la Page.IconImageSource proprietà non può essere popolata da un'immagine in un set di immagini del catalogo di asset. Caricare invece immagini icona per la Page.IconImageSource proprietà da un file, una risorsa incorporata, un URI o un flusso.

Immagini incorporate

Le immagini incorporate vengono fornite anche con un'applicazione (ad esempio immagini locali), ma invece di avere una copia dell'immagine nella struttura di file di ogni applicazione il file di immagine viene incorporato nell'assembly come risorsa. Questo metodo di distribuzione delle immagini è consigliato quando vengono usate immagini identiche in ogni piattaforma ed è particolarmente adatto per la creazione di componenti, in quanto l'immagine viene in bundle con il codice.

Per incorporare un'immagine in un progetto, fare clic con il pulsante destro del mouse per aggiungere nuovi elementi e selezionare l'immagine/i da aggiungere. Per impostazione predefinita, l'immagine avrà Azione di compilazione: Nessuna. Questa opzione deve essere impostata su Azione di compilazione: EmbeddedResource.

Impostare l'azione di compilazione sulla risorsa incorporata

L'azione di compilazione può essere visualizzata e modificata nella finestra Proprietà di un file.

In questo esempio l'ID risorsa è WorkingWithImages.beach.jpg. L'IDE ha generato questo valore predefinito concatenando lo spazio dei nomi predefinito per questo progetto con il nome file, usando un punto (.) tra ogni valore.

Se si inseriscono immagini incorporate in cartelle all'interno del progetto, i nomi delle cartelle sono separati anche da punti (.) nell'ID risorsa. Lo spostamento dell'immagine beach.jpg in una cartella denominata MyImages genera un ID risorsa di WorkingWithImages.MyImages.beach.jpg

Il codice per caricare un'immagine incorporata passa semplicemente l'ID risorsa al ImageSource.FromResource metodo come illustrato di seguito:

Image embeddedImage = new Image
{
    Source = ImageSource.FromResource("WorkingWithImages.beach.jpg", typeof(MyClass).GetTypeInfo().Assembly)
};

Nota

Per supportare la visualizzazione di immagini incorporate in modalità di rilascio nel piattaforma UWP (Universal Windows Platform), è necessario usare l'overload di che specifica l'assembly di ImageSource.FromResource origine in cui cercare l'immagine.

Attualmente non esiste alcuna conversione implicita per gli identificatori di risorsa. È invece necessario usare ImageSource.FromResource o new ResourceImageSource() per caricare immagini incorporate.

Gli screenshot seguenti mostrano il risultato della visualizzazione di un'immagine incorporata in ogni piattaforma:

Applicazione di esempio che visualizza un'immagine incorporata

XAML

Poiché non esiste un convertitore di tipi predefinito da string a ResourceImageSource, questi tipi di immagini non possono essere caricati in modo nativo da XAML. È invece possibile scrivere una semplice estensione di markup XAML personalizzata per caricare immagini usando un ID risorsa specificato in XAML:

[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
 public string Source { get; set; }

 public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   {
     return null;
   }

   // Do your translation lookup here, using whatever method you require
   var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}

Nota

Per supportare la visualizzazione di immagini incorporate in modalità di rilascio nel piattaforma UWP (Universal Windows Platform), è necessario usare l'overload di che specifica l'assembly di ImageSource.FromResource origine in cui cercare l'immagine.

Per usare questa estensione, aggiungere un oggetto personalizzato xmlns al codice XAML, usando lo spazio dei nomi e i valori di assembly corretti per il progetto. L'origine immagine può quindi essere impostata usando questa sintassi: {local:ImageResource WorkingWithImages.beach.jpg}. Di seguito è riportato un esempio XAML completo:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
   xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:local="clr-namespace:WorkingWithImages;assembly=WorkingWithImages"
   x:Class="WorkingWithImages.EmbeddedImagesXaml">
 <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
 </StackLayout>
</ContentPage>

Risolvere i problemi relativi alle immagini incorporate

Debug del codice

Poiché a volte è difficile comprendere il motivo per cui una determinata risorsa immagine non viene caricata, è possibile aggiungere temporaneamente il codice di debug seguente a un'applicazione per verificare che le risorse siano configurate correttamente. Verranno restituite tutte le risorse note incorporate nell'assembly specificato nella console per facilitare il debug dei problemi di caricamento delle risorse.

using System.Reflection;
// ...
// NOTE: use for debugging, not in released app code!
var assembly = typeof(MyClass).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
{
    System.Diagnostics.Debug.WriteLine("found resource: " + res);
}

Immagini incorporate in altri progetti

Per impostazione predefinita, il ImageSource.FromResource metodo cerca solo immagini nello stesso assembly del codice che chiama il ImageSource.FromResource metodo . Usando il codice di debug precedente è possibile determinare quali assembly contengono una risorsa specifica modificando l'istruzione typeof() in un Type elemento noto in ogni assembly.

Tuttavia, l'assembly di origine in cui viene eseguita la ricerca di un'immagine incorporata può essere specificato come argomento per il ImageSource.FromResource metodo :

var imageSource = ImageSource.FromResource("filename.png",
            typeof(MyClass).GetTypeInfo().Assembly);

Scarica immagini

Le immagini possono essere scaricate automaticamente per la visualizzazione, come illustrato nel codice XAML seguente:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       x:Class="WorkingWithImages.DownloadImagesXaml">
  <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
    <Label Text="Image UriSource Xaml" />
    <Image Source="https://aka.ms/campus.jpg" />
    <Label Text="campus.jpg gets downloaded from microsoft.com" />
  </StackLayout>
</ContentPage>

Il codice C# equivalente è il seguente:

var webImage = new Image {
     Source = ImageSource.FromUri(
        new Uri("https://aka.ms/campus.jpg")
     ) };

Il ImageSource.FromUri metodo richiede un Uri oggetto e restituisce un nuovo UriImageSource oggetto che legge da Uri.

Esiste anche una conversione implicita per le stringhe URI, quindi l'esempio seguente funzionerà anche:

webImage.Source = "https://aka.ms/campus.jpg";

Gli screenshot seguenti mostrano il risultato della visualizzazione di un'immagine remota in ogni piattaforma:

Applicazione di esempio che visualizza un'immagine scaricata

Memorizzazione nella cache dell'immagine scaricata

Un UriImageSource supporta anche la memorizzazione nella cache delle immagini scaricate, configurate tramite le proprietà seguenti:

  • CachingEnabled - Indica se la memorizzazione nella cache è abilitata (true per impostazione predefinita).
  • CacheValidity - Oggetto TimeSpan che definisce per quanto tempo l'immagine verrà archiviata in locale.

La memorizzazione nella cache è abilitata per impostazione predefinita e archivia l'immagine in locale per 24 ore. Per disabilitare la memorizzazione nella cache per una particolare immagine, creare un'istanza dell'origine immagine come indicato di seguito:

image.Source = new UriImageSource { CachingEnabled = false, Uri = new Uri("https://server.com/image") };

Per impostare un periodo di cache specifico ,ad esempio 5 giorni, creare un'istanza dell'origine immagine come indicato di seguito:

webImage.Source = new UriImageSource
{
    Uri = new Uri("https://aka.ms/campus.jpg"),
    CachingEnabled = true,
    CacheValidity = new TimeSpan(5,0,0,0)
};

La memorizzazione nella cache predefinita semplifica il supporto di scenari come lo scorrimento di elenchi di immagini, in cui è possibile impostare (o associare) un'immagine in ogni cella e consentire alla cache predefinita di ricaricare l'immagine quando la cella viene scorrere indietro nella visualizzazione.

GIF animate

Xamarin.Forms include il supporto per la visualizzazione di PICCOLE GIF animate. Questa operazione viene eseguita impostando la Image.Source proprietà su un file GIF animato:

<Image Source="demo.gif" />

Importante

Anche se il supporto GIF animato in Xamarin.Forms include la possibilità di scaricare file, non supporta la memorizzazione nella cache o lo streaming di GIF animate.

Per impostazione predefinita, quando viene caricata una GIF animata, non verrà riprodotta. Ciò è dovuto al fatto che la IsAnimationPlaying proprietà , che controlla se una GIF animata è in riproduzione o arrestata, ha un valore predefinito di false. Questa proprietà, di tipo bool, è supportata da un BindableProperty oggetto , il che significa che può essere la destinazione di un data binding e stile.

Pertanto, quando viene caricata una GIF animata, non verrà riprodotta finché la IsAnimationPlaying proprietà non viene impostata su true. La riproduzione può quindi essere arrestata impostando la IsAnimationPlaying proprietà su false. Si noti che questa proprietà non ha alcun effetto quando viene visualizzata un'origine immagine non GIF.

Nota

In Android, il supporto gif animato richiede che l'applicazione usi renderer veloci e non funzionerà se si è scelto di usare i renderer legacy. Nella piattaforma UWP, il supporto gif animato richiede una versione minima dell'aggiornamento dell'anniversario di Windows 10 (versione 1607).

Icone e schermate iniziali

Anche se non correlati alla Image visualizzazione, le icone dell'applicazione e le schermate iniziali sono anche un uso importante delle immagini nei Xamarin.Forms progetti.

L'impostazione delle icone e delle schermate iniziali per Xamarin.Forms le app viene eseguita in ognuno dei progetti dell'applicazione. Ciò significa generare immagini con dimensioni corrette per iOS, Android e UWP. Queste immagini devono essere denominate e posizionate in base ai requisiti di ogni piattaforma.

Icone

Per altre informazioni sulla creazione di queste risorse dell'applicazione, vedi iOS Working with Images, Google Iconography e UWP Guidelines for tile and icon assets for tile and icon assets (Uso di immagini, Google Iconography e linee guida UWP per asset di riquadri e icone ).

Inoltre, le icone dei tipi di carattere possono essere visualizzate dalla Image visualizzazione specificando i dati dell'icona del carattere in un FontImageSource oggetto . Per altre informazioni, vedere Visualizzare le icone dei tipi di carattere nella guida Tipi di carattere .

Schermate iniziali

Solo le applicazioni iOS e UWP richiedono una schermata iniziale (detta anche schermata di avvio o immagine predefinita).

Vedere la documentazione relativa all'uso di immagini e schermate iniziali di iOS in Windows Dev Center.