Xamarin.Forms

Intégrez vos images sans douleur dans Xamarin.Forms avec ResizetizerNT

par
publié le
Image par Gerd Altmann de Pixabay

Il y a peu, je vous montrais comment gagner en productivité en utilisant les embedded fonts pour intégrer des polices de caractère personnalisée dans Xamarin.Forms. Aujourd’hui encore, je vous propose de gagner énormément de temps en vous épargnant l’enfer de la gestion des images dans Xamarin.Forms.

Comment a-t-on pu supporter ça si longtemps ?

Vous le savez, la force de Xamarin.Forms réside dans la mise-en-commun du code et des interfaces utilisateur entre toutes les plateformes. Cela fonctionne très bien dans 90% des cas mais il subsiste encore quelques situations qui nécessitent de travailler séparément dans chaque projet natif.

C’est le cas notamment de la gestion des images : il faut s’assurer d’avoir chaque image dans toutes les définitions nécessaires à chaque plateforme et de les distribuer au bon endroit.

Un véritable casse tête :

  • iOS réclame 3 définitions différentes de chaque image, toutes stockées dans le même dossier mais avec des noms dépendant de leur densité. Par exemple : image.png, image@2x.png, image@3x.png.
  • Chez Android, c’est légèrement différent. L’image a le même nom quelque soit sa définition, mais chaque version est répartie dans le dossier correspondant à sa définition !
  • Sous UWP, c’est encore une nomenclature différente !

Dans le meilleur des cas, vous disposez de tous les assets dans toutes les définitions, vous avez juste à bien les copier dans chaque dossier sans vous tromper. Et encore, chez moi Visual Studio fige plusieurs secondes à chaque fois que j’ajoute une image dans le projet Android. Juste un peu crispant.

La plupart du temps, vous avez juste une image de base et c’est à vous de vous débrouiller pour générer tous les assets. Alors bien entendu, il existe quelques outils qui automatisent tout ça, mais quand vous reçevez les assets au compte goutte et que vous devez recommencer 10 fois… 🤯

Et j’ai gardé le meilleur pour la fin. Quand on passera aux écrans 4K sur les téléphone et que tous les OS réclameront une ou deux versions supplémentaires de chacune de vos images ? Hein, vous y avez pensé ? Ça va être amusant de tout recommencer !

Jonathan Dick, mon héros

Alors figurez vous qu’il y a quelqu’un chez Xamarin que ça énervait autant que moi. Et pas n’importe qui : Jonathan Dick, l’un des principaux développeurs de l’équipe !

Il a donc créé une “petite chose” comme il le dit lui-même qui génère automatiquement toutes les définitions d’images nécessaires et les distribue au bon endroit à partir d’une simple image vectorielle partagée dans le dossier Xamarin.Forms.

Cela s’appelle ResizetizerNT.

Pour ceux d’entre-vous qui comprennent l’anglais, je vous invite à consulter directement les articles originaux : Shared Images for Xamarin with Resizetizer NT et La démonstration vidéo avec James Montemagno et Jonathan Dick

Sinon, continuez avec moi, je vous explique tout en français ! 😉

Installation de Resizetizer

Partons d’une solution Xamarin.Forms “Blank” par défaut. Allez-y, je vous attends.

1. Installer le package nuget

C’est bon, la solution est créée ? Ajoutons maintenant le package nuget Resizertizer.NT à tous les projets.

Image illustrant l'installation du package nuget Resizetizer.NT
Installer le package nuget dans tous les projets

2. Ajouter une image au projet Xamarin.Forms

Ajouter votre image au projet Xamarin.Forms, où bon vous semble mais en prenant bien garde que :

  • L’image soit au format vectoriel svg
  • Son Build Action soit SharedImage
Image illustrant la configuration du build action
Affectez le build action sur SharedImage

3. Indiquer la taille de base de l’image dans le fichier .csproj

C’est la partie un peu délicate de la procédure : indiquer la taille finale de l’image dans le fichier .csproj.

Hé oui, le format svg étant vectoriel, il n’a pas de dimension à proprement parler, il est donc nécessaire d’indiquer à Xamarin.Forms la dimension de base sur laquelle s’appuyer pour générer les différentes versions des assets.

Après un clic-droit sur le projet Xamarin.Forms dans l’éditeur de solution, sélectionnez Edit project file.

Image illustrant l'édition du fichier .csproj
Editez le fichier projet Xamarin.Forms

Vous devriez y trouver un ItemGroup contenant votre SharedImage, quelquechose comme ça :

<ItemGroup>
    <SharedImage Include="xamarin.svg" />
</ItemGroup>

Il s’agit maintenant de lui attribuer sa taille de base avec l’attibut BaseSize, typiquement sa taille d’affichage dans le code xaml :

<ItemGroup>
    <SharedImage Include="xamarin.svg" BaseSize="60,60" />
</ItemGroup>

Sauvegardez votre fichier projet, fermez l’onglet, nous vous n’en avez plus besoin.

3. Utiliser l’image dans l’application

Allons au plus simple, rendez-vous dans la page MainPage.xaml du projet et remplacez le contenu du StackLayout déjà présent par votre image, avec une extension png :

<Image Source="xamarin.png" HeightRequest="60"  WidthRequest="60" VerticalOptions="Center"/>

Et c’est bien ce dont il s’agit, car lors de la compilation du projet Resizetizer converti automagiquement votre fichier svg en png dans toutes les définitions nécessaires (en s’appuyant sur SkiaSharp), puis les distribue aux bons endroits.

Vous noterez que les valeurs des propriétés `HeightRequest` et `WidthRequest` correspondent au `BaseSize` défini plus tôt.

4. La preuve par l’image

Illustration sous Android, affichage du logo Xamarin au centre de la page, à partir d’une image svg partagée dans le projet Xamarin.Forms :

Capture d'écran sous Android

Quelques infos supplémentaires

Dans son blog, J. Dick précise que tout cela fonctionne également avec un fichier source au format png, mais qu’il faut bien prendre soin de définir correctement le BaseSize sous peine d’obtenir un résultat bien moche lors de la conversion.

Les versions futurs de ResizetizerNT devraient connaître quelques améliorations, par exemple l’affectation d’une couleur aux images de la conversion à partir d’un fichier svg, ou la gestion des icones d’application.

Projet à surveiller, donc !

Le code source

Le code source du projet de démo est disponible dans mon repository github.

Ne soyez pas surpris, il ne contient vraiment pas grand chose, et c'est justement ça qui est important à retenir !