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

熊小屋日誌

Windows 10 UWPやXamarin, Python、mbed/NetMF/Arduino/Edison, Azureなどぼちぼちと。たまにPCや勉強会、セミナーなどの話題も

アプリのアイコン作成~InkscapeによるSVGからXAMLへの変換

前回の記事「Windows 8.1ユニバーサルアプリ、Windows 10 UWPアプリのアイコン作成」で、 Inkscapeを使ってSVGファイルからアイコンの画像ファイルを作成していると書きました。

blog.strawhat.net

Package.appxmanifestで指定するアイコンはビットマップ画像ファイル(PNGファイル)ですが、 アプリ中のボタンなどに表示するアイコン画像ではXAMLを使うこともできます。 以下のコードでは、ButtonのContentプロパティにCanvasを作成して、 そこにPath、Rectangle、Ellipseなどで図形を描画しています。

<Button x:Name="ShutterButton"
    Padding="0" Margin="0,0,20,0"
    MinHeight="10" MinWidth="10"
    HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
    HorizontalAlignment="Right" VerticalAlignment="Center"
    Click="ShutterButton_Click"
    BorderBrush="Transparent">
    <Button.Content>
        <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            Width="50" Height="50"
            Canvas.Left="0" Canvas.Top="0">
            <Canvas.RenderTransform>
                <MatrixTransform Matrix="8 0 0 8 0.8830807 11.011266"/>
            </Canvas.RenderTransform>
            <Path Fill="#FFE0E5E8" Data="M 2.45595 1.03022 3.052314 0.078134 c 0.603186 -0.10493 1.2365 -0.104199 1.90003 0.0021928 l 0.588648 0.930646 c 0.599937 -0.00869 1.02624 0.205231 1.05263 0.619185 l 0 3.41145 -5.18251 0 c -0.488429 0.254691 -0.948919 0.296679 -1.40705 0.00804 L 1.24e-6 1.5300181 c 0.180379 -0.330302 0.481444 -0.49452 0.903357 -0.492733 l 1.55258996 -0.00707 z"/>
            <Rectangle Canvas.Left="1.1696399" Canvas.Top="0.67375702" Width="1.1998301" Height="0.29429901" RadiusX="0.29651701" RadiusY="0.29651701" Fill="#FFE0E5E8"/>
            <Ellipse Canvas.Left="2.4" Canvas.Top="1.5" Width="3.3" Height="3.3" Fill="#FF000000"/>
            <Ellipse Canvas.Left="2.4" Canvas.Top="1.6" Width="3.2" Height="3.2" Fill="#FFE0E5E8"/>
            <Ellipse Canvas.Left="2.6" Canvas.Top="1.7" Width="2.9" Height="2.9" Fill="#FF000000"/>
            <Ellipse Canvas.Left="2.7" Canvas.Top="1.8" Width="2.7" Height="2.7" Fill="#FFE0E5E8"/>
            <Ellipse Canvas.Left="2.8" Canvas.Top="1.9" Width="2.5" Height="2.5" Fill="#FF000000"/>
            <Path Fill="#FF000000" Data="M 5.74411 2.88883 6.133375 2.944462 C 6.19055 3.068478 6.191931 3.24236 6.131015 3.370598 L 5.736877 3.458879 c 0.0428 -0.130594 0.045887 -0.453993 0.00723 -0.57005 z"/>
            <Ellipse Canvas.Left="0.5" Width="0.5" Canvas.Top="1.4" Height="0.4" Fill="#FF000000"/>
            <Rectangle Canvas.Left="1.41113" Canvas.Top="1.89463" Width="0.097079702" Height="2.8955801" RadiusX="0.138391" RadiusY="0.138391" Fill="#FF000000"/>
            <Rectangle Canvas.Left="3.11555" Canvas.Top="0.96305603" Width="1.81266" Height="0.102741" RadiusX="0.53049803" RadiusY="0.53049803" Fill="#FF000000"/>
            <Ellipse Canvas.Left="-1.2" Canvas.Top="-1.5" Width="8.8" Height="8.8" Fill="Transparent"
            Stroke="White" StrokeThickness=".3"/>
        </Canvas>
    </Button.Content>
</Button>

実行すると赤で囲んだシャッターボタンのように表示されます。

f:id:kumar:20151101090209p:plain

※Noun Projectに登録されたアイコン(Camera By Okan Benn, CY)を利用しています。

thenounproject.com

XAMLでのアイコンデータの作り方

