Menggunakan Sumber Daya SVG di Xamarin

Saat mengembangkan aplikasi seluler, ada banyak hal yang perlu diperhatikan. Ini adalah pilihan teknologi yang akan digunakan untuk menulisnya, dan pengembangan arsitektur aplikasi, dan, pada kenyataannya, penulisan kode. Cepat atau lambat suatu saat akan tiba ketika tulang punggung aplikasi ada di sana, semua logika tertulis dan aplikasi, secara umum, berfungsi, tetapi ... tidak ada tampilan. Di sini perlu dipikirkan tentang sumber daya grafis yang akan digunakan, karena grafik merupakan bagian terbesar dari ukuran perakitan akhir, baik itu .apk di Android atau .ipa di iOS. Rakitan besar, pada prinsipnya, diharapkan untuk game seluler, bahkan sekarang dari PlayMarket terkadang Anda harus mengunduh volume data hingga 2 GB dan ada baiknya jika Anda dapat terhubung ke Wi-Fi selama mengunduh atau operator seluler menyediakan koneksi tanpa batas berkecepatan tinggi.Tetapi untuk game hal ini diharapkan, dan aplikasi bisnis sebesar ini secara tidak sengaja menimbulkan pertanyaan "Dari mana asalnya?". Salah satu alasan besarnya ukuran perakitan aplikasi bisnis adalah karena banyaknya ikon dan gambar yang harus ditampilkan di dalamnya. Dan juga jangan lupa bahwa sejumlah besar grafik secara proporsional mempengaruhi kinerja aplikasi.



Masalah serius sering muncul saat membuat komponen grafis dari suatu aplikasi. Ada banyak sekali perangkat seluler, dari jam tangan hingga tablet, dan resolusi layarnya sangat berbeda. Karena itu, sering kali diperlukan untuk menyertakan sumber daya grafik dalam rakitan di file terpisah untuk setiap tipe yang ada. 5 salinan untuk Android dan 3 untuk iOS. Ini secara signifikan mempengaruhi ukuran perakitan akhir yang akan Anda unggah ke toko.



Kami akan memberi tahu Anda apa yang bisa dilakukan agar tidak masuk ke situasi seperti itu di artikel ini.



Perbandingan format PNG dan SVG



Perbedaan utama antara format PNG dan SVG adalah PNG adalah format bitmap dan SVG adalah format vektor.



Bitmap adalah kotak piksel pada monitor dan digunakan di mana-mana, baik itu ikon kecil atau spanduk besar. Di antara keunggulan jenis grafik ini, berikut ini juga yang harus diperhatikan:



  1. Grafik raster memungkinkan Anda membuat gambar dengan hampir semua kerumitan, tanpa kehilangan ukuran file yang nyata;
  2. Jika skala gambar tidak diperlukan, kecepatan pemrosesan gambar yang kompleks sangat tinggi;
  3. Representasi gambar bitmap alami untuk sebagian besar perangkat I / O.


Namun, ada juga kerugiannya.



Misalnya, bitmap tidak dapat diskalakan dengan sempurna. Saat Anda memperbesar gambar kecil, gambar "berbusa" dan Anda dapat melihat piksel isinya.







Selain itu, gambar sederhana yang terdiri dari sejumlah besar titik berukuran besar. Oleh karena itu, disarankan untuk menyimpan gambar sederhana dalam format vektor. Semua hal di atas berlaku untuk PNG dan format grafis raster lainnya.

Format SVG sebenarnya bukanlah gambar. Menurut artikel wikipedia, SVG adalah bahasa markup grafik vektor yang dapat diskalakan yang memungkinkan Anda membaca dan mengedit file sesuai kebutuhan.



Selain itu, sebagai bahasa markup, SVG memungkinkan Anda menerapkan filter dalam dokumen (mis. Blur, bump, dll.). Mereka dideklarasikan sebagai tag yang penampil bertanggung jawab untuk rendering, yang berarti mereka tidak mempengaruhi ukuran file asli.



Selain di atas, format SVG memiliki beberapa keunggulan lain:



  1. Sebagai format vektor, SVG memungkinkan Anda menskalakan bagian mana pun dari gambar tanpa kehilangan kualitas;
  2. Grafik raster dapat dimasukkan ke dalam dokumen SVG;
  3. Mudah diintegrasikan dengan dokumen HTML dan XHTML.


Namun, ada juga kerugian dari format ini:



  1. Semakin banyak detail halus pada gambar, semakin cepat ukuran data SVG bertambah. Dalam beberapa kasus, SVG tidak hanya memberikan keuntungan, tetapi juga kalah dalam raster;
  2. Kompleksitas penggunaan dalam aplikasi kartografi, karena untuk tampilan yang benar dari sebagian kecil gambar, Anda perlu membaca seluruh dokumen.


Ada kerugian lain dalam kasus pengembangan aplikasi seluler di platform Xamarin.



