Images dans Xamarin.Forms

Les images peuvent être partagées entre les plateformes avec Xamarin.Formslesquelles elles peuvent être chargées spécifiquement pour chaque plateforme, ou être téléchargées pour l’affichage.

Les images font partie intégrante de la navigation, de la convivialité et de la personnalisation des applications. Xamarin.Forms les applications doivent être en mesure de partager des images sur toutes les plateformes, mais également d’afficher des images différentes sur chaque plateforme.

Les images spécifiques à la plateforme sont également requises pour les icônes et les écrans de démarrage ; ces éléments doivent être configurés par plateforme.

Afficher les images

Xamarin.Forms utilise l’affichage Image pour afficher des images sur une page. Il a plusieurs propriétés importantes :

  • Source - Instance ImageSource , fichier, URI ou ressource, qui définit l’image à afficher.
  • Aspect - Comment dimensionner l’image dans les limites dans laquelle elle est affichée (s’il faut étirer, rogner ou boîte à lettres).

ImageSource les instances peuvent être obtenues à l’aide de méthodes statiques pour chaque type de source d’image :

  • FromFile - Nécessite un nom de fichier ou un chemin de fichier qui peut être résolu sur chaque plateforme.
  • FromUri - Nécessite un objet Uri, par exemple. new Uri("http://server.com/image.jpg") .
  • FromResource - Nécessite un identificateur de ressource pour un fichier image incorporé dans le projet de bibliothèque .NET Standard ou application, avec une action de génération :EmbeddedResource.
  • FromStream - Nécessite un flux qui fournit des données d’image.

La Aspect propriété détermine la façon dont l’image sera mise à l’échelle pour s’adapter à la zone d’affichage :

  • Fill - Étire l’image pour remplir complètement et exactement la zone d’affichage. Cela peut entraîner une déformation de l’image.
  • AspectFill - Clipse l’image de sorte qu’elle remplit la zone d’affichage tout en préservant l’aspect (c’est-à-dire sans distorsion).
  • AspectFit - Boîtes aux lettres de l’image (si nécessaire) afin que l’image entière s’intègre dans la zone d’affichage, avec un espace vide ajouté au haut/bas ou aux côtés selon que l’image est large ou haute.

Les images peuvent être chargées à partir d’un fichier local, d’une ressource incorporée, d’un téléchargement ou d’un chargement à partir d’un flux. En outre, les icônes de police peuvent être affichées par l’affichage Image en spécifiant les données d’icône de police dans un FontImageSource objet. Pour plus d’informations, consultez Afficher les icônes de police dans le guide Polices .

Images locales

Les fichiers image peuvent être ajoutés à chaque projet d’application et référencés à partir du Xamarin.Forms code partagé. Cette méthode de distribution d’images est indispensable dans le cas d’images spécifiques à la plateforme, par exemple si vous utilisez différentes résolutions sur différentes plateformes ou des conceptions qui présentent quelques variations mineures.

Pour utiliser une seule image sur toutes les applications, le même nom de fichier doit être utilisé sur chaque plateforme, et il doit s’agir d’un nom de ressource Android valide (c’est-à-dire des lettres minuscules, des chiffres, du trait de soulignement et de la période autorisée).

  • iOS : la meilleure façon de gérer et de prendre en charge les images depuis iOS 9 consiste à utiliser les ensembles d’images du catalogue de ressources, qui doivent contenir toutes les versions d’une image nécessaires pour prendre en charge différents appareils et facteurs d’échelle pour une application. Pour plus d’informations, consultez Ajout d’images à un ensemble d’images de catalogue de ressources.
  • Android : placez des images dans le répertoire ressources/dessinables avec l’action de génération : AndroidResource. Les versions haute et faible d’une image peuvent également être fournies (dans des sous-répertoires Resources correctement nommés, tels que drawable-ldpi, drawable-hdpi et drawable-xhdpi).
  • plateforme Windows universelle (UWP) : par défaut, les images doivent être placées dans le répertoire racine de l’application avec l’action de génération : contenu. Vous pouvez également placer des images dans un autre répertoire, qui est ensuite spécifié avec une plateforme spécifique à la plateforme. Pour plus d’informations, consultez le répertoire d’images par défaut sur Windows.

Important

