タッチパネルを生かしてフリーハンドの文字を認識させるアプリを作ろう

2012年11月12日(月)
薬師寺 国安

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。

ロジックコードを記述する

リスト2 (MainWindow.xaml.vb)

Option Strict On

Windows 8のインクシステムをサポートするクラスの含まれる、Windows.UI.Input.Inking名前空間をインポートします。インクストロークを描画する場合等に、この名前空間に含まれるクラスを使用します。

Imports Windows.UI.Input.Inking

タッチ、スタイラス ・ ペン、マウス、およびキーボード デバイス等の入力をサポートするクラスの含まれる、Windows.UI.Input名前空間をインポートします。

Imports Windows.UI.Input

ポインター、タッチ、マウス、およびキーボードを識別し、それらのデバイスに関する情報を取得するクラスの含まれる、Windows.Devices.Input名前空間をインポートします。

Imports Windows.Devices.Input

図形に関するクラスの含まれる、Windows.UI.Xaml.Shapes名前空間をインポートします。

Imports Windows.UI.Xaml.Shapes

コア システムの機能と、その UI についてのランタイム情報にアクセスするアプリケーションを提供するクラスの含まれる、Windows.UI名前空間をインポートします。描くラインの色を指定する場合等に、この名前空間に含まれるクラスを使用します。

Imports Windows.UI

Public NotInheritable Class MainPage
  Inherits Page

ポインター入力位置のクライアント座標を取得して格納する、Point型のメンバ変数prevContactPointを宣言します(ポインターデバイスが開始された時のポインター入力位置)。Pointクラスは、2 次元の座標系の点をカプセル化するクラスです。

  Dim prevContactPoint As Point

入力、操作、および 1 つ以上の(手書きの認識を含む)の処理を管理するプロパティとメソッドを提供するクラスであるInkManagerクラスのインスタンスである、メンバ変数myInkManagerを宣言します。

  Dim myInkManager As New InkManager

入力ポインターの一意の識別子を取得して格納するメンバ変数myPenIDメンバ変数を宣言します。

  Dim myPenID As UInteger

ポインター入力位置のクライアント座標を取得して格納する、Pointクラス型のメンバ変数currentContactPointを宣言します(ポインターが移動した時のポインター入力位置)。

  Dim currentContactPoint As Point

ポインターデバイスが開始された時のX、Y座標(x1,y1)、ポインターが移動した時のX、Y座標(x2,y2)を格納するDouble型のメンバ変数を宣言しておきます。

  Dim x1 As Double
  Dim x2 As Double
  Dim y1 As Double
  Dim y2 As Double

ページがアクティブになった時の処理

初期状態では[文字認識]ボタンの使用は不可としておきます。

AddHandlerステートメントで、要素内で、プレスアクションを起こし、ポインターデバイスが開始された時に発生する、PointerPressedイベントに、myCanvas_PointerPressedイベントハンドラを追加します。

AddHandlerステートメントで、要素内で、ポインターが移動した時に発生する、PointerMovedイベントに、myCanvas_PointerMovedイベントハンドラを追加します。

AddHandlerステートメントで、要素内で、プレス アクションを開始したポインター デバイスが離された時に発生するPointerReleasedイベントに、myCanvas_PointerReleasedイベントハンドラを追加します。

AddHandlerステートメントで、要素の領域からポインターが離れた時に発生する、PointerExitedイベントに、myCanvas_PointerReleasedイベントハンドラを追加します。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    recognizeButton.IsEnabled = False
    AddHandler myCanvas.PointerPressed, AddressOf myCanvas_PointerPressed
    AddHandler myCanvas.PointerMoved, AddressOf myCanvas_PointerMoved
    AddHandler myCanvas.PointerReleased, AddressOf myCanvas_PointerReleased
    AddHandler myCanvas.PointerExited, AddressOf myCanvas_PointerReleased
  End Sub

要素内で、プレスアクションを起こし、ポインターデバイスが開始された時に発生するイベント

