見出し画像

C# SVGアイコンを使う

C#で使えるアイコンは基本的にPNG/BMP/JPG/Icoといったラスター画像で大きさや色を動的に変えるのは結構大変でした。コードで記述したりすると結構手間がかかっていました。
Web系だとSVG等のベクター画像が使えるので結構簡単です。調べたらSVG.NET(https://github.com/svg-net/SVG)ってライブラリ使うとかなり簡単に扱える事が分かったのでその健忘禄です。
githubにもまとめてあります。

SVGの利点

SVG自体はwikiを参照。

  • データが小さい。

  • 使えるアイコンがいっぱいある。GoogleIconsが有名です。

  • 大きさ・色の変更が楽。

  • Adobe Illustrator/Inkscapeで簡単に作成できる。

SVG.NETのインストール

Visual Studioの「ツール」メニューにある「ソリューションのNuGetパッケージの管理」を選んでSVGを検索すれば簡単にインストールできます。その他の必要な物も自動的にインストールされます。

SVGアイコンの準備

IllustratorやInkscapeで作ってもいいですが、お手軽にGoogleIconsからDLすしてます。

リソースへ登録

SVG.NETがstreamからのSVG読み込みが楽だったので、通常のプロパティからの登録ではない方法でリソースに登録します。
プロジェクトフォルダの中に"svg"フォルダを作成しDLしたsvgファイルを入れます。
ソリューションエクスプローラーで同じく"svg"てフォルダを作成し既存のファイルとしてsvgファイルを登録します。通常だと表示されないのですべてのファイルを選んでください。

登録したsvgファイルをすべて選択して、プロパティパネルの「ビルドアクション」を「埋め込みリソース」に変更します。これで

リソースのSVGファイルを表示させる。

using System.IO;
using System.Reflection;
using Svg;

private void loadSVG()
{
	//描画する画像
	m_bitmap = new Bitmap(base.Width, base.Height);
	Graphics g = Graphics.FromImage(m_bitmap);
	// 画像をクリア
	g.Clear(BackColor);
	//アセンブリを獲得
	var assembly = Assembly.GetExecutingAssembly();
	//読み込むアイコンのファイル名。
	// アセンブリのナームスペース.フォルダ名.ファイル名
	var resourceName = "MyNAMESPACE.svg.icon.svg";
	// streamで読み込む
	using (var stream = assembly.GetManifestResourceStream(resourceName))
	{
		if (stream != null)
		{
			//SvgDocumentに読み込む
			var doc = SvgDocument.Open<SvgDocument>(stream, new SvgOptions());
			// Fillカラーを設定
			doc.Fill = new SvgColourServer(ForeColor);
			//サイズを指定して描画
			Bitmap bm = doc.Draw(m_bitmap.Width, m_bitmap.Height);
			//目的のグラフィックに描画
			g.DrawImage(bm, 0, 0);
		}
	}
}

上記のコードは参考用でこのままでは動きませんが、読み込みの手順をわかりやすくコーディングされています。
GoogleIconsのモノカラーのアイコンなのでFillメンバーに描画色を設定するだけで簡単に色を変えられます。
Draw関数で大きさが指定できます。
SVGのアラーアイコンの場合はこんなに簡単には色は変えられません。

実際はgithubにあるIconBtn.csを見てください。

SvgDocumentのFill

IllustratorのSVGが上記のメンバで色替えできなかった。
GoogleIconsのSVGは

<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" 
fill="#e8eaed">

とSVGタグに書かれているが、Illustratorでは下記のようにStylesheetで指定されている。

  <path d="M3,27.2c-.5-.5-.9-1.1-1.2-1.9-.3-.8-.4-1.6-.4-2.4V6.9c0-.9.1-1.7.4-2.4.3-.7.7-1.3,1.2-1.8.5-.4,1-.7,1.6-.7h10.8c.6,0,1.1.2,1.6.7.5.4.9,1,1.2,1.8.3.7.4,1.6.4,2.4v16c0,.9-.1,1.7-.4,2.4-.3.8-.7,1.4-1.2,1.9-.5.5-1,.7-1.6.7H4.6c-.6,0-1.1-.2-1.6-.7ZM4.2,19.2L14.5,6.4H4.7c-.1,0-.2,0-.3.2,0,.1-.1.3-.1.5v12.2ZM5.4,23.4h9.9c.1,0,.2,0,.3-.2,0-.1.1-.3.1-.4v-12.2l-10.3,12.9Z" 
style="fill: #231815; stroke-width: 0px;"/>

書式がファイルごとに違うので、面倒だが手作業でSVGタグへFillをコピペして対処すればSvgDocument.Fillで色替えができるようになる。

SVGIcon.IconBtn/SVGIcon.IconBtnTable

上記の方法で作ったカスタムコントロールです。githubにあります。
内部画像にSVGを描画してからコントロール自体に描画しています。再描画のストレスを減らすため工夫をしているだけでごく簡単な機能を持ったボタンです。
DLLとして作成してあります。

この記事が気に入ったらサポートをしてみませんか?