LINEで送る

前回、Windowsストアアプリで、ペンやタッチのイベントを取得する方法を紹介しましたが、そのイベントを利用し、線を描画する方法を紹介します。
今回は、タッチには反応せず、ペンにのみ反応する形となっています。

1.描画の開始
Pressedイベントでは、デバイスがペンかどうかを判別します。
ペンだった場合には、IDと座標を保存し、以降のイベントで利用します。

void InkCanvas_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    LogText.Text = "InkCanvas_PointerPressed ----------------------------------------- ";
    OutputPointerData(e);

    PointerPoint po = e.GetCurrentPoint(InkCanvas);
    if (po.PointerDevice.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Pen)
    {
        _PenID = po.PointerId;
        _PrevPoint = po.Position;
    }

    e.Handled = true;
}

2.描画処理の実装
描画の処理は、Movedイベントに実装します。
ここでは、1で取得したIDを利用し、該当のデバイスかどうかをチェックしています。
該当のデバイスだった場合には、以前の位置から移動しているかどうのチェックを行い、筆圧や消しゴムかどうかを取得して線を描画しています。

void InkCanvas_PointerMoved(object sender, PointerRoutedEventArgs e)
{
    LogText.Text = "InkCanvas_PointerMoved ------------------------------------------- ";
    OutputPointerData(e);

    if (e.Pointer.PointerId == _PenID)
    {
        PointerPoint po = e.GetCurrentPoint(InkCanvas);
        Point currentPoint = po.Position;

        if (GetPointDistance(_PrevPoint, currentPoint) > 0)
        {
            // 線の作成
            Line l = new Line();
            l.X1 = _PrevPoint.X;
            l.Y1 = _PrevPoint.Y;
            l.X2 = currentPoint.X;
            l.Y2 = currentPoint.Y;

            // 線を円形にする
            l.StrokeStartLineCap = PenLineCap.Round;
            l.StrokeEndLineCap = PenLineCap.Round;

            // 線の太さ 
            // 筆圧によって太さを変える
            l.StrokeThickness = MAX_STROKE_WIDTH * po.Properties.Pressure;

            // 線の色
            // 消しゴムの場合は白に変更する
            if (po.Properties.IsEraser)
            {
                l.Stroke = new SolidColorBrush(Colors.White);
            }
            else
            {
                l.Stroke = new SolidColorBrush(Colors.Black);
            }

            // 線を追加
            InkCanvas.Children.Add(l);

            // 現在の位置を保存する
            _PrevPoint = currentPoint;
        }
    }

    e.Handled = true;
}

MAX_STROKE_WIDTHは、線の最大の太さを定数で定義しています。
ペンの筆圧は、0~1の値となるので、MAX_STROKE_WIDTH * 筆圧で線の太さを決定しています。

ペンが動いたかどうかのチェックに利用しているGetPointDistanceメソッドは、以下のようにして、2点間の距離を取得しています。

// 2点間の距離
public double GetPointDistance(Point po1, Point po2)
{
    return Math.Sqrt(Math.Pow(po2.X - po1.X, 2) + Math.Pow(po2.Y - po1.Y, 2));
}

3.描画の終了
最後にReleasedイベントで、該当のデバイスが離されたかどうかをチェックします。
該当のデバイスだった場合には、保存していたIDを初期化し、描画を終了します。

void InkCanvas_PointerReleased(object sender, PointerRoutedEventArgs e)
{
    LogText.Text = "InkCanvas_PointerReleased ---------------------------------------- ";
    OutputPointerData(e);

    if (e.Pointer.PointerId == _PenID)
    {
        _PenID = 0;
    }

    e.Handled = true;
}

それでは、実際にアプリケーションを実行し、線を書いてみましょう。
筆圧に対応したペンで書いた場合、以下のスクリーンショットのように、筆圧によって線の太さが変わります。
また、消しゴムを利用した場合には、線が白で塗りつぶされます。

wsa_2_1

サンプルソースはこちらにアップしています。
興味のある方は、実際に試して頂ければと思います。

次回は、Windowsストアアプリでの文字認識についてご紹介します。

Top