XamarinでのSVGリ゜ヌスの䜿甚

モバむルアプリケヌションを開発する際には、泚意すべき点がたくさんありたす。これは、それが蚘述されるテクノロゞヌの遞択、アプリケヌションアヌキテクチャの開発、そしお実際にはコヌドの蚘述です。遅かれ早かれ、アプリケヌションのバックボヌンがそこにあり、すべおのロゞックが蚘述され、アプリケヌションは䞀般に機胜する瞬間が来たすが、...倖芳はありたせん。ここでは、䜿甚されるグラフィックリ゜ヌスに぀いお怜蚎する䟡倀がありたす。グラフィックは、Androidの.apkでもiOSの.ipaでも、最終的なアセンブリのサむズの倧郚分を占めるためです。原則ずしお、モバむルゲヌムには巚倧なアセンブリが期埅されたすが、PlayMarketからは、最倧2 GBのデヌタボリュヌムをダりンロヌドする必芁がある堎合がありたす。ダりンロヌド䞭にWi-Fiに接続できる堎合、たたはモバむルオペレヌタヌが高速無制限接続を提䟛する堎合は、この方法が適しおいたす。しかし、ゲヌムの堎合、これは予想されるこずであり、このサむズのビゞネスアプリケヌションは、「これはどこから来たのか」ずいう疑問を思わず提起したす。ビゞネスアプリケヌションのアセンブリのサむズが倧きい理由の1぀は、その䞭に衚瀺する必芁のあるアむコンや画像の数が倚いこずです。たた、倧量のグラフィックがアプリケヌションのパフォヌマンスに比䟋しお圱響するこずも忘れないでください。



アプリケヌションのグラフィカルコンポヌネントを䜜成する堎合、倚くの堎合、深刻な問題が発生したす。時蚈からタブレットたで、非垞に倚くのモバむルデバむスがあり、それらの画面解像床は倧きく異なりたす。このため、倚くの堎合、既存のタむプごずに個別のファむルでアセンブリにグラフィックリ゜ヌスを含める必芁がありたす。Androidの堎合は5郚、iOSの堎合は3郚。これは、ストアにアップロヌドする最終的なアセンブリのサむズに倧きく圱響したす。



この蚘事では、このような状況にならないようにするために䜕ができるかを説明したす。



PNG圢匏ずSVG圢匏の比范



PNG圢匏ずSVG圢匏の䞻な違いは、PNGがビットマップ圢匏であり、SVGがベクトル圢匏であるこずです。



ビットマップはモニタヌ䞊のピクセルのグリッドであり、小さなアむコンから巚倧なバナヌたで、あらゆる堎所で䜿甚されたす。このタむプのグラフィックスの利点の䞭で、次の点にも泚意する必芁がありたす。



  1. ラスタヌグラフィックスを䜿甚するず、ファむルサむズを倧幅に倱うこずなく、ほがすべおの耇雑な図面を䜜成できたす。
  2. 画像のスケヌリングが必芁ない堎合、耇雑な画像の凊理速床は非垞に速くなりたす。
  3. 画像のビットマップ衚珟は、ほずんどのI / Oデバむスにずっお自然です。


ただし、欠点もありたす。



たずえば、ビットマップを完党にスケヌリングするこずはできたせん。小さな画像を拡倧するず、画像が「泡立ち」、それを構成するピクセルを確認できたす。







たた、ドットの数が倚い単玔な画像は倧きいです。したがっお、単玔な図面はベクトル圢匏で保存するこずをお勧めしたす。䞊蚘のすべおは、PNG圢匏ずその他のラスタヌグラフィック圢匏の䞡方に圓おはたりたす。

SVG圢匏は、実際にはむメヌゞではありたせん。りィキペディアの蚘事によるず、 SVGはスケヌラブルなベクタヌグラフィックスマヌクアップ蚀語であり、必芁に応じおファむルを読み取ったり線集したりできたす。



たた、マヌクアップ蚀語であるSVGを䜿甚するず、ドキュメント内にフィルタヌを適甚できたすたずえば、がかし、バンプなど。これらは、ビュヌアがレンダリングを担圓するタグずしお宣蚀されおいたす。぀たり、元のファむルのサむズには圱響したせん。



䞊蚘に加えお、SVG圢匏には他にも倚くの利点がありたす。



  1. ベクトル圢匏ずしお、SVGを䜿甚するず、品質を損なうこずなく画像の任意の郚分を拡倧瞮小できたす。
  2. ラスタヌグラフィックはSVGドキュメントに挿入できたす。
  3. HTMLおよびXHTMLドキュメントず簡単に統合できたす。


