読者です 読者をやめる 読者になる 読者になる

Xamarin 日本語情報

Xamarin(ザマリン) の代理店だったエクセルソフト田淵のブログです。主に Xamarin に関するエントリーをアップしていきます。(なるべく正しい有益な情報を掲載していきたいと考えていますが、このブログのエントリーは所属組織の公式見解ではありませんのでご注意ください)

Xamarin.Forms で SVG 画像を表示するには

こんにちは。エクセルソフトの田淵です。

AppleApp Store のバッジが SVG でしたので、Xamarin.Forms アプリで SVG 画像を表示する方法を調べました。

SVG Control Plugin for Xamarin.Forms

www.nuget.org

今回はこちらを使いました。残念ながら UWP には未対応です。

このプラグインでは、PCL プロジェクトに「Embedded Resource(埋め込みリソース)」として SVG 画像をコピーする必要があります。そのため、App StoreSVG を含む、以下の 3つを参照してみます。(下2つはプラグインのサンプルアプリで使われていたファイルで GitHub にうまく参照できなかったので、png 画像で表示しています。)

App Store

https://devimages.apple.com.edgekey.net/app-store/marketing/guidelines/images/badge-download-on-the-app-store.svg

Cool Mask

f:id:ytabuchi:20170324144157p:plain:w150

Tiger

f:id:ytabuchi:20170324144217p:plain:w600

動作イメージ

f:id:ytabuchi:20170324144351p:plain:w600

コード

サンプルプロジェクトをアップしました。

github.com

基本的には、以下の作者のページのやり方を見ながらやってみました。

github.com

画像をダウンロード

最初に必要な画像をダウンロードし、Visual Studio/Xamarin Studio の PCL プロジェクトに追加します。今回は Resources フォルダを作成し、AppStore.svgCoolMask.svgTiger.svg として保存しました。

プラグインインストール

NuGet から Xam.Plugins.Forms.Svg を追加します。

f:id:ytabuchi:20170324155919p:plain:w600

Init

作者の GitHub README にもあるように、Init() が必要です。

Xamarin.Forms.Init(); //platform specific init
SvgImageRenderer.Init();

各プロジェクトで Forms の Init の後に、SvgImageRenderer.Init(); を追加します。

C#

XAML は少し特殊な書き方なので、最初に C# からです。

var appStore = new SvgImage
{
    SvgPath = "SvgSample.Resources.AppStore.svg",
    SvgAssembly = typeof(App).GetTypeInfo().Assembly,
    WidthRequest = 135,
    HeightRequest = 40,
    HorizontalOptions = LayoutOptions.Center
};
var coolMask = new SvgImage
{
    SvgPath = "SvgSample.Resources.CoolMask.svg",
    SvgAssembly = typeof(App).GetTypeInfo().Assembly,
    WidthRequest = 100,
    HeightRequest = 100,
    HorizontalOptions = LayoutOptions.Center
};
var tiger = new SvgImage
{
    SvgPath = "SvgSample.Resources.Tiger.svg",
    SvgAssembly = typeof(App).GetTypeInfo().Assembly,
    WidthRequest = 300,
    HeightRequest = 300,
    HorizontalOptions = LayoutOptions.Center
};

Title = "SVG via CSharp";
Content = new ScrollView
{
    Padding = new Thickness(8),
    Content = new StackLayout
    {
        Children =
        {
            appStore,
            coolMask,
            tiger
        }
    }
};

SvgPath で PCL 内の画像のパスを指定して、SvgAssembly にはアプリ内のAssemblyを参照するように typeof(App).GetTypeInfo().Assembly を指定します。

XAML

Reflection を XAML で指定できないから(?)なのか、コードをバインドする形でファイルを参照します。

Assembly プロパティと、C# でも指定した各ファイルへのパスのプロパティを持つ ViewModel ファイルを作成します。

