タブレットPCの加速度センサーを使って目的の画像を直感的に探せるプログラムを作る
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト2 (MainWindow.xaml.vb)
サポートされているセンサーの種類と関連するモーションデータにアクセスできるようにするクラスの含まれる、Windows.Devices.Sensors名前空間をインポートします。
Imports Windows.Devices.Sensors
コンテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、Windows.UI.Popups名前空間をインポートします。
Imports Windows.UI.Popups
アプリケーションウインドウやウインドウ対話を作成し管理するサポートと、ウィンドウ上の入力イベントを処理するサポートを提供する、Windows.UI.Core名前空間をインポートします。
Imports Windows.UI.Core
ウインドウのUIに関する機能を提供するWindows.UI名前空間をインポートします。
Imports Windows.UI Public NotInheritable Class MainPage Inherits Page
タイマーを表すDispatcherTimerクラスのメンバ変数myTimerを宣言します。
Dim myTimer As DispatcherTimer
加速度センサーを表すAccelerometerクラスのメンバ変数myAccelerometerを宣言します。
Dim myAccelerometer As Accelerometer Dim no As Integer = 0 Dim myCount As Integer = 0
加速度計の読み取り結果を表すAccelerometerReadingクラスのメンバ変数myValueを宣言しNothingで初期化しておきます。
Dim myValue As AccelerometerReading = Nothing
ページがアクティブになった時の処理
新しいDispacherTimerのインスタンスmyTimerオブジェクトを作成します。
Intervalプロパティに1000ミリセコンド(1秒)を指定します。
AddHandlerステートメントで、指定したタイマーの間隔が経過し、タイマーが有効である場合に発生するTickイベントにmyTimer_Tickイベントハンドラを追加します。Startメソッドでタイマーを開始します。
Accelerometer.GetDefaultメソッドで、加速度センサーを既定の加速度計とします。
既定の加速度計が装備されていない場合は、警告メッセージを出して、処理を抜けます。装備されている場合は、AddHandlerステートメントで、加速度計が新しいセンサー読み取り結果を報告するたびに発生する、ReadingChangedイベントに、myAccelerometer_ReadingChangedイベントハンドラを追加します。
ピクチャライブラリにアクセスします。GetFilesAsyncメソッドでファイルを取得し、コレクション変数myPicturesに格納します。Countプロパティでファイルの個数を取得し、ファイルが無い場合は警告メッセージを発して処理を抜けます。ファイルがある場合は以下の処理を行います。
コレクション変数myPictures内のファイルを変数resultに格納しながら、以下の処理を繰り返します。
新しいBimapImageのインスタンスbmpオブジェクトを作成し、SetSourceメソッドに、
Await result.OpenSequentialReadAsync
と指定して、OpenSequentialReadAsyncメソッドで、ファイルの内容を読むために、現在のファイルの順次アクセスストリームを開き、BitmapSourceのソースイメージに設定します。
新しいImageのインスタンスmyImageオブジェクトを作成します。Stretch(コンテンツのサイズを変更して、割り当てられている領域を埋める方法)にNoneを指定し、Sourceプロパティにbmpオブジェクトを追加します。
新しいTextBlockのインスタンスfileNameTextBlockオブジェクトを作成します。
パディングに5、文字サイズに24、文字色にGold、Textプロパティに、GetFileNameメソッドでファイル名と拡張子の付いたファイル名を指定します。Result.Nameでフルパス付きのファイル名を取得しますので、GetFileNameメソッドを使って、ファイル名と拡張子だけのファイル名を取得しています。文字を中央揃えとします。
新しいStackPanelのインスタンスmyStackPanelオブジェクトを作成します。
AddメソッドでmyImage、fileNameTextBlockオブジェクトを追加します。このmyStackPanelオブジェクトをFlipView1にAddメソッドで追加していきます。PageTextBlock内に何枚中何枚目という表示を1/10・・・5/10といった形式で表示します。
Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) myTimer = New DispatcherTimer myTimer.Interval = TimeSpan.FromMilliseconds(1000) AddHandler myTimer.Tick, AddressOf myTimer_Tick myTimer.Start() myAccelerometer = Accelerometer.GetDefault If myAccelerometer Is Nothing = True Then Dim message As New MessageDialog("加速度センサーに対応しておりません。") Await message.ShowAsync Exit Sub Else AddHandler myAccelerometer.ReadingChanged, AddressOf myAccelerometer_ReadingChanged End If Dim myFolder = Windows.Storage.KnownFolders.PicturesLibrary Dim myPictures = Await myFolder.GetFilesAsync myCount = myPictures.Count If myCount = 0 Then Dim message As New MessageDialog("ピクチャライブラリ内に表示する画像がありません。") Await message.ShowAsync Exit Sub End If For Each result In myPictures Dim bmp As New BitmapImage bmp.SetSource(Await result.OpenSequentialReadAsync) Dim myImage As New Image myImage.Stretch = Stretch.None myImage.Source = bmp Dim fileNameTextBlock As New TextBlock With fileNameTextBlock .Padding = New Thickness(5) .FontSize = 24 .Foreground = New SolidColorBrush(Colors.Gold) .Text = Path.GetFileName(result.Name) .HorizontalAlignment = Xaml.HorizontalAlignment.Center End With Dim myStackPanel As New StackPanel myStackPanel.Children.Add(myImage) myStackPanel.Children.Add(fileNameTextBlock) FlipView1.Items.Add(myStackPanel) Next PageTextBlock.Text = (no + 1).ToString & "/" & myCount End Sub
加速度計が新しいセンサー読み取り結果を報告するたびに発生するイベント
最新の加速度計の読み取りを取得して、メンバ変数myValueで参照しておきます。
Private Sub myAccelerometer_ReadingChanged(sender As Accelerometer, e As AccelerometerReadingChangedEventArgs) myValue = e.Reading End Sub
指定したタイマーの間隔が経過し、タイマーが有効である場合に発生するイベント
加速度計に最新の値が無い場合は処理を抜けます。それ以外の場合は、以下の処理を行います。
x軸に沿った重力アクセラレータの絶対値が、y軸に沿った重力アクセラレータより小さい場合は処理を抜けます。つまりタブレットPCが水平に置かれた場合は処理を抜けるということです。
x軸に沿った重力アクセラレータの値が0より大きい場合、つまりタブレットPCが右に傾けられた場合の処理です。メンバ変数noの値が、ピクチャフォルダー内にあるファイルの個数より大きい場合は、メンバ変数noの値をmyCount-1で初期化して処理を抜けます。メンバ変数myCountにはピクチャフォルダー内の画像ファイルの個数が格納されています。メンバ変数noの値が、ピクチャフォルダー内にあるファイルの個数より小さい場合は、メンバ変数noの値を1ずつ増加させて、その値をFlipView1のSelectedIndexの値に指定します。これで、タブレットPCを右に傾けると、順次画像が表示されていき、最後まで表示されるとそこで止まります。
x軸に沿った重力アクセラレータの値が0より小さい場合、つまりタブレットPCが左に傾けられた場合の処理です。
メンバ変数noの値が0か0より小さい場合は、メンバ変数noの値を0で初期化し処理を抜けます。それ以外の場合は、メンバ変数noの値を1ずつ減算し、その値をFlipView1のSelectedIndexの値に指定します。前の画像が順次表示されていき、先頭の画像になったら表示を止めます。
pageTextBlock内に何枚目中何枚目の画像であるということを、1/10・・・・5/10の形式で表示します。
Private Sub myTimer_Tick(sender As Object, e As Object) If myValue Is Nothing = True Then Exit Sub Else If Math.Abs(myValue.AccelerationX) < Math.Abs(myValue.AccelerationY) Then Exit Sub Else If myValue.AccelerationX > 0 Then If no >= myCount - 1 Then no = myCount - 1 Exit Sub Else no += 1 FlipView1.SelectedIndex = no End If Else If no <= 0 Then no = 0 Exit Sub Else no -= 1 FlipView1.SelectedIndex = no End If End If End If End If PageTextBlock.Text = (no + 1).ToString & "/" & myCount End Sub End Class
アイコンの作成
詳細については、「自分の現在位置を取得して表示するサンプルプログラム」の記事を参照してください。
今回でWindows ストア・アプリのサンプル解説は一応終了です。長い間おつきあいありがとうございました。今回の連載が、皆様にとって、Windows ストア・アプリ作成のヒントとアイデアを生み出す要因になれば筆者としては嬉しいです。
では、またの機会にお会いしましょう。ありがとうございました。
タブレットPCを傾けて写真を直感的に探せるプログラム
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- 加速度センサーやジャイロスコープセンサーを使った、3つのセンサーサンプル
- ContextMenuコントロールを使う、加速度センサー、GPSでの位置情報取得
- GPSによる位置情報の取得と加速度センサー
- センサーとサウンドの処理を組み込んでアプリを完成させる
- センサーの範囲内にいる人間を見つけて撮影・保存するKinectサンプル
- キャラクターが音声で応援してくれる脳トレーニングアプリを作ってみよう
- 撮影した写真の管理ができるマイフォトアプリを作る
- 画面上を流れる数字を暗算して正解を求めるアプリを作ろう(その2)
- 制限時間内に指定した画像を見つけ出す脳トレーニングアプリを作ろう
- 選択した画像を拡大表示してアニメーションさせる+1つのサンプル