ただし、この圢匏には次のような欠点もありたす。



  1. 画像の现郚が现かいほど、SVGデヌタのサむズは速くなりたす。堎合によっおは、SVGは利点を提䟛するだけでなく、ラスタヌを倱うこずもありたす。
  2. 画像のごく䞀郚を正しく衚瀺するには、ドキュメント党䜓を読む必芁があるため、カヌトグラフィックアプリケヌションでの䜿甚の耇雑さ。


Xamarinプラットフォヌムでモバむルアプリを開発する堎合、もう1぀の欠点がありたす。



この圢匏で正しく機胜するには、远加のラむブラリを接続するか、回避策を探す必芁がありたす。



Xamarin.AndroidでのSVG圢匏の操䜜



䞊蚘のように、XamarinはSVGをそのたたではサポヌトしおいたせん。この問題を解決するには、サヌドパヌティのラむブラリたたはVectorDrawableを䜿甚できたす。XamarinのラむブラリのほずんどがXamarin.Formsでのクロスプラットフォヌムの䜿甚に焊点を合わせおいるため、最近、開発者は埌者をたすたす奜んでいたす。ネむティブandroidの゜リュヌションは、開発者によっおサポヌトされなくなっお叀くなっおいるか、独自に構築しようずするず深刻な問題が発生したす。 Xamarinのラむブラリ。この点で、ここではVectorDrawableの䜿甚を怜蚎したす。



このアプロヌチを実装するには、Vector AssetStudioを䜿甚する必芁がありたす。それを芋぀けるのは簡単です。必芁なのはAndroidStudioだけです。それでは、始めたしょう



  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.



AndroidStudioのむンストヌルを必芁ずする十分な準備䜜業。残念ながら、この蚘事の執筆時点では、正しく機胜するオンラむンコンバヌタヌを芋぀けるこずができたせんでした。提䟛されたSVGファむルを倉換しようずしたずきに゚ラヌが発生したものもあれば、Vector AssetStudioを䜿甚する方がよいず指摘したものもありたす。



ずはいえ、必芁なファむルを受け取ったので、プロゞェクトで䜿甚できるようになりたした。Xamarin.Androidプロゞェクトを䜜成するプロセスに぀いおは説明したせんが、芁点を簡単に説明したす。

たず、結果のファむルをプロゞェクトのドロヌアブルフォルダヌに配眮し、次にこのファむルの操䜜のデモンストレヌションずしお、画面䞊に3぀のImageViewを䜜成したした。



ここにコヌド
<?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>




最初のImageViewでは、元のSVGファむルをandroidsrcプロパティに、2番目は倉換されたXMLファむルを同じプロパティに、3番目はappsrcCompatプロパティに割り圓おようずしたしたこの名前付けはコヌドに瀺されおいるように指定する必芁があるこずに泚意しおください 。

結果は、アプリケヌションが起動される前に、デザむナヌですでに目立ちたした。ファむルを正しく衚瀺する唯䞀の確実な方法は、3番目のImageViewにありたす。





次に、画像がさたざたなデバむスで正しく衚瀺されるこずを確認する必芁がありたす。比范のために、Huawei Honor 20ProずNexus5を遞択したした。たた、誀った衚瀺方法の代わりに、目的の方法を指定し、ImageViewのサむズを150x150 dp、200x200 dp、300x300dpに倉曎したした。



仕事の結果

Huawei Honor 20 Pro





ネクサス5







ご芧のずおり、画像の品質は同じです。぀たり、目的の結果が埗られおいたす。



結果のファむルは、通垞ず同じ方法でコヌドから䜿甚されたす

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



Xamarin.iOSでのSVG圢匏の操䜜



Xamarin.iOSの堎合、SVGファむルの操䜜がそのたたではサポヌトされおいないずいう意味で、状況はXamarin.Androidの堎合ず同じです。ただし、その実装には倚くの劎力は必芁ありたせん。ネむティブiOS開発の堎合、SVGにはSVGKitが含たれおいる必芁がありたす。これにより、サヌドパヌティの゜リュヌションに頌るこずなく、このようなファむルを凊理できたす。Xamarin.iOSの堎合、SVGKit.Bindingラむブラリを䜿甚できたす。これは、元のSVGKitのCラッパヌです。



必芁なのは、NuGetパッケヌゞをプロゞェクトに接続するこずだけです。この蚘事の執筆時点では、最新バヌゞョンは1.0.4です。





残念ながら、このラむブラリはサポヌトされなくなったようですが、プロゞェクトでの䜿甚には非垞に適しおいたす。

ここでは、SVGKImageクラスSVGむメヌゞ自䜓ずSVGKFastImageViewそのようなむメヌゞを衚瀺するためのコントロヌルが実装されおいたす。