Untuk bekerja dengan benar dengan format ini, Anda perlu menghubungkan pustaka tambahan, atau mencari solusi.



Bekerja dengan format SVG di Xamarin.Android



Seperti disebutkan di atas, Xamarin tidak mendukung SVG di luar kotak. Untuk mengatasi masalah ini - Anda dapat menggunakan pustaka pihak ketiga atau VectorDrawable. Baru-baru ini, pengembang semakin memilih yang terakhir, karena sebagian besar perpustakaan untuk Xamarin difokuskan pada penggunaan lintas platform di Xamarin. Formulir, dan solusi untuk Android asli tidak lagi didukung oleh pengembang mereka dan sudah ketinggalan zaman, atau ada masalah serius ketika mencoba membangun berdasarkan mereka perpustakaan untuk Xamarin. Dalam hal ini, di sini kami akan mempertimbangkan untuk menggunakan VectorDrawable.



Untuk menerapkan pendekatan ini, Anda perlu menggunakan Vector Asset Studio. Menemukannya cukup mudah, Anda hanya perlu Android Studio. Jadi, mari kita mulai:



  1. Android Studio File -> New -> New Project;

    , — Vector Asset Studio, .
  2. drawable -> New -> Vector Asset;



    Asset Studio. Material Design, SVG PSD, xml-. .
  3. Asset Studio



    ,  , .
  4. Next 



    Xamarin.Android.



Pekerjaan persiapan yang cukup yang membutuhkan penginstalan Android Studio. Sayangnya, pada saat penulisan ini, kami tidak dapat menemukan konverter online yang berfungsi dengan benar. Beberapa memberikan kesalahan saat mencoba mengonversi file SVG yang disediakan, beberapa menunjukkan bahwa lebih baik menggunakan Vector Asset Studio.



Bagaimanapun, kami mendapatkan file yang diperlukan dan sekarang kami dapat menggunakannya dalam proyek kami. Kami tidak akan menjelaskan proses pembuatan proyek Xamarin.Android, mari langsung ke intinya.

Pertama-tama, kami menempatkan file yang dihasilkan di folder drawable proyek, kemudian, sebagai demonstrasi bekerja dengan file ini, kami membuat 3 ImageView di layar.



kode di sini
<?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>




Di ImageView pertama, kami mencoba untuk menetapkan file SVG asli di properti android: src, di ImageView kedua, file XML yang dikonversi di properti yang sama, dan yang ketiga, di properti app: srcCompat (perhatikan bahwa namespace ini harus ditentukan seperti yang ditunjukkan dalam kode ).

Hasilnya sudah terlihat di desainer, sebelum aplikasi diluncurkan - satu-satunya cara pasti untuk menampilkan file kita dengan benar diberikan di ImageView ketiga.





Sekarang Anda perlu memastikan bahwa gambar ditampilkan dengan benar di perangkat yang berbeda. Sebagai perbandingan, kami memilih Huawei Honor 20 Pro dan Nexus 5. Dan juga, alih-alih metode tampilan yang salah, kami menentukan metode yang diinginkan dan mengubah ukuran ImageView menjadi 150x150 dp, 200x200 dp, dan 300x300 dp.



Hasil pekerjaan

Huawei Honor 20 Pro





Nexus 5







Seperti yang Anda lihat, kualitas gambarnya sama, artinya kami telah mencapai hasil yang diinginkan.



File yang dihasilkan digunakan dari kode dengan cara yang sama seperti biasa

image.SetImageResource(Resource.Drawable.< >);



Bekerja dengan format SVG di Xamarin.iOS



Dalam kasus Xamarin.iOS, situasinya sama dengan Xamarin.Android, dalam arti bahwa bekerja dengan file SVG tidak didukung di luar kotak. Namun dalam implementasinya tidak membutuhkan banyak tenaga. Dalam kasus pengembangan iOS asli, SVG memerlukan SVGKit untuk disertakan. Ini memungkinkan Anda untuk memproses file tersebut tanpa menggunakan solusi pihak ketiga. Dalam kasus Xamarin.iOS, kita dapat menggunakan library SVGKit.Binding . Ini adalah pembungkus C # di atas SVGKit asli.



Yang kami butuhkan hanyalah menghubungkan paket NuGet ke proyek kami. Pada saat penulisan ini, versi terbaru adalah 1.0.4.





Sayangnya, ternyata library ini sudah tidak didukung lagi, tetapi cukup cocok digunakan dalam proyek tersebut.

Di sini kelas SVGKImage (gambar SVG itu sendiri) dan SVGKFastImageView (kontrol untuk menampilkan gambar semacam itu) diimplementasikan.



kode untuk digunakan
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);
}


Untuk membuat SVGKImage, pustaka menerapkan dua opsi bergantung pada file BuildAction - BundleResource (dilambangkan dengan image_bundle_resource dalam kode) dan Konten (dilambangkan dengan image_content dalam kode).

