前回の記事「Windows 8.1ユニバーサルアプリ、Windows 10 UWPアプリのアイコン作成」で、 Inkscapeを使ってSVGファイルからアイコンの画像ファイルを作成していると書きました。
Windows 8.1ユニバーサルアプリ、Windows 10 UWPアプリのアイコン作成
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>
実行すると赤で囲んだシャッターボタンのように表示されます。
※Noun Projectに登録されたアイコン(Camera By Okan Benn, CY)を利用しています。
https://thenounproject.com/term/camera/1267
XAMLでのアイコンデータの作り方
このXAMLでの描画はパスの計算が大変なので、Inkscapeを使ってSVGファイルからXAMLデータへ変換しています。
まず、InkscapeでSVGファイルを開いて、ファイル>名前を付けて保存を実行します。
「ファイルの保存先の選択」ダイアログで、ファイルの種類に"Microsoft XAML (*.xaml)“を選択して、 ファイル名を指定して保存を押します。
XAML出力のオプションで"Silverlight互換のXAML"を選択してOKを押します。
作成された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で変換していますが、そのうちに手書きできるようになりたいですね。