public Assembly SvgAssembly
{
    get { return typeof(App).GetTypeInfo().Assembly; }
}

public string AppStorePath
{
    get { return "SvgSample.Resources.AppStore.svg"; }
}
public string CoolMaskPath
{
    get { return "SvgSample.Resources.CoolMask.svg"; }
}
public string TigerPath
{
    get { return "SvgSample.Resources.Tiger.svg"; }
}

XAML でこの ViewModel をバインドして、その他の指定をしていきます。

アセンブリの参照が必要なので、今回は svgxmlns:svg="clr-namespace:SVG.Forms.Plugin.Abstractions;assembly=SVG.Forms.Plugin.Abstractions" を追加して、ViewModel を参照して <svg:SvgImage を使用します。

<ContentPage.BindingContext>
    <local:SvgPageXamlViewModel />
</ContentPage.BindingContext>
<ScrollView Padding="8">
    <StackLayout>
        <svg:SvgImage SvgPath="{Binding AppStorePath}"
                        SvgAssembly="{Binding SvgAssembly}"
                        WidthRequest="135"
                        HeightRequest="40"
                        HorizontalOptions="Center"/>
        <svg:SvgImage SvgPath="{Binding CoolMaskPath}"
                        SvgAssembly="{Binding SvgAssembly}"
                        WidthRequest="100"
                        HeightRequest="100"
                        HorizontalOptions="Center"/>
        <svg:SvgImage SvgPath="{Binding TigerPath}"
                        SvgAssembly="{Binding SvgAssembly}"
                        WidthRequest="300"
                        HeightRequest="300"
                        HorizontalOptions="Center"/>
    </StackLayout>
</ScrollView>

いかがですか

f:id:ytabuchi:20170324144351p:plain:w600

こんな感じで表示されます。

作者のページにも書いてありますが、Android で VectorGraphics のサポートライブラリがあり、今後 SVG に移行するのかな?という感じです。特に Android のアイコンは SVG でアニメーションするやつとかあるし。

Android のサポートライブラリを使った書き方も調べてみたいですね。

Xamarin.iOSSVG を表示する方法は @ticktackmobile さんがエントリーを書いてくださっているので参考にしてください。私が使ったライブラリではなく、NGraphics というライブラリを使用しています。

ticktack.hatenablog.jp

余談

<svg version="1.1" id="US_UK_Download_on_the" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     x="0px" y="0px" width="135px" height="40px" viewBox="0 0 135 40" enable-background="new 0 0 135 40" xml:space="preserve">
<g>
    <path fill="#A6A6A6" d="M130.197,40H4.729C2.122,40,0,37.872,0,35.267V4.726C0,2.12,2.122,0,4.729,0h125.468
      C132.803,0,135,2.12,135,4.726v30.541C135,37.872,132.803,40,130.197,40L130.197,40z"/>
    <path d="M134.032,35.268c0,2.116-1.714,3.83-3.834,3.83H4.729c-2.119,0-3.839-1.714-3.839-3.83V4.725
      c0-2.115,1.72-3.835,3.839-3.835h125.468c2.121,0,3.834,1.72,3.834,3.835L134.032,35.268L134.032,35.268z"/>

App Store バッジの SVG なんですが、最初の <path fill="#A6A6A6" が後ろの黒背景ですよね?色指定が灰色になっています。でも、Web では黒く表示される。Visual Studio でビルドした iOSAndroid アプリも黒く。でも、Xamarin Studio でビルドしたやつだけ灰色なんですよね… なんでだろう?

f:id:ytabuchi:20170324165915p:plain:w600

Xamarin 気になった方は

Visual Studio 2017 をインストールして触ってみてください。手順書は こちらのエントリー をご覧ください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)

Xamarin 有償トレーニング : XLsoft エクセルソフト

Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。

私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。おなじみの ReSharper (JetBrains)、 や Atlassian の JIRA, Confluence、Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。

以上です。