Sayangnya, perpustakaan memiliki sejumlah kelemahan:



  1. SVGKFastImageView tidak mendukung inisialisasi tanpa menyediakan SVGKImage - kesalahan muncul yang menunjukkan perlunya menggunakan konstruktor yang disediakan dalam kode;
  2. Tidak ada cara untuk menggunakan file SVG di kontrol lain. Namun, jika ini tidak diperlukan, Anda dapat menggunakannya.


Hasil dari program




Jika aplikasi sangat penting untuk menggunakan file SVG tidak hanya di ImageView, Anda dapat menggunakan pustaka lain. Misalnya, FFImageLoading . Ini adalah pustaka hebat yang memungkinkan Anda tidak hanya untuk menurunkan gambar SVG di Xamarin.iOS UIImage asli, tetapi juga melakukannya secara langsung di kontrol yang diinginkan, menghemat waktu pengembangan. Ada juga fungsi untuk mengunduh gambar dari Internet, tetapi kami tidak akan mempertimbangkannya dalam artikel ini.



Untuk menggunakan pustaka, Anda perlu menghubungkan dua paket NuGet ke proyek - Xamarin.FFImageLoading dan Xamarin.FFImageLoading.SVG.





Dalam aplikasi pengujian kami, kami menggunakan metode yang memuat gambar SVG ke dalam UIImageView secara langsung dan menurunkan gambar ke dalam UIImage asli.



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




Ada juga metode di pustaka ini untuk mengganti representasi string SVG di UIImage, tetapi ini hanya masuk akal untuk file kecil.



Kode sampel
    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();




Perpustakaan juga memiliki sejumlah fungsi, tetapi kami tidak akan mempertimbangkannya di sini. Satu-satunya hal yang perlu disebutkan adalah bahwa pustaka ini dapat digunakan di proyek Xamarin.Android juga. Untuk digunakan dalam proyek Xamarin.Forms, ada analog dari perpustakaan ini, yang akan kita bahas di bawah ini.



Bekerja dengan format SVG di Xamarin.Forms



Pada umumnya, tidak perlu mencari pustaka untuk formulir, Anda cukup menyambungkan platform yang diketahui proyek dan butuh waktu lama dan suram untuk menulis ulang render untuk setiap kontrol yang ingin Anda gunakan. Untungnya, ada solusi yang akan kami bagikan.



Xamarin.FFImageLoading Xamarin.FFImageLoading.SVG, Xamarin.Forms (Xamarin.FFImageLoading.Forms Xamarin.FFImageLoading.SVG.Forms). Xamarin.Forms , , :



  1. (PCL ) NuGet- — Xamarin.FFImageLoading.Forms Xamarin.FFImageLoading.SVG.Forms;
  2. 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);
    }
  3. 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());
    }
    
Setelah itu, perpustakaan bisa digunakan.

Pustaka mengimplementasikan panggilan ke sumber daya SVG yang terletak di proyek platform dan proyek PCL EmbeddedResouce. SvgCachedImage digunakan untuk menampilkan gambar SVG. Tidak seperti kontrol Image asli yang digunakan di Xamarin.Forms dan menerima ImageSource, SvgCachedImage bekerja dengan SvgImageSource.



PENTING!
svg, , :



xmlns:svg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"




Anda dapat menyediakannya dengan beberapa cara:



  1. Tentukan dalam file XAML nama file SVG yang terletak di sumber daya proyek platform:

    <svg:SvgCachedImage
                Source="question.svg"
                WidthRequest="100"
                HeightRequest="100"/>
    
  2. Tentukan dalam file XAML jalur lengkap ke file SVG yang merupakan sumber daya tertanam dalam proyek PCL:



    <svg:SvgCachedImage
                Source="resource://SVGFormsTest.SVG.question1.svg"
                WidthRequest="100"
                HeightRequest="100"/>
    


    Saat memuat dari sumber daya yang disematkan, Anda dapat menentukan nama rakitan lain:



    resource://SVGFormsTest.SVG.question1.svg?assembly=[ASSEMBLY FULL NAME]
    
  3. Saat bekerja dari kode, pertama kita beri nama pada kontrol:



    <svg:SvgCachedImage
                x:Name="image"
                WidthRequest="100"
                HeightRequest="100"/>
    


    Kemudian, bergantung pada sumber daya mana yang digunakan, kami memilih salah satu opsi:



    • untuk menggunakan sumber daya tertanam

      image.Source = SvgImageSource.FromResource("SVGFormsTest.SVG.question1.svg");






    • image.Source = SvgImageSource.FromFile("question.svg");


  4. 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;
          }
      }
      


      , . , , .




SVG- , . , , , , , , SVG- . , PNG- , SVG, .



Sumber daya SVG juga memiliki kelemahan kecil. Mereka tidak dapat diberikan sebagai ikon aplikasi, karena hanya file PNG dan JPEG yang dapat digunakan sebagai ikon menurut pedoman Google dan Apple.




All Articles