Lors du développement d'une application mobile, de nombreux points doivent être pris en compte. C'est le choix de la technologie sur laquelle elle sera écrite, et le développement de l'architecture de l'application, et, en fait, l'écriture du code. Tôt ou tard, un moment arrive où le cœur de l'application est là, toute la logique est écrite et l'application, en général, fonctionne, mais ... il n'y a pas d'apparence. Ici, il convient de réfléchir aux ressources graphiques qui seront utilisées, car les graphiques représentent la part du lion de la taille de l'assemblage final, que ce soit .apk sur Android ou .ipa sur iOS. D'énormes assemblages sont, en principe, attendus pour les jeux mobiles, même maintenant à partir de PlayMarket, vous devez parfois télécharger des volumes de données allant jusqu'à 2 Go et c'est bien si vous pouvez vous connecter au Wi-Fi pendant le téléchargement ou que l'opérateur mobile fournit une connexion haut débit illimitée.Mais pour les jeux, cela est attendu, et une application métier d'une telle taille soulève involontairement la question "D'où cela vient-il?" L'une des raisons de la grande taille de l'assemblage d'une application métier peut être un nombre important d'icônes et d'images qui doivent y être affichées. Et n'oubliez pas non plus qu'une grande quantité de graphiques affecte proportionnellement les performances de l'application.
Lors de la création du composant graphique d'une application, il y a souvent un problème sérieux. Il existe de nombreux appareils mobiles, des montres aux tablettes, et leurs résolutions d'écran sont très différentes. Pour cette raison, il est souvent nécessaire d'inclure des ressources graphiques dans un assemblage dans des fichiers distincts pour chacun des types existants. 5 exemplaires pour Android et 3 pour iOS. Cela affecte considérablement la taille de l'assemblage final que vous téléchargerez dans le magasin.
Nous vous expliquerons ce que vous pouvez faire pour éviter de vous retrouver dans une telle situation dans cet article.
Comparaison des formats PNG et SVG
La principale différence entre les formats PNG et SVG est que PNG est un format bitmap et SVG est un format vectoriel.
Un bitmap est une grille de pixels sur un moniteur et est utilisé partout, que ce soit de petites icônes ou d'immenses bannières. Les avantages de ce type de graphiques sont les suivants:
- Les graphiques raster vous permettent de créer des dessins de presque n'importe quelle complexité, sans perte notable de taille de fichier;
- Si aucune mise à l'échelle de l'image n'est requise, la vitesse de traitement des images complexes est très élevée;
- La représentation bitmap des images est naturelle pour la plupart des périphériques d'E / S.
Cependant, il y a aussi des inconvénients.
Par exemple, une image bitmap ne peut pas être mise à l'échelle parfaitement. Lorsque vous agrandissez une petite image, l'image «mousse» et vous pouvez voir les pixels qui la composent.
De plus, les images simples constituées d'un grand nombre de points sont grandes. Par conséquent, il est recommandé de stocker des dessins simples au format vectoriel. Tout ce qui précède est vrai à la fois pour le format PNG et pour tout autre format graphique raster.
Le format SVG, quant à lui, n'est pas vraiment une image. Selon l'article de wikipedia, SVG est un langage de balisage graphique vectoriel évolutif qui vous permet de lire et de modifier un fichier selon vos besoins.
De plus, étant un langage de balisage, SVG vous permet d'appliquer des filtres dans un document (par exemple, flou, relief, etc.). Ils sont déclarés comme des balises dont le spectateur est responsable du rendu, ce qui signifie qu'ils n'affectent pas la taille du fichier d'origine.
En plus de ce qui précède, le format SVG présente un certain nombre d'autres avantages:
- En tant que format vectoriel, SVG vous permet de mettre à l'échelle n'importe quelle partie d'une image sans perte de qualité;
- Les graphiques raster peuvent être insérés dans un document SVG;
- S'intègre facilement aux documents HTML et XHTML.
Cependant, ce format présente également des inconvénients:
- Plus les détails de l'image sont fins, plus la taille des données SVG augmente rapidement. Dans certains cas, SVG non seulement n'offre pas d'avantages, mais perd également pour le raster;
- La complexité d'utilisation dans les applications cartographiques, car pour afficher correctement une petite partie de l'image, il faut lire l'intégralité du document.
Il existe un autre inconvénient dans le cas du développement d'applications mobiles sur la plateforme Xamarin.
Pour fonctionner correctement avec ce format, vous devez connecter des bibliothèques supplémentaires ou rechercher des solutions de contournement.
Utilisation du format SVG dans Xamarin.Android
Comme mentionné ci-dessus, Xamarin ne prend pas en charge SVG prêt à l'emploi. Pour résoudre ce problème, vous pouvez utiliser des bibliothèques tierces ou VectorDrawable. Récemment, les développeurs donnent de plus en plus la préférence à ce dernier, car la plupart des bibliothèques pour Xamarin sont axées sur une utilisation multiplateforme dans Xamarin.Forms, et les solutions pour l'android natif ne sont plus prises en charge par leurs développeurs et sont obsolètes, ou il y a de graves problèmes lors de la tentative de construction sur leur base bibliothèque pour Xamarin. À cet égard, nous allons ici envisager d'utiliser VectorDrawable.
Pour mettre en œuvre cette approche, vous devez utiliser Vector Asset Studio. Le trouver est assez simple, vous avez juste besoin d'Android Studio. Alors, commençons:
- Android Studio File -> New -> New Project;
, — Vector Asset Studio, . - drawable -> New -> Vector Asset;
Asset Studio. Material Design, SVG PSD, xml-. . - Asset Studio
, , . - Next
Xamarin.Android.
Assez de travail préparatoire pour que Android Studio soit installé. Malheureusement, au moment d'écrire ces lignes, nous n'avons pas pu trouver de convertisseurs en ligne fonctionnant correctement. Certains ont donné une erreur lors de la tentative de conversion du fichier SVG fourni, d'autres ont indiqué qu'il était préférable d'utiliser Vector Asset Studio.
Quoi qu'il en soit, nous avons le fichier requis et nous pouvons maintenant l'utiliser dans notre projet. Nous ne décrirons pas le processus de création d'un projet Xamarin.Android, allons droit au but.
Tout d'abord, nous avons placé le fichier résultant dans le dossier dessinable du projet, puis, comme démonstration de l'utilisation de ce fichier, nous avons créé 3 ImageViews à l'écran.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android ="http://schemas.android.com/apk/res/android"
xmlns:app ="http://schemas.android.com/apk/res-auto"
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentLeft="true"
android:id="@+id/imageView1"
android:adjustViewBounds="true"
app:srcCompat="@drawable/question_svg"
android:background="@android:color/holo_red_dark"/>
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentRight="true"
android:id="@+id/imageView2"
android:adjustViewBounds="true"
app:src="@drawable/question"
android:background="@android:color/holo_red_dark"/>
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:id="@+id/imageView3"
android:adjustViewBounds="true"
android:layout_marginTop="30dp"
app:srcCompat="@drawable/question"
android:layout_below="@id/imageView1"/>
</RelativeLayout>
Dans le premier ImageView, nous avons essayé d'attribuer le fichier SVG d'origine dans la propriété android: src, dans le second, le fichier XML converti dans la même propriété, et dans le troisième, dans la propriété app: srcCompat (notez que cet espace de noms doit être spécifié comme indiqué dans le code ).
Les résultats étaient déjà visibles dans le concepteur, avant le lancement de l'application - le seul moyen sûr d'afficher correctement notre fichier est donné dans le troisième ImageView.
Vous devez maintenant vous assurer que l'image s'affiche correctement sur différents appareils. À titre de comparaison, nous avons choisi Huawei Honor 20 Pro et Nexus 5. Et aussi, au lieu de méthodes d'affichage incorrectes, nous avons spécifié celle souhaitée et redimensionné l'ImageView à 150x150 dp, 200x200 dp et 300x300 dp.
Huawei Honor 20 Pro
Nexus 5
Comme vous pouvez le constater, la qualité des images est la même, ce qui signifie que nous avons obtenu le résultat souhaité.
Le fichier résultant est utilisé à partir du code de la même manière que d'habitude
image.SetImageResource(Resource.Drawable.< >);
Utilisation du format SVG dans Xamarin.iOS
Dans le cas de Xamarin.iOS, la situation est la même qu'avec Xamarin.Android, en ce sens que l'utilisation de fichiers SVG n'est pas prise en charge par défaut. Cependant, sa mise en œuvre ne demande pas beaucoup d'efforts. Dans le cas du développement iOS natif, SVG nécessite une connexion SVGKit. Il vous permet de traiter ces fichiers sans recourir à des solutions tierces. Dans le cas de Xamarin.iOS, nous pouvons utiliser la bibliothèque SVGKit.Binding . Il s'agit d'un wrapper C # sur le SVGKit d'origine.
Tout ce dont nous avons besoin est de connecter le package NuGet à notre projet. Au moment d'écrire ces lignes, la dernière version est la 1.0.4.
Malheureusement, apparemment, cette bibliothèque n'est plus prise en charge, mais elle convient tout à fait à une utilisation dans le projet.
Ici, la classe SVGKImage (l'image SVG elle-même) et SVGKFastImageView (le contrôle pour afficher ces images) sont implémentées.
void CreateControls()
{
var image_bundle_resource = new SVGKImage("SVGImages/question.svg");
img1 = new SVGKFastImageView(image_bundle_resource);
Add(img1);
img1.Frame = new CGRect(View.Frame.Width / 4, 50, View.Frame.Width / 2, View.Frame.Width / 2);
var image_content = new SVGKImage(Path.Combine(NSBundle.MainBundle.BundlePath, "SVGImages/question1.svg"));
img2 = new SVGKFastImageView(image_content);
Add(img2);
img2.Frame = new CGRect(5, img1.Frame.Bottom + 5, View.Frame.Width - 5, View.Frame.Width - 5);
}
Malheureusement, la bibliothèque présente un certain nombre d'inconvénients:
- SVGKFastImageView ne prend pas en charge l'initialisation sans fournir SVGKImage - une erreur est générée indiquant la nécessité d'utiliser le constructeur fourni dans le code;
- Il n'y a aucun moyen d'utiliser les fichiers SVG dans d'autres contrôles. Cependant, si cela n'est pas nécessaire, vous pouvez l'utiliser.
Si l'application est essentielle pour utiliser les fichiers SVG non seulement dans ImageView, vous pouvez utiliser d'autres bibliothèques. Par exemple, FFImageLoading . Il s'agit d'une bibliothèque puissante qui vous permet non seulement de décharger des images SVG dans l'UIImage native Xamarin.iOS, mais également de le faire directement dans le contrôle souhaité, ce qui permet de gagner du temps de développement. Il existe également une fonctionnalité de téléchargement d'images depuis Internet, mais nous ne la considérerons pas dans cet article.
Pour utiliser la bibliothèque, vous devez connecter deux packages NuGet au projet: Xamarin.FFImageLoading et Xamarin.FFImageLoading.SVG.
Dans l'application de test, nous avons utilisé une méthode qui charge l'image SVG directement dans UIImageView et décharge l'image dans l'UIImage native.
private async Task CreateControls()
{
img1 = new UIImageView();
Add(img1);
img1.Frame = new CGRect(View.Frame.Width / 4, 50, View.Frame.Width/2, View.Frame.Width/2);
ImageService.Instance
.LoadFile("SVGImages/question.svg")
.WithCustomDataResolver(new SvgDataResolver((int)img1.Frame.Width, 0, true))
.Into(img1);
var button = new UIButton() { BackgroundColor = UIColor.Red};
Add(button);
button.Frame = new CGRect(View.Frame.Width/2 - 25, img1.Frame.Bottom + 20, 50, 50);
UIImage imageSVG = await ImageService.Instance
.LoadFile("SVGImages/question.svg")
.WithCustomDataResolver(new SvgDataResolver((int)View.Frame.Width, 0, true))
.AsUIImageAsync();
if(imageSVG != null)
button.SetBackgroundImage(imageSVG, UIControlState.Normal);
}
Il existe également une méthode dans cette bibliothèque pour remplacer la représentation sous forme de chaîne SVG dans UIImage, mais cela n'a de sens que pour les petits fichiers.
var svgString = @"<svg><rect width=""30"" height=""30"" style=""fill:blue"" /></svg>";
UIImage img = await ImageService.Instance
.LoadString(svgString)
.WithCustomDataResolver(new SvgDataResolver(64, 0, true))
.AsUIImageAsync();
La bibliothèque possède également un certain nombre de fonctionnalités, mais nous ne les considérerons pas ici. La seule chose qui mérite vraiment d'être mentionnée est que cette bibliothèque peut également être utilisée dans les projets Xamarin.Android. Pour une utilisation dans les projets Xamarin.Forms, il existe des analogues de cette bibliothèque, dont nous parlerons ci-dessous.
Utilisation du format SVG dans Xamarin.Forms
Dans l'ensemble, il n'est pas nécessaire de rechercher des bibliothèques pour les formulaires, vous pouvez simplement connecter les plates-formes connues aux projets et prendre beaucoup de temps et triste à réécrire les rendus pour chaque contrôle que vous souhaitez utiliser. Heureusement, il existe une solution que nous partagerons.
Xamarin.FFImageLoading Xamarin.FFImageLoading.SVG, Xamarin.Forms (Xamarin.FFImageLoading.Forms Xamarin.FFImageLoading.SVG.Forms). Xamarin.Forms , , :
- (PCL ) NuGet- — Xamarin.FFImageLoading.Forms Xamarin.FFImageLoading.SVG.Forms;
- AppDelegate.cs iOS-:
public override bool FinishedLaunching( UIApplication app, NSDictionary options ) { global::Xamarin.Forms.Forms.Init(); FFImageLoading.Forms.Platform.CachedImageRenderer.Init(); CachedImageRenderer.InitImageSourceHandler(); var ignore = typeof(SvgCachedImage); LoadApplication(new App()); return base.FinishedLaunching(app, options); }
- MainActivity.cs Android-:
protected override void OnCreate( Bundle savedInstanceState ) { TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); FFImageLoading.Forms.Platform.CachedImageRenderer.Init(true); CachedImageRenderer.InitImageViewHandler(); var ignore = typeof(SvgCachedImage); LoadApplication(new App()); }
La bibliothèque implémente des appels à des ressources SVG situées à la fois dans des projets de plateforme et dans des projets EmbeddedResouce PCL. SvgCachedImage est utilisé pour afficher des images SVG. Contrairement au contrôle Image d'origine utilisé dans Xamarin.Forms et acceptant une ImageSource, SvgCachedImage fonctionne avec SvgImageSource.
xmlns:svg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
Vous pouvez le fournir de plusieurs manières:
- Spécifiez dans le fichier XAML le nom du fichier SVG situé dans les ressources du projet de la plateforme:
<svg:SvgCachedImage Source="question.svg" WidthRequest="100" HeightRequest="100"/>
- Spécifiez dans le fichier XAML le chemin d'accès complet au fichier SVG qui est une ressource incorporée dans le projet PCL:
<svg:SvgCachedImage Source="resource://SVGFormsTest.SVG.question1.svg" WidthRequest="100" HeightRequest="100"/>
Lors du chargement à partir de ressources incorporées, vous pouvez spécifier le nom d'un autre assembly:
resource://SVGFormsTest.SVG.question1.svg?assembly=[ASSEMBLY FULL NAME]
- Lorsque vous travaillez à partir de code, nous donnons d'abord un nom aux contrôles:
<svg:SvgCachedImage x:Name="image" WidthRequest="100" HeightRequest="100"/>
Ensuite, en fonction de la ressource utilisée, nous choisissons l'une des options:
- utiliser des ressources embarquées
image.Source = SvgImageSource.FromResource("SVGFormsTest.SVG.question1.svg");
-
image.Source = SvgImageSource.FromFile("question.svg");
- utiliser des ressources embarquées
- Binding 2 :
- , SvgImageSource. , XAML- :
<svg:SvgCachedImage Source="{Binding Source}" WidthRequest="100" HeightRequest="100"/>
- . , . :
<ContentPage.Resources> <ResourceDictionary> <svg:SvgImageSourceConverter x:Key="SourceConverter"/> </ResourceDictionary> </ContentPage.Resources>
:
<svg:SvgCachedImage Source="{Binding Source1, Converter={StaticResource SourceConverter}}" WidthRequest="100" HeightRequest="100"/>
:
public MainVM() { source1 = "question.svg"; } string source1; public string Source1 { get => source1; set { source1 = value; } }
:
public MainVM() { source1 = "resource://SVGFormsTest.SVG.question1.svg"; } string source1; public string Source1 { get => source1; set { source1 = value; } }
, . , , .
- , SvgImageSource. , XAML- :
SVG- , . , , , , , , SVG- . , PNG- , SVG, .
Les ressources SVG présentent également un inconvénient mineur. Ils ne peuvent pas être fournis en tant qu'icône d'application, car seuls les fichiers PNG et JPEG peuvent être utilisés comme icône conformément aux directives de Google et d'Apple.