Images dans Xamarin.Forms

Télécharger l’exemple Télécharger l’exemple

Les images peuvent être partagées sur plusieurs plateformes avec Xamarin.Forms, elles peuvent être chargées spécifiquement pour chaque plateforme ou téléchargées pour être affichées.

Les images sont un élément crucial de la navigation, de la facilité d’utilisation 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.

Des images spécifiques à la plateforme sont également requises pour les icônes et les écrans de démarrage ; celles-ci doivent être configurées par plateforme.

Afficher les images

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

  • Source- Un ImageSource instance, fichier, URI ou ressource, qui définit l’image à afficher.
  • Aspect - Comment dimensionner l’image dans les limites où elle s’affiche (s’il s’agit d’étirer, de rogner ou de boîte aux 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 l’application ou le projet de bibliothèque .NET Standard, 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 aucune 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/au 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, téléchargées ou chargées à partir d’un flux. En outre, les icônes de police peuvent être affichées par la Image vue en spécifiant les données de l’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 dans 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 que seuls les minuscules, les chiffres, le trait de soulignement et le point sont autorisés).

  • iOS : la meilleure façon de gérer et de prendre en charge les images depuis iOS 9 consiste à utiliser des 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 de mise à l’échelle pour une application. Pour plus d’informations, consultez Ajout d’images à un ensemble d’images du catalogue de ressources.
  • Android : placez des images dans le répertoire Ressources/dessinable avec action de génération : AndroidResource. Les versions haute et faible DPI d’une image peuvent également être fournies (dans les sous-répertoires ressources 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 Action de génération : Contenu. Vous pouvez également placer les images dans un autre répertoire qui est ensuite spécifié avec un répertoire spécifique à la plateforme. Pour plus d’informations, consultez Répertoire d’images par défaut sur Windows.

Important

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

L’adhésion à ces règles pour l’attribution de noms et le placement des 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 indiqué 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 de fichier d’image sur toutes les plateformes, le nom doit être valide sur toutes les plateformes. Les dessinables Android ont des restrictions de nommage ( seules les minuscules, les chiffres, le trait de soulignement et le point sont autorisés ), et pour une compatibilité multiplateforme, cela doit également être suivi sur toutes les autres plateformes. L’exemple de nom de fichierwaterfront.png suit les règles, mais les 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 de 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 le chargement d’images locales, de sorte qu’elle prend automatiquement en charge d’autres résolutions si les fichiers sont correctement nommés et situés dans le projet.

La méthode recommandée pour gérer les images depuis iOS 9 consiste à faire glisser les images pour chaque résolution requise vers l’ensemble d’images de catalogue de ressources approprié. Pour plus d’informations, consultez Ajout d’images à un ensemble d’images du catalogue de ressources.

Avant iOS 9, les versions retina de l’image pouvaient être placées dans le dossier Resources ( 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 des images dans une application iOS a été dépréciée par Apple. Pour plus d’informations, consultez Tailles d’image et noms de fichiers.

Les images de résolution alternative 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 Android à résolution multiple

Les noms de fichiers d’image UWP peuvent être suffixes avant .scale-xxx l’extension de fichier, où xxx est le pourcentage de mise à l’échelle appliqué à la ressource, par exemple ,myimage.scale-200.png. Les images peuvent ensuite être référencées dans le code ou XAML sans le modificateur d’échelle, par exemple , simplementmyimage.png. La plateforme sélectionne la mise à l’échelle 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 possède 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 d’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 de Page possède IconImageSource des propriétés et BackgroundImageSource , qui peuvent recevoir un fichier, une ressource incorporée, un URI ou un flux. 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 les 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 est particulièrement adaptée à la création de composants, car l’image est groupé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 la ou les images 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 de 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’imagebeach.jpg dans un dossier appelé MyImages entraînerait un ID de ressource deWorkingWithImages.MyImages.beach.jpg

Le code pour 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)
};

Notes

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

Actuellement, il n’existe aucune conversion implicite pour les identificateurs de ressources. Au lieu de cela, vous devez utiliser ImageSource.FromResource ou new ResourceImageSource() pour 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 pas de convertisseur de type intégré de string à ResourceImageSource, ces types d’images ne peuvent pas être chargés en mode natif par XAML. Au lieu de cela, une simple extension de balisage XAML personnalisée peut être écrite pour charger des images à l’aide d’un ID de ressource spécifié dans 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;
 }
}

Notes

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

Pour utiliser cette extension, ajoutez un personnalisé xmlns au 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 la syntaxe suivante : {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 vérifier que les ressources sont correctement configurées. Il génère toutes les ressources connues incorporées dans l’assembly donné dans 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 les 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 remplaçant l’instruction typeof() par une Type instruction connue 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 être affichées, 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 de .Uri

Il existe également une conversion implicite pour les chaînes d’URI, de sorte que l’exemple suivant fonctionnera é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 des images téléchargées

Un UriImageSource prend également en charge la mise en cache des images téléchargées, configurées via les propriétés suivantes :

  • CachingEnabled - Si la mise en cache est activée (true par défaut).
  • CacheValidityTimeSpan- qui 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 d’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 de listes d’images, où vous pouvez définir (ou lier) une image dans chaque cellule et permettre au cache intégré de se charger à nouveau de charger l’image lorsque la cellule est de nouveau affichée.

GIF animés

Xamarin.Forms inclut la prise en charge de l’affichage de petits GIF 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 charge des GIF animés dans Xamarin.Forms 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 n’est 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 d’arrêt, a une valeur par défaut de false. Cette propriété, de type bool, est soutenue par un BindableProperty objet, ce qui signifie qu’elle peut être la cible d’une liaison de données et stylée.

Par conséquent, lorsqu’un GIF animé est chargé, il n’est pas lu tant que la IsAnimationPlaying propriété n’est pas définie sur true. Vous pouvez ensuite arrêter la lecture 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.

Notes

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

Icônes et écrans de démarrage

Bien qu’elles ne soient pas liées à la vue, les Image 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 des icônes et des écrans de démarrage pour Xamarin.Forms les applications est effectuée dans chacun des projets d’application. Cela signifie générer des images correctement dimensionnées pour iOS, Android et UWP. Ces images doivent être nommées et localisées en fonction des exigences de chaque plateforme.

Icônes

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

En outre, les icônes de police peuvent être affichées par la Image vue en spécifiant les données de l’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 relative à l’utilisation d’images iOS et aux écrans de démarrage dans le Centre de développement Windows.