当ブログは移転しました。

Win2Dでお絵かきプログラミング

はじめに

僕は普段、簡単なプログラミングにはProcessingを使っている。
java使えるし、見た目のあるアプリケーションを簡単に開発できるので気に入っている。
ところで、最近WindowsAPIを使って開発したいものがあった。こういうものはVisualStudioを使ってC#で作るのがよい。

さて、WindowsGUI開発にはいくつか種類があって、「フォームアプリケーション」とかWPFとかUWPとかある。
新しいのがUWPで、センサーの値を拾ったりするのが簡単である。見た目の部分はxamlを使って描くらしい。
GUIの部品はある程度用意されており、デザイナーの使い勝手もとてもいい。ただ前述のとおりProcessingが好きな僕は、できればUWPでも簡単に図形を描画したりしたい。

そんな願いを叶えてくれるのが、Microsoftが出している(!)Win2Dというライブラリである。 簡単に説明すると、DirectXのラッパーである。

導入

「ファイル」→「新規作成」→「プロジェクト」から「空のアプリケーション」を選択。

f:id:salmon2073:20160314115327p:plain

新しいプロジェクトが開いたら、「ツール」→「NuGetパッケージマネージャー」→「ソリューションのNuGetパッケージの管理」と進み、 「参照」タブを選択。検索バーにwin2dと入力するといくつか候補が出てくる。 赤いアイコンのやつがうまく動いてくれるので、win10の人は基本的に「Win2D.uwp」を選択してインストール。プロジェクト作成時に(Windows8.1)と表示された人は「Win2D.wiin81」を選択しよう。

f:id:salmon2073:20160314120116p:plain

Win2dの初期設定

公式ドキュメントに使い方が載っている。

Introduction

MainPage.xamlのPageタグの中に以下の文を書き込み、

xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"

Gridタグの中に以下の文を書き込めばよい。

<canvas:CanvasControl Draw="CanvasControl_Draw" ClearColor="White" Loaded="CanvasControl_Loaded"/>

MainPage.xaml.csにセットアップ用のメソッドと描画用のメソッドを実装する。 最低限動くコードは以下の通り。

using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.UI.Xaml;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App2
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void CanvasControl_Loaded(object sender, RoutedEventArgs e) {

        }

        private void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args) {
            CanvasDrawingSession d = args.DrawingSession;
            /*ここに描画命令を書く*/
        }
    }
}

プロセッサアーキテクチャが云々言われたらAnyCPUから他のものに変えよう。 ここまでくるとprocessingとそっくりなので書きやすい。

図形の描画

argsからDrawingSessionを取り出して描画命令を呼び出す。 簡単な命令をいくつか。

using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Text;
using Microsoft.Graphics.Canvas.UI.Xaml;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App2 {
    public sealed partial class MainPage : Page {
        public MainPage() {
            this.InitializeComponent();
        }

        private void CanvasControl_Loaded(object sender, RoutedEventArgs e) {

        }

        private void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args) {
            CanvasDrawingSession d = args.DrawingSession;
            d.FillRectangle(250, 250, 700, 400, Color.FromArgb(50, 100, 50, 250));
            d.DrawEllipse(450, 450, 200, 200, Color.FromArgb(100, 100, 100, 255));
            d.FillEllipse(750, 450, 200, 200, Color.FromArgb(100, 100, 100, 255));
            CanvasTextFormat f = new CanvasTextFormat();
            f.FontSize = 30;
            d.DrawText("Hello World!", 370, 430, Color.FromArgb(200, 255, 255, 255),f);
        }
    }
}

実行するとこんな感じ

f:id:salmon2073:20160314134044p:plain

そういえば、ウィンドウの縦横情報を取得する方法が分からなくて困った。こんな感じに取得できる。

var width = sender.Size.Width;
var hight = sender.Size.Height;

アニメーションをつくる

Introductionのコードは静止したスケッチを描くようなので、アニメーションをしようと思ったらcanvasを以下のように書き換える。

<canvas:CanvasAnimatedControl x:Name="canvas" Draw="canvas_DrawAnimated" ClearColor="White"  CreateResources="canvas_CreateResources"/>

コードのほうも少し変える。

using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.UI;
using Microsoft.Graphics.Canvas.UI.Xaml;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App3 {
    public sealed partial class MainPage : Page {
        public MainPage() {
            this.InitializeComponent();
        }

        private void canvas_Loaded(object sender, RoutedEventArgs e) {

        }

        private void canvas_CreateResources(CanvasAnimatedControl sender, CanvasCreateResourcesEventArgs args) {

        }

        private void canvas_DrawAnimated(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args) {
            CanvasDrawingSession d = args.DrawingSession;
        }
    }
}

おわりに

意外と日本語の情報が少なかった。 本来はもっといろんなCG処理を描けるものらしいので、気が向いたらやってみる。