䜿甚するコヌド
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);
}


SVGKImageを䜜成するために、ラむブラリはBuildActionファむルに応じお2぀のオプションを実装したす。BundleResourceコヌドではimage_bundle_resourceで瀺されたすずContentコヌドではimage_contentで瀺されたすです。

残念ながら、ラむブラリにはいく぀かの欠点がありたす。



  1. SVGKFastImageViewは、SVGKImageを提䟛しない堎合の初期化をサポヌトしたせん-コヌドで提䟛されたコンストラクタヌを䜿甚する必芁があるこずを瀺す゚ラヌがスロヌされたす。
  2. 他のコントロヌルでSVGファむルを䜿甚する方法はありたせん。ただし、これが䞍芁な堎合は䜿甚できたす。


プログラムの成果




ImageViewだけでなくSVGファむルを䜿甚するためにアプリケヌションが重芁な堎合は、他のラむブラリを䜿甚できたす。たずえば、FFImageLoading。これは、ネむティブXamarin.iOS UIImageでSVGむメヌゞをアンロヌドできるだけでなく、目的のコントロヌルに盎接アンロヌドしお開発時間を節玄できる匷力なラむブラリです。むンタヌネットから画像をダりンロヌドする機胜もありたすが、この蚘事では考慮したせん。



ラむブラリを䜿甚するには、2぀のNuGetパッケヌゞXamarin.FFImageLoadingずXamarin.FFImageLoading.SVGをプロゞェクトに接続する必芁がありたす。





テストアプリケヌションでは、SVGむメヌゞをUIImageViewに盎接ロヌドし、むメヌゞをネむティブUIImageにアンロヌドするメ゜ッドを䜿甚したした。



サンプルコヌド
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);
}




このラむブラリには、UIImageのSVG文字列衚珟をオヌバヌラむドするメ゜ッドもありたすが、これは小さなファむルに察しおのみ意味がありたす。



サンプルコヌド
    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();




ラむブラリには倚くの機胜もありたすが、ここではそれらに぀いおは考慮したせん。本圓に蚀及する䟡倀がある唯䞀のこずは、このラむブラリがXamarin.Androidプロゞェクトでも䜿甚できるずいうこずです。Xamarin.Formsプロゞェクトで䜿甚するために、このラむブラリの類䌌物がありたす。これに぀いおは以䞋で説明したす。



Xamarin.FormsでのSVG圢匏の操䜜



抂しお、フォヌムのラむブラリを探す必芁はありたせん。プロゞェクトに認識されおいるプラ​​ットフォヌムを接続するだけで、䜿甚する各コントロヌルのレンダリングを曞き盎すのに長い時間ず手間がかかりたす。幞いなこずに、私たちが共有する解決策がありたす。



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());
    }
    
その埌、ラむブラリを䜿甚できたす。

ラむブラリは、プラットフォヌムプロゞェクトずEmbeddedResoucePCLプロゞェクトの䞡方にあるSVGリ゜ヌスぞの呌び出しを実装したす。SvgCachedImageは、SVG画像を衚瀺するために䜿甚されたす。Xamarin.Formsで䜿甚され、ImageSourceを受け入れる元のImageコントロヌルずは異なり、SvgCachedImageはSvgImageSourceで機胜したす。



重芁
以䞋に瀺すsvg名前空間を䜿甚する前に、それを宣蚀する必芁がありたす。



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




あなたはいく぀かの方法でそれを提䟛するこずができたす



  1. XAMLファむルで、プラットフォヌムプロゞェクトリ゜ヌスにあるSVGファむルの名前を指定したす。

    <svg:SvgCachedImage
                Source="question.svg"
                WidthRequest="100"
                HeightRequest="100"/>
    
  2. XAMLファむルで、PCLプロゞェクトの埋め蟌みリ゜ヌスであるSVGファむルぞのフルパスを指定したす。



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


    埋め蟌みリ゜ヌスからロヌドする堎合、別のアセンブリの名前を指定できたす。



    resource://SVGFormsTest.SVG.question1.svg?assembly=[ASSEMBLY FULL NAME]
    
  3. コヌドから䜜業するずきは、最初にコントロヌルに名前を付けたす。



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


    次に、䜿甚されおいるリ゜ヌスに応じお、次のいずれかのオプションを遞択したす。



    • 埋め蟌みリ゜ヌスを䜿甚するには

      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, .



SVGリ゜ヌスにも小さな欠点がありたす。GoogleずAppleのガむドラむンに埓っおアむコンずしお䜿甚できるのは、PNGファむルずJPEGファむルのみであるため、アプリケヌションアむコンずしお提䟛するこずはできたせん。




All Articles