このXAMLでの描画はパスの計算が大変なので、Inkscapeを使ってSVGファイルからXAMLデータへ変換しています。

まず、InkscapeでSVGファイルを開いて、ファイル>名前を付けて保存を実行します。

f:id:kumar:20151101091441p:plain

「ファイルの保存先の選択」ダイアログで、ファイルの種類に"Microsoft XAML (*.xaml)"を選択して、 ファイル名を指定して保存を押します。

f:id:kumar:20151101091447p:plain

XAML出力のオプションで"Silverlight互換のXAML"を選択してOKを押します。

f:id:kumar:20151101091451p:plain

作成されたXAMLファイルからCanvas要素を取り出してButtonのContentプロパティに指定します (上記の例では、Canvas要素の内容を手作業で調整しています)。

<?xml version="1.0" encoding="UTF-8"?>
<!--This file is compatible with Silverlight-->
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="8" Height="7.9999997" Canvas.Left="0" Canvas.Top="0">
  <Canvas.RenderTransform>
    <TranslateTransform X="0" Y="0"/>
  </Canvas.RenderTransform>
  <Canvas.Resources/>
  <!--Unknown tag: metadata-->
  <!--Unknown tag: sodipodi:namedview-->
  <Canvas Name="g8">
    <Canvas.RenderTransform>
      <TranslateTransform X="0.8008093" Y="1.5045462"/>
    </Canvas.RenderTransform>
    <Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path10" Fill="#FF1F1A17" Data="M 2.45595 1.03022 3.052314 0.078134 c 0.603186 -0.10493 1.2365 -0.104199 1.90003 0.0021928 l 0.588648 0.930646 c 0.599937 -0.00869 1.02624 0.205231 1.05263 0.619185 l 0 3.41145 -5.18251 0 c -0.488429 0.254691 -0.948919 0.296679 -1.40705 0.00804 L 1.24e-6 1.5300181 c 0.180379 -0.330302 0.481444 -0.49452 0.903357 -0.492733 l 1.55258996 -0.00707 z"/>
    <Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="1.1696399" Canvas.Top="0.67375702" Width="1.1998301" Height="0.29429901" RadiusX="0.29651701" RadiusY="0.29651701" Name="rect12" Fill="#FF1F1A17"/>
    <Ellipse xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="2.4" Canvas.Top="1.5" Width="3.3" Height="3.3" Name="circle14" Fill="#FFFFFFFF"/>
    <Ellipse xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="2.4" Canvas.Top="1.6" Width="3.2" Height="3.2" Name="circle16" Fill="#FF1F1A17"/>
    <Ellipse xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="2.6" Canvas.Top="1.7" Width="2.9" Height="2.9" Name="circle18" Fill="#FFFFFFFF"/>
    <Ellipse xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="2.7" Canvas.Top="1.8" Width="2.7" Height="2.7" Name="circle20" Fill="#FF1F1A17"/>
    <Ellipse xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="2.8" Canvas.Top="1.9" Width="2.5" Height="2.5" Name="circle22" Fill="#FFFFFFFF"/>
    <Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path24" Fill="#FFFFFFFF" Data="M 5.74411 2.88883 6.133375 2.944462 C 6.19055 3.068478 6.191931 3.24236 6.131015 3.370598 L 5.736877 3.458879 c 0.0428 -0.130594 0.045887 -0.453993 0.00723 -0.57005 z"/>
    <Ellipse xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="0.5" Width="0.5" Canvas.Top="1.4" Height="0.4" Name="ellipse26" Fill="#FFFFFFFF"/>
    <Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="1.41113" Canvas.Top="1.89463" Width="0.097079702" Height="2.8955801" RadiusX="0.138391" RadiusY="0.138391" Name="rect28" Fill="#FFFFFFFF"/>
    <Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="3.11555" Canvas.Top="0.96305603" Width="1.81266" Height="0.102741" RadiusX="0.53049803" RadiusY="0.53049803" Name="rect30" Fill="#FFFFFFFF"/>
  </Canvas>
</Canvas>

XAMLでアイコンを描画するメリットとしては、RenderTransformを使って拡大・縮小を実行したときに、ラスタ画像のPNGファイルと違って粗さが出る心配がない点が挙げられるかと思います。

なお、XAMLでのアイコン作成ですが、ぐらばくさんのようにBlendなどのツールを使って手書きすることもできます。 私はまだこの方法に慣れてないので専らInkscapeで変換していますが、そのうちに手書きできるようになりたいですね。

grabacr.net