Intégrez vos images sans douleur dans Xamarin.Forms avec ResizetizerNT
Tags: xamarinforms, images, resizetizernt, french
Published: 2020-07-20 14:48:01

Il y a peu, je vous montrais comment gagner en productivité en utilisant les [embedded fonts](https://www.sylvainmoingeon.fr/simplifiez-vous-les-fonts-sous-xamarinforms/) 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](https://redth.codes/), l'un des principaux développeurs de l'équipe ! 

Il a donc créé une ["petite chose"](https://redth.codes/resizetizer-nt-shared-images-for-xamarin/) 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](https://github.com/Redth/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](https://redth.codes/resizetizer-nt-shared-images-for-xamarin/) et
[La démonstration vidéo avec James Montemagno et Jonathan Dick](https://channel9.msdn.com/Shows/XamarinShow/Cross-platform-Images-Simplified-with-ResizetizerNT--The-Xamarin-Show)

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.

<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/i/vszpj9v8st50r7ez7hyo.png" alt="Image illustrant l'installation du package nuget Resizetizer.NT"></img>
<figcaption>Installer le package nuget dans tous les projets</figcaption>
</figure>

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

<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/i/z6hmku6zn6s57r9cr4bo.png" alt="Image illustrant la configuration du build action"></img>		<figcaption>Affectez le build action sur SharedImage</figcaption>
</figure>

## 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`.

<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/i/1rrfowkvbrpbhxhc68jv.png" alt="Image illustrant l'édition du fichier .csproj"></img>
<figcaption>Editez le fichier projet Xamarin.Forms</figcaption>
</figure>

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

```xml
<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` :

```xml
<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`** :

```xml
<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](https://github.com/mono/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](https://dev-to-uploads.s3.amazonaws.com/i/5q8buuihl2chz78xrf5j.png)

# Quelques infos supplémentaires
Dans son [blog](https://redth.codes/resizetizer-nt-shared-images-for-xamarin/), 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](https://github.com/Redth/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](https://github.com/SylvainMoingeon/ResizetizerNTDemo "Repository github vers le projet de démo").

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