単一のマウス、ペン/スタイラス、またはタッチに関連付けられた入力のポインターを提供クラスである、PointerPoint型の変数myPointerを宣言し、GetCurrentPointメソッドで、Canvasの現在のポインターを取得します。PointerPointクラスのPositionプロパティで、ポインター入力の位置のクライアント座標を取得し、メンバ変数prevContactPointに格納します。

現在の、ポインターデバイスのPointerDeviceTypeを取得します。

ポインターデバイスのタイプが、ペン、またはマウス、またはタッチで、かつ、入力がマウスの左ボタン押下、またはその他の入力メソッドの左ボタン押下からであった場合の処理です。

〔文字認識〕ボタンの使用を可能にします。InkManagerクラスのProcessPointerDownメソッドで、Canvasの、初期の接触位置と圧力、および傾きなどの接触点の位置や機能に関する情報を処理します。InkManagerクラスは、入力、操作、および 1 つ以上の(手書きの認識を含む)の処理を管理するプロパティとメソッドを提供するクラスです。PointerIdで、入力ポインターの一意の識別子を取得して、メンバ変数myPenIDに格納しておきます。

  Private Sub myCanvas_PointerPressed(sender As Object, e As PointerRoutedEventArgs)
    Try
      Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
      prevContactPoint = myPointer.Position
      Dim myPointerDevType As PointerDeviceType = e.Pointer.PointerDeviceType
      If myPointerDevType = PointerDeviceType.Pen Or myPointerDevType = PointerDeviceType.Mouse Or myPointerDevType = PointerDeviceType.Touch And myPointer.Properties.IsLeftButtonPressed = True Then
        myInkManager.ProcessPointerDown(myPointer)
        myPenID = myPointer.PointerId
        e.Handled = True
      End If
    Catch
      Exit Sub
    End Try
  End Sub

要素内で、ポインターが移動した時に発生するイベント

イベントデータを提供するPointerIdが、入力ポインターの一意の識別子と同じである場合の処理です。

GetCurrentPointメソッドで、Canvasの現在のポインターを取得します。PointerPointクラスのPositionプロパティで、ポインター入力位置のクライアント座標を取得し、メンバ変数currentContactPointに格納します

メンバ変数x1に、ポインターデバイスが開始された時のX座標を指定します。メンバ変数y1にポインターデバイスが開始された時のY座標を指定します。メンバ変数x2に、要素内で、ポインターが移動した時のX座標を指定します。メンバ変数y2に、要素内で、ポインターが移動した時のY座標を指定します。

新しいLineのインスタンスmyLineオブジェクトを作成します。Line の始点の x 座標に変数x1の値を指定します。Line の始点の y 座標に変数y1の値を指定します。Line の終点の x 座標に変数x2の値を指定します。Line の終点の y 座標に変数y2の値を指定します。Lineの太さを5に指定し、ラインの色を赤に指定します。

要素内で、ポインターが移動した時の、Canvasの現在のポインターをメンバ変数prevContactPointに代入します。CanvasにAddメソッドでmyLineオブジェクトを追加します。InkManagerクラスのProcessPointerUpdateメソッドで、最後のイベントポインターから現在のポインターイベントまでの、圧力と傾きなどの、位置と状態プロパティを更新します。

  Private Sub myCanvas_PointerMoved(sender As Object, e As PointerRoutedEventArgs)
    If e.Pointer.PointerId = myPenID Then
      recognizeButton.IsEnabled = True
      Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
      currentContactPoint = myPointer.Position
      x1 = prevContactPoint.X
      y1 = prevContactPoint.Y
      x2 = currentContactPoint.X
      y2 = currentContactPoint.Y
  
        Dim myLine As New Line
        With myLine
          .X1 = x1
          .Y1 = y1
          .X2 = x2
          .Y2 = y2
          .StrokeThickness = 5
          .Stroke = New SolidColorBrush(Colors.Red)
        End With
        prevContactPoint = currentContactPoint
        myCanvas.Children.Add(myLine)
        myInkManager.ProcessPointerUpdate(myPointer)
      End If
    e.Handled = True
  End Sub
  • フリーハンドの文字を認識させるサンプルアプリ

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています