Webカメラのデバイスの種類が選択された時の処理
メンバ変数cameraNoにcameraComboBoxより選択されたインデックス番号を格納しておきます。
AppBar1を表示状態にします。
MediaCaptureの新しいインスタンスmyMediaCaptureオブジェクトを作成します。
InitializeAsyncメソッドで、以下の内容でMediaCaptureオブジェクトを初期化します。
新しいMediaCaptureInitializationSettingsクラスのインスタンスを作成します。MediaCaptureInitializationSettingsクラスは、MediaCaptureオブジェクトの初期化設定をするクラスです。VideoDevideIdプロパティにcameraComboBoxより選択されたインデックスに対応する、コレクション変数myCameraのデバイスIDを指定します。
CaptureElement1のSourceプロパティにデバイスIDで初期化されたmyMediaCaptureを指定します。StartPreviewAsyncメソッドでプレビューを開始します。これで、Webカメラの画像が表示されます。
マウスの右クリックで表示されるshutterButton(Attach Cameraアイコン)の使用を可能にします。非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
01 | Private Async Sub cameraComboBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles cameraComboBox.SelectionChanged |
03 | cameraNo = cameraComboBox.SelectedIndex |
04 | AppBar1.Visibility = Xaml.Visibility.Visible |
05 | myMediaCapture = New MediaCapture |
06 | Await myMediaCapture.InitializeAsync(New MediaCaptureInitializationSettings With {.VideoDeviceId = myCamera(cameraComboBox.SelectedIndex).Id}) |
07 | CaptureElement1.Source = myMediaCapture |
08 | Await myMediaCapture.StartPreviewAsync |
09 | shutterButton.IsEnabled = True |
「Attach Camera」アイコンがタップされた時の処理
MediaElement1を再生します。つまりシャッター音が鳴ります。
ピクチャライブラリにアクセスし、CreateFolderAsyncメソッドで、ピクチャフォルダ内にImageDiaryというサブフォルダを作成します。その際、CreationCollisionOption.OpenIfExistsと指定しておくと、同名フォルダやファイルがある場合は、そのフォルダやファイル名を返し、ない場合は新規に作成してくれます。
CreateFileAsyncメソッドで現在の年月日時間分秒.jpgファイルを作成します。メンバ変数saveImageFileNameに、このjpgファイル名を格納しておきます。
イメージストリームの書式を表す新しい、ImageEncodingPropertiesクラスのインスタンス、myImageEncodingPropertyオブジェクトを作成します。書式のサブタイプを表すSubtypeプロパティにjpegを指定し、Widthに640、Heightに480と指定します。
CapturePhotoToStorageFileAsyncメソッドで、ストレージファイルにフォトをキャプチャします。書式は以下の通りです。
CapturePhotoToStorageFileAsync(ImageEncodingProperties,IStorageFile)
コレクション変数myPictureFilesにGetFilesAsyncメソッドで、ImageDiaryフォルダ内の画像ファイルを取得して格納します。
コレクション変数myPictureFilesが格納しているファイルの個数を、Countプロパティで取得して、メンバ変数Indexに格納します。
新しいBitmapImageクラスのインスタンスsaveBmpを作成します。SetSourceメソッドに
Await myPictureFiles(Index - 1).OpenReadAsync
と指定して、コレクション変数内のIndexに対応するファイルをOpenReadAsyncメソッドで開き、ソースイメージに指定します。Indexを-1しているのはコレクション変数myPictureFilesが格納しているファイルのインデックスが0から始まるためです。「Save」アイコンの使用を可能にします。
非同期処理で行われるためメソッドの先頭にAsyncを追加します。
01 | Private Async Sub shutterButton_Click(sender As Object, e As RoutedEventArgs) Handles shutterButton.Click |
04 | Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary |
05 | Dim mySubFolder = Await myFolder.CreateFolderAsync("ImageDiary", CreationCollisionOption.OpenIfExists) |
06 | Dim myFile As StorageFile = Await mySubFolder.CreateFileAsync(DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".jpg") |
07 | saveImageFileName = DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".jpg" |
08 | Dim myImageEncodingProperty As New ImageEncodingProperties |
09 | myImageEncodingProperty.Subtype = "jpeg" |
10 | myImageEncodingProperty.Width = 640 |
11 | myImageEncodingProperty.Height = 480 |
13 | AwaitmyMediaCapture.CapturePhotoToStorageFileAsync(myImageEncodingProperty, myFile) |
14 | myPictureFiles = Await mySubFolder.GetFilesAsync() |
15 | Index = myPictureFiles.Count |
16 | saveBmp = New BitmapImage |
17 | saveBmp.SetSource(Await myPictureFiles(Index - 1).OpenReadAsync) |
18 | Image1.Source = saveBmp |
19 | saveButton.IsEnabled = True |
「Save」アイコンがタップされた時の処理
コメント欄が未入力の場合は、警告メッセージを発して処理を抜けます。
それ以外の場合は、ピクチャライブラリのImageDiaryXMLサブフォルダにアクセスします。
XMLを作成して変数saveXmlに格納します。作成するXMLは、ルート要素がで、その子要素として、があり、 要素の子要素として、、、要素があります。
各要素の内容は、Visual Basicの埋め込み式を用いています。埋め込み式の構文はで、ASP.NET で使用される構文と同じです。要素の内容には埋め込み式で、saveImageFileNameの値を、要素には、commentTextBox.Textの値を、には、myLatitudeの値を、には、myLongitudeの値を指定します。
XElement.Parseメソッドで、作成したXMLを文字列として読み込みます。読み込んだXMLを変数resultXmlに格納します。
ImageDiaryXMLフォルダに、CreateFileAsyncメソッドで、saveImageFileName変数が格納している画像ファイル名から、20文字分取りだして、文字列「.xml」と連結したXMLファイルを作成し、変数myXmlFileで参照しておきます。
OpenAsyncメソッドで、読み込みと書きこみモードでmyXmlFileが参照しているファイルを開き、myStreamで参照します。
データをストリームに書きこむ、myStreamで初期化された新しいインスタンス、writerを作成します。
エンコードにUTF-8を指定し、WriteStringメソッドで、出力ストリームにresultXmlの内容を書きこみます。
StoreAsyncメソッドで、ストアにバッファのデータをコミットします。
文字列型の新しいリストである、xmlFileListオブジェクトを作成します。ImageDiaryXml内のファイルを、GetFilesAsyncで取得して、コレクション変数myXmlFileNameに格納します。
XMLファイルが存在する場合は、コレクション変数myXmlFileName内を、変数resultで反復しながら、以下の処理を繰り返します。
Addメソッドで、取得したファイル名から、パスと拡張子を除いたファイル名を取り出し、それに、文字列「.xml」を連結して、xmlFileListオブジェクトに追加していきます。
fileListBoxのItemsSourceプロパティにxmlFileListオブジェクトを指定します。ListBoxに保存したXMLファイルが追加されます。
Folderアイコンの使用を可能にし、Saveアイコンの使用を不可とします。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
01 | Private Async Sub saveButton_Click(sender As Object, e As RoutedEventArgs) Handles saveButton.Click |
02 | If commentTextBox.Text = String.Empty Then |
03 | Dim message As New MessageDialog("何かコメントを入力してください。") |
04 | Await message.ShowAsync |
07 | Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary |
08 | Dim mySubFolder = Await myFolder.CreateFolderAsync("ImageDiaryXML", CreationCollisionOption.OpenIfExists) |
09 | Dim saveXml As XElement = <ImageDiary><Info><ImageName><%= saveImageFileName %></ImageName><Comment><%= commentTextBox.Text %></Comment><Latitude><%= myLatitude %></Latitude><Longitude><%= myLongitude %></Longitude></Info></ImageDiary> |
10 | Dim saveXmlDoc As XElement = XElement.Parse(saveXml.ToString) |
11 | Dim resultXml As String = saveXmlDoc.ToString |
12 | Dim myXmlFile As StorageFile = Await mySubFolder.CreateFileAsync(saveImageFileName.Substring(0, 20) & ".xml", CreationCollisionOption.ReplaceExisting) |
14 | Using myStream As IRandomAccessStream = Await myXmlFile.OpenAsync(FileAccessMode.ReadWrite) |
15 | Dim writer As DataWriter = New DataWriter(myStream) |
16 | writer.UnicodeEncoding = UnicodeEncoding.Utf8 |
17 | writer.WriteString(resultXml) |
18 | Await writer.StoreAsync |
21 | Dim xmlFileList As New List(Of String) |
22 | Dim myXmlFileName = Await mySubFolder.GetFilesAsync |
23 | If myXmlFileName.Count > 0 Then |
24 | For Each result In myXmlFileName |
25 | xmlFileList.Add(Path.GetFileNameWithoutExtension(result.Path) & ".xml") |
28 | fileListBox.Items.Clear() |
30 | fileListBox.ItemsSource = xmlFileList |
31 | ichiranButton.IsEnabled = True |
32 | saveButton.IsEnabled = False |
ListBoxからXMLファイルが選択された時の処理
AppBarを非表示にし、ブール型メンバ変数をTrueで初期化します。この値を元に戻る(←)アイコンがタップされた時、どこに戻るかを決定します。
Frameを表示状態にし、ListBoxから選択されたXMLファイル名を変数mySelectedFileに格納します。
Image1を非表示にします。
FrameのNavigateメソッドで、mySelectedFileを引数にDataShowPageに遷移します。
エラーが発生した場合は、Frameを非表示にし、AppBarとImageを表示状態にします。
01 | Private Sub fileListBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles fileListBox.SelectionChanged |
02 | AppBar1.Visibility = Xaml.Visibility.Collapsed |
05 | myFrame.Visibility = Xaml.Visibility.Visible |
06 | Dim mySelectedFile As String = fileListBox.SelectedItem.ToString |
07 | Image1.Visibility = Xaml.Visibility.Collapsed |
08 | myFrame.Navigate(GetType(DataShowPage), mySelectedFile) |
10 | myFrame.Visibility = Xaml.Visibility.Collapsed |
11 | AppBar1.Visibility = Xaml.Visibility.Visible |
12 | Image1.Visibility = Xaml.Visibility.Visible |
戻る(←)アイコンがタップされた時の処理
各表示を以下の状態にします。
- CaptureElementを表示状態にします。
- cameraComboBoxを表示状態にします。
- AppBarを表示状態にします。
- myFrameを非表示にします。
- Image1を表示状態にします。
- CommentTextBox内を空にします。
ブール型メンバ変数がTrueの場合は、DataShowプロシージャを実行して、flagをFalseで初期化します。それ以外は、flagをFalseで初期化し、処理を抜けます。
01 | Private Sub backButton_Click(sender As Object, e As RoutedEventArgs) Handles backButton.Click |
02 | CaptureElement1.Visibility = Xaml.Visibility.Visible |
03 | cameraComboBox.Visibility = Xaml.Visibility.Visible |
04 | AppBar1.Visibility = Xaml.Visibility.Visible |
05 | AppBar1.IsEnabled = True |
06 | myFrame.Visibility = Xaml.Visibility.Collapsed |
07 | Image1.Visibility = Xaml.Visibility.Visible |
08 | Image1.Source = Nothing |
09 | commentTextBox.Text = String.Empty |
「Folder」アイコンがタップされた時の処理
CaptureElementを非表示に、cameraComboBoxを非表示に、myFrameを表示状態に、AppBarを非表示とします。
myFrameのNavigateメソッドでDataIchiranShowPageに遷移します。何も値は渡さないのでNothingを指定しておきます。
1 | Private Sub ichiranButton_Click(sender As Object, e As RoutedEventArgs) Handles ichiranButton.Click |
2 | CaptureElement1.Visibility = Xaml.Visibility.Collapsed |
3 | cameraComboBox.Visibility = Xaml.Visibility.Collapsed |
4 | myFrame.Visibility = Xaml.Visibility.Visible |
5 | AppBar1.Visibility = Xaml.Visibility.Collapsed |
6 | myFrame.Navigate(GetType(DataIchiranShowPage), Nothing) |
Geolocatorの機能が変更された時に発生する処理
Geolocatorオブジェクトの更新後の状態を、変数positionStatusで参照します。
Select Case文で条件分岐を行います。場所データを提供するGeolocatorオブジェクトがDisabledであった場合、つまり、場所プロバイダーが無効であった場合は、RunAsyncメソッドでディスパッチされたイベントの結果を非同期に返します。ディスパッチャの優先順位は標準のNormalを指定しています。
この場合は、「位置情報を取得できません。GPSおよび位置情報取得可能なPCでお試しください。」というメッセージボックスを表示させ、「Attach Camera」アイコンの使用を不可として、処理を抜けます。それ以外の場合は、「Attch Camera」アイコンの使用を可能にします。
非同期で行われるためメソッドの先頭にAsyncを追加します。
01 | Private Async Sub myGeolocator_StatusChanged(sender As Geolocator, args As StatusChangedEventArgs) |
02 | Dim positionStatus = args.Status |
03 | Select Case positionStatus |
04 | Case Windows.Devices.Geolocation.PositionStatus.Disabled |
05 | Await myCoreDispacher.RunAsync(CoreDispatcherPriority.Normal, Async Sub() |
07 | Dim message As New MessageDialog("位置情報を取得できません。GPSおよび位置情報取得可能なPCでお試しください。") |
08 | Await message.ShowAsync |
09 | shutterButton.IsEnabled = False |
13 | Await myCoreDispacher.RunAsync(CoreDispatcherPriority.Normal, Sub() |
14 | shutterButton.IsEnabled = True |
次に、ソリューションエクスプローラー内のDataShowPage.xamlを展開して表示される、DataShowPage.xaml.vbをダブルクリックしてリスト5のコードを記述します。
ロジックコードを記述する
リスト5 (DataShowPage.xaml.vb)
ファイル、フォルダおよびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。
Bing Mapsに関するクラスの含まれるBing.Maps名前空間をインポートします。
図形を定義するクラスの含まれる、Windows.UI.Xaml.Shapes名前空間をインポートします。
1 | Imports Windows.UI.Xaml.Shapes |
オブジェクトのUIをサポートする機能の含まれる、Windows.UI名前空間をインポートします。
最新のHTTPアプリケーション用のプログラミング インターフェイスを提供するクラスの含まれる、System.Net.Http名前空間をインポートします。
3 | Imports Windows.UI.Popups |
シーケンシャルアクセスストリームおよびランダムアクセスストリームに対する読み取りと書きこみのサポートを提供するクラスの含まれる、Windows.Storage.Streams名前空間をインポートします。
1 | Imports Windows.Storage.Streams |
3 | Public NotInheritable Class DataShowPage |
文字列型の定数メンバ変数を宣言し、YahooのアプリケーションIDで初期化します。
1 | Const AppID As String = "YahooのアプリケーションID" |
3 | Dim myLatitude As String |
4 | Dim myLongitude As String |
5 | Dim myImageFile As String |
7 | Dim delXmlFile As String |