Avant iOS 9, les images ont généralement été placées dans le dossier Ressources avec l’action de génération : BundleResource. Toutefois, cette méthode d’utilisation d’images dans une application iOS a été déconseillée par Apple. Pour plus d’informations, consultez Tailles d’image et noms de fichiers.

L’adhésion à ces règles pour l’affectation de noms et le placement de fichiers permet au code XAML suivant de charger et d’afficher l’image sur toutes les plateformes :

<Image Source="waterfront.jpg" />

Le code C# équivalent est le suivant :

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

Les captures d’écran suivantes montrent le résultat de l’affichage d’une image locale sur chaque plateforme :

Exemple d’application affichant une image locale

Pour plus de flexibilité, la Device.RuntimePlatform propriété peut être utilisée pour sélectionner un autre fichier image ou chemin d’accès pour certaines ou toutes les plateformes, comme illustré dans cet exemple de code :

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

Important

Pour utiliser le même nom d’image sur toutes les plateformes, le nom doit être valide sur toutes les plateformes. Les dessinables Android ont des restrictions de nommage ( seuls les lettres minuscules, les chiffres, le trait de soulignement et la période sont autorisés) et, pour la compatibilité entre plateformes, cela doit également être suivi sur toutes les autres plateformes. L’exemple de nom de fichier waterfront.png suit les règles, mais des exemples de noms de fichiers non valides incluent « water front.png », « WaterFront.png », « water-front.png » et « wåterfront.png ».

Résolutions natives (rétine et haute résolution)

IOS, Android et UWP incluent la prise en charge des différentes résolutions d’images, où le système d’exploitation choisit l’image appropriée au moment de l’exécution en fonction des fonctionnalités de l’appareil. Xamarin.Forms utilise les API des plateformes natives pour charger des images locales, de sorte qu’elle prend automatiquement en charge les autres résolutions si les fichiers sont correctement nommés et situés dans le projet.

La meilleure façon de gérer les images, car iOS 9 consiste à faire glisser des images pour chaque résolution requise pour le jeu d’images du catalogue de ressources approprié. Pour plus d’informations, consultez Ajout d’images à un ensemble d’images de catalogue de ressources.

Avant iOS 9, les versions rétine de l’image peuvent être placées dans le dossier Ressources : deux et trois fois la résolution avec un suffixe @2x ou @3x sur le nom de fichier avant l’extension de fichier (par exemple). myimage@2x.png Toutefois, cette méthode d’utilisation d’images dans une application iOS a été déconseillée par Apple. Pour plus d’informations, consultez Tailles d’image et noms de fichiers.

Les images de résolution alternatives Android doivent être placées dans des répertoires spécialement nommés dans le projet Android, comme illustré dans la capture d’écran suivante :

Emplacement de l’image à résolution multiple Android

Les noms de fichiers image UWP peuvent être suffixes .scale-xxx avant l’extension de fichier, où xxx est le pourcentage de mise à l’échelle appliquée à la ressource, par exemple myimage.scale-200.png. Les images peuvent ensuite être référencées dans du code ou en XAML sans le modificateur d’échelle, par exemple, simplement myimage.png. La plateforme sélectionne l’échelle de ressource appropriée la plus proche en fonction de l’ppp actuel de l’affichage.

Contrôles supplémentaires qui affichent des images

Certains contrôles ont des propriétés qui affichent une image, telles que :

  • Button a une ImageSource propriété qui peut être définie sur une image bitmap à afficher sur le Button. Pour plus d’informations, consultez Utilisation de bitmaps avec des boutons.

  • ImageButton a une Source propriété qui peut être définie sur l’image à afficher dans le ImageButton. Pour plus d’informations, consultez Définition de la source de l’image.

  • ToolbarItem a une IconImageSource propriété qui peut être définie sur une image chargée à partir d’un fichier, d’une ressource incorporée, d’un URI ou d’un flux.

  • ImageCell a une ImageSource propriété qui peut être définie sur une image récupérée à partir d’un fichier, d’une ressource incorporée, d’un URI ou d’un flux.

  • Page. Tout type de page qui dérive d’un Page fichier IconImageSourceBackgroundImageSource , d’une ressource incorporée, d’un URI ou d’un flux peut être affecté. Dans certaines circonstances, par exemple lorsqu’un NavigationPage affiche un ContentPage, l’icône s’affiche si elle est prise en charge par la plateforme.

    Important

    Sur iOS, la Page.IconImageSource propriété ne peut pas être remplie à partir d’une image dans un ensemble d’images de catalogue de ressources. Au lieu de cela, chargez des images d’icône pour la Page.IconImageSource propriété à partir d’un fichier, d’une ressource incorporée, d’un URI ou d’un flux.

