小さな子ども向けの文字練習アプリ「もじのれんしゅう」を作る

2014年2月21日(金)
薬師寺 国安

[けす]ボタンがタップされた時の処理

認識された文字が表示されていた、非表示のTextBlock1の内容を空にします。
InkManagerクラスのModeプロパティで、インク入力モードをInkManipulationMode.Erasingに指定します。ストロークが削除モードになります。
InkManagerのGetStrokesメソッドで、InkManager の管理するコレクション内のすべての InkStroke オブジェクトを取得し、変数myStrokeに格納します。

InkStrokeのコレクションの数だけ繰り返し処理を行います。すべてのInkStrokeを選択状態にします。
DeleteSelectedメソッドで、選択されたInkStroke オブジェクトを InkManager の管理する InkStroke のコレクションから削除します。
Canvasの背景色をWhiteに指定し、Canvas内をクリアします。その後、InkManagerのModeをInkManipulationMode.Inkingに戻しておきます。
再びインクストロークが可能な状態になります。[よむといみ]と[けす]ボタンの使用を不可とします。

  Private Sub clearButton_Click(sender As Object, e As RoutedEventArgs) Handles clearButton.Click
    TextBox1.Text = String.Empty
    myInkManager.Mode = InkManipulationMode.Erasing
    Dim myStroke = myInkManager.GetStrokes
    For i As Integer = 0 To myStroke.Count - 1
      myStroke(i).Selected = True
    Next
    myInkManager.DeleteSelected()
    myCanvas.Background = New SolidColorBrush(Colors.White)
    myCanvas.Children.Clear()
    myInkManager.Mode = InkManipulationMode.Inking
    recognizeButton.IsEnabled = False
    clearButton.IsEnabled = False
  End Sub

[よむ]ボタンがタップされた時の処理

[けす]ボタンの使用を不可とします。
InkManagerのGetStrokesメソッドで、InkManager のを管理するコレクション内のすべての InkStroke オブジェクトを取得し、変数myStrokeに格納します。
InkStrokeのコレクションの数だけ繰り返し処理を行います。
すべてのInkStrokeを選択状態にします。

文字列変数myRecNameを「Microsoft 日本語手書き認識エンジン」と初期化しておきます。

英語の認識エンジンを使用する場合は「Microsoft English (US) Handwriting Recognizer」と指定します。

InkManagerのGetRecognizersメソッドで、手書き認識エンジンのコレクションを取得します。

取得したコレクションの数だけ反復処理を行います。変数myRecNameの値が、手書き認識エンジンのコレクションのNameと一致する場合は、その手書き認識エンジンを、SetDefaultRecognizerメソッドで規定値として設定します。「Microsoft 日本語手書き認識エンジン」が規定値に設定されます。
RecognizeAsyncメソッドで、 1つまたは複数のInkStrokeオブジェクトに対して手書き認識を実行します。
InkRecognitionTarget.Allで、ストロークコレクション内のすべてのストロークを認識エンジンに渡します。
UpdateRecognitionResultsメソッドで、潜在的なテキストのコレクションが、手書きの認識からマッチするよう更新します。

認識された手書きの結果テキストのコレクション内を反復処理しながら、以下の処理を行います。

InkRecognitionResult.GetTextCandidatesメソッドで、手書き認識と一致する可能性のある候補として識別された、文字列のコレクションを取得して、変数myTextに格納します。認識された文字列をTextBox1に表示します。このTextBox1は非表示になっています。

メンバー変数readingTextに、格納されている認識された文字が表示されているTextBlock1の値を格納します。
[けす]ボタンの使用を可能にし、音声で喋らすsyokoVoiceタスクを実行します。

非同期処理で行われますので、メソッドの先頭にAsyncを追加します。

  Private Async Sub recognizeButton_Click(sender As Object, e As RoutedEventArgs) Handles recognizeButton.Click
    clearButton.IsEnabled = False
    Dim myStroke = myInkManager.GetStrokes
    For i As Integer = 0 To myStroke.Count - 1
      myStroke(i).Selected = True
    Next
   
    Dim myRecName = "Microsoft English (US) Handwriting Recognizer" '"Microsoft 日本語手書き認識エンジン" 
    Dim myRecognizer = myInkManager.GetRecognizers
 
    For i As Integer = 0 To myRecognizer.Count - 1
      If myRecName = myRecognizer(i).Name Then
        myInkManager.SetDefaultRecognizer(myRecognizer(i))
      End If
    
    Next
 
    Dim result As IReadOnlyList(Of InkRecognitionResult) = Await myInkManager.RecognizeAsync(InkRecognitionTarget.All)
    myInkManager.UpdateRecognitionResults(result)
 
    Dim myAlternate = String.Empty
    For Each myResult In result
      Dim myText = myResult.GetTextCandidates
      myAlternate = myAlternate & " " & myText(0)
      TextBox1.Text = myAlternate
    Next
      readingText = TextBox1.Text
      clearButton.IsEnabled = True
      Await syokoVoice()
    End If
 
  End Sub

結果をキャラクタが音声で喋る処理

MediaElement型のmyMedia変数を宣言し、MediaElement1で初期化しておきます。
音声機能へのアクセスを提供する、新しいSpeechSynthesizerのインスタンス、synthオブジェクトを作成します。
SynthesizeTextToStreamAsyncメソッドで、指定した文字列から、音声出力を非同期に生成します。
SetSourceメソッドで、指定されたストリームおよびMIME型を使用してSourceプロパティを設定します。
Playメソッドで音声を再生します。
音声をどの言語で、どのような声で喋らすかは、SpeechSynthesizerのVoiceプロパティで参照できます。下記のURLを参照してください。
> SpeechSynthesizer.Voice | voice property
上記URLを見るとJapanese JA は性別が「Female」で、名前は「Haruka」という女性が読み上げるようです。

非同期処理で行われるため、メソッドの先頭にAsyncを追加します。

  Private Async Function syokoVoice() As Task
    Dim myMedia As MediaElement = Me.MediaElement1
    Dim synth = New Windows.Media.SpeechSynthesis.SpeechSynthesizer
    Dim stream = Await synth.SynthesizeTextToStreamAsync(readingText)
    myMedia.SetSource(stream, stream.ContentType)
    myMedia.Play()
  End Function
End Class

今回はここまでです。また次回の記事でお会いしましょう。

  • もじのれんしゅうアプリのサンプル

    『Windows 8.1+Visual Studio 2013によるWindows ストア・アプリ開発実例集』 第7回のサンプルプログラムです。
薬師寺国安事務所

薬師寺国安事務所代表。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メルマガ会員のサービス内容を見る

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