Images incorporées

Les images incorporées sont également fournies avec une application (comme les images locales), mais au lieu d’avoir une copie de l’image dans la structure de fichier de chaque application, le fichier image est incorporé dans l’assembly en tant que ressource. Cette méthode de distribution d’images est recommandée lorsque des images identiques sont utilisées sur chaque plateforme et sont particulièrement adaptées à la création de composants, car l’image est regroupée avec le code.

Pour incorporer une image dans un projet, cliquez avec le bouton droit pour ajouter de nouveaux éléments et sélectionnez l’image/s que vous souhaitez ajouter. Par défaut, l’image aura l’action de génération : Aucune ; cela doit être défini sur Action de génération : EmbeddedResource.

Définir l’action de génération sur une ressource incorporée

L’action de génération peut être consultée et modifiée dans la fenêtre Propriétés d’un fichier.

Dans cet exemple, l’ID de ressource est WorkingWithImages.beach.jpg. L’IDE a généré cette valeur par défaut en concaténant l’espace de noms par défaut pour ce projet avec le nom de fichier, à l’aide d’un point (.) entre chaque valeur.

Si vous placez des images incorporées dans des dossiers au sein de votre projet, les noms des dossiers sont également séparés par des points (.) dans l’ID de ressource. Le déplacement de l’image beach.jpg dans un dossier appelé MyImages entraînerait un ID de ressource de WorkingWithImages.MyImages.beach.jpg

Le code permettant de charger une image incorporée transmet simplement l’ID de ressource à la ImageSource.FromResource méthode, comme indiqué ci-dessous :

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

Remarque

Pour prendre en charge l’affichage d’images incorporées en mode mise en production sur l’plateforme Windows universelle, il est nécessaire d’utiliser la surcharge de ImageSource.FromResource ce qui spécifie l’assembly source dans lequel rechercher l’image.

Actuellement, il n’existe aucune conversion implicite pour les identificateurs de ressource. Au lieu de cela, vous devez utiliser ImageSource.FromResource ou new ResourceImageSource() charger des images incorporées.

Les captures d’écran suivantes montrent le résultat de l’affichage d’une image incorporée sur chaque plateforme :

Exemple d’application affichant une image incorporée

XAML

Étant donné qu’il n’existe aucun convertisseur de type intégré à ResourceImageSourcepartir duquel string , ces types d’images ne peuvent pas être chargés en mode natif par XAML. Au lieu de cela, une extension de balisage XAML personnalisée simple peut être écrite pour charger des images à l’aide d’un ID de ressource spécifié en 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;
 }
}

Remarque

Pour prendre en charge l’affichage d’images incorporées en mode mise en production sur l’plateforme Windows universelle, il est nécessaire d’utiliser la surcharge de ImageSource.FromResource ce qui spécifie l’assembly source dans lequel rechercher l’image.

Pour utiliser cette extension, ajoutez un code personnalisé xmlns au code XAML, en utilisant les valeurs d’espace de noms et d’assembly appropriées pour le projet. La source d’image peut ensuite être définie à l’aide de cette syntaxe : {local:ImageResource WorkingWithImages.beach.jpg}. Un exemple XAML complet est illustré ci-dessous :

<?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>

Résoudre les problèmes liés aux images incorporées

Déboguer du code

Étant donné qu’il est parfois difficile de comprendre pourquoi une ressource d’image particulière n’est pas chargée, le code de débogage suivant peut être ajouté temporairement à une application pour vous aider à confirmer que les ressources sont correctement configurées. Elle génère toutes les ressources connues incorporées dans l’assembly donné à la console pour aider à déboguer les problèmes de chargement des ressources.

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

Images incorporées dans d’autres projets

Par défaut, la ImageSource.FromResource méthode recherche uniquement des images dans le même assembly que le code appelant la ImageSource.FromResource méthode. À l’aide du code de débogage ci-dessus, vous pouvez déterminer quels assemblys contiennent une ressource spécifique en modifiant l’instruction typeof() en une Type instruction connue pour être dans chaque assembly.

Toutefois, l’assembly source recherché pour une image incorporée peut être spécifié comme argument de la ImageSource.FromResource méthode :

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

Télécharger des images

Les images peuvent être téléchargées automatiquement pour l’affichage, comme indiqué dans le code XAML suivant :

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

Le code C# équivalent est le suivant :

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

La ImageSource.FromUri méthode nécessite un Uri objet et retourne un nouveau UriImageSource qui lit à partir du Uri.

Il existe également une conversion implicite pour les chaînes d’URI. L’exemple suivant fonctionne également :

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

Les captures d’écran suivantes montrent le résultat de l’affichage d’une image distante sur chaque plateforme :

Exemple d’application affichant une image téléchargée

Mise en cache d’images téléchargée

Il UriImageSource prend également en charge la mise en cache des images téléchargées, configurées par le biais des propriétés suivantes :

  • CachingEnabled - Indique si la mise en cache est activée (true par défaut).
  • CacheValidity : qui TimeSpan définit la durée pendant laquelle l’image sera stockée localement.

La mise en cache est activée par défaut et stocke l’image localement pendant 24 heures. Pour désactiver la mise en cache d’une image particulière, instanciez la source de l’image comme suit :

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

Pour définir une période de cache spécifique (par exemple, 5 jours) instanciez la source d’image comme suit :

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

La mise en cache intégrée facilite la prise en charge de scénarios tels que le défilement des listes d’images, où vous pouvez définir (ou lier) une image dans chaque cellule et laisser le cache intégré prendre soin de recharger l’image lorsque la cellule est renvoyée en mode affichage.

Gif animés

Xamarin.Forms inclut la prise en charge de l’affichage de fichiers GIF petits et animés. Pour ce faire, définissez la Image.Source propriété sur un fichier GIF animé :

<Image Source="demo.gif" />

Important

Bien que la prise en Xamarin.Forms charge de l’image GIF animée inclut la possibilité de télécharger des fichiers, elle ne prend pas en charge la mise en cache ou la diffusion en continu de gif animés.

Par défaut, lorsqu’un GIF animé est chargé, il ne sera pas lu. Cela est dû au fait que la IsAnimationPlaying propriété, qui contrôle si un GIF animé est en cours de lecture ou arrêté, a une valeur par défaut de false. Cette propriété, de type bool, est sauvegardée par un BindableProperty objet, ce qui signifie qu’elle peut être la cible d’une liaison de données et avec style.

Par conséquent, lorsqu’un GIF animé est chargé, il ne sera pas lu tant que la IsAnimationPlaying propriété n’est pas définie truesur . La lecture peut ensuite être arrêtée en définissant la IsAnimationPlaying propriété sur false. Notez que cette propriété n’a aucun effet lors de l’affichage d’une source d’image non GIF.

Remarque

Sur Android, la prise en charge de GIF animée nécessite que votre application utilise des renderers rapides et ne fonctionne pas si vous avez choisi d’utiliser les convertisseurs hérités. Sur UWP, la prise en charge des GIF animées nécessite une version minimale de la mise à jour anniversaire Windows 10 (version 1607).

Icônes et écrans de démarrage

Bien qu’elles ne soient pas liées à l’affichage Image , les icônes d’application et les écrans de démarrage sont également une utilisation importante des images dans les Xamarin.Forms projets.

La définition d’icônes et d’écrans de démarrage pour Xamarin.Forms les applications est effectuée dans chacun des projets d’application. Cela signifie la génération d’images correctement dimensionnées pour iOS, Android et UWP. Ces images doivent être nommées et situées en fonction des exigences de chaque plateforme.

Icônes

Pour plus d’informations sur la création de ces ressources d’application, consultez l’article iOS Working with Images, Google Iconography et UWP Guidelines for tile and icon assets .

En outre, les icônes de police peuvent être affichées par l’affichage Image en spécifiant les données d’icône de police dans un FontImageSource objet. Pour plus d’informations, consultez Afficher les icônes de police dans le guide Polices .

Écrans de démarrage

Seules les applications iOS et UWP nécessitent un écran de démarrage (également appelé écran de démarrage ou image par défaut).

Reportez-vous à la documentation pour iOS Working with Images and Splash screens on the Windows Centre de développement.