カメラでクラウディア(Webカメラと画像を合成保存):2カ月で160本作った還暦開発者が送る10のアプリ開発ノウハウ(1)(4/5 ページ)
古(いにしえ)からのVBでWindows 8.1向けのさまざまな機能のアプリを開発する手順やコツを解説していく。初回は、Webカメラの映像と画像を合成保存する方法と一覧表示について。
空白のページを作成してコントロールを配置して画像一覧画面にする(ImageIchiranPage.xaml)
VS2013のメニューから、[プロジェクト(P)]→[新しい項目の追加(W)]と選択し、表示される「新しい項目の追加」画面で、左のWindows ストアを選択し、右の欄から「空白のページ」を選択する。「名前(N)」には「ImageIchiranPage.xaml」と指定し、[追加(A)]ボタンをクリックする(図14)。ImageIchiranPage.xamlは保存した画像を一覧するページだ。
ツールボックスからデザイン画面上にコントロールを配置する。書き出されるXAMLをリスト4のように編集する。
<Page
x:Class="CameraWithClaudia.ImageIchiranPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CameraWithClaudia"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Viewbox>■(1)
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer HorizontalScrollBarVisibility="Visible" Margin="10">■(2)
<GridView x:Name="GridView1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="1336" FlowDirection="LeftToRight" Height="699" />■(2)
</ScrollViewer>■(2)
<AppBar Height="110" Background="Gray" Margin="0,668,-10,0">■(3)
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Height="100">■(3)
<AppBarButton x:Name="deleteButton" Label="削除" Icon="Delete" ClickMode="Press" Margin="10" Height=”110”/>■(3)
<AppBarButton x:Name="AlldeleteButton" Label="一括削除" Icon="Delete" ClickMode="Press" Margin="10" Height=”110”/>■(3)
</StackPanel>■(3)
</AppBar>■(3)
</Grid>
</Viewbox>■(1)
</Page>
以上、全てをレイアウトしたのが図15だ。
以降は、ソースコードに割り振った番号ごとに詳細に見ていこう。
(1)
Grid要素全体をViewBox要素で囲む。
(2)
ScrollViewer要素を配置し、その子要素として名前が「GridView1」というGridView要素を配置する。この中に保存された画像の一覧が表示される。ScrollViewer要素の子要素であるため、横にスクロールが可能だ。
(3)
AppBar要素を配置し、背景色にGrayを指定する。AppBar要素の子要素として、[Orientaion]プロパティに水平方向を表す「Horizontal」を指定したStackPanel要素を配置し、その子要素として、名前が「deleteButton」と「allDeleteButton」というAppBarButton要素を配置する。
プロパティから「Symbol」に「Delete」を選択し、「Label」に「削除」と「一括削除」と指定する。AppBar要素は、マウスの右クリックで表示されるアプリケーションバーだ。表示された時に、アプリケーションバー内に[削除]アイコンと、[一括削除]アイコンが表示される。
メイン画面のロジックコード(MainWindow.xaml.vb)
次に、[ソリューション・エクスプローラー]内のMainWindow.xamlを展開して表示される、「MainWindow.xaml.vb」のコードを記述する。
ここでは、コードが長くなるため今回のテーマと肝となる「画像の合成」「データの一覧表示」部分の解説にとどめている。名前空間の読み込み、メンバー変数の宣言も省略している。全てのコードを見る場合は、サンプルをダウンロードして「MainWindow.xaml.vb」ファイルを見ていただきたい。
‘ ImageInfoクラス内に文字列型の「画像名」というプロパティを定義している。
Public Class ImageInfo
Public Property 画像名 As String
End Class
「写真を撮る」アイコンがタップされた時の処理
この処理は、コードだけ記載しておく。
Private Async Sub shutterButton_Click(sender As Object, e As RoutedEventArgs) Handles shutterButton.Click
Try
MediaElement1.Play()
claudiaListBox.Visibility = Xaml.Visibility.Visible
Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
Dim mySubFolder = Await myFolder.CreateFolderAsync("CameraWithClaudia", CreationCollisionOption.OpenIfExists)
myFile = Await mySubFolder.CreateFileAsync(DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".png")
saveImageFileName = DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".png"
Dim myImageEncodingProperty As New ImageEncodingProperties
myImageEncodingProperty.Subtype = "png"
myImageEncodingProperty.Width = 640
myImageEncodingProperty.Height = 480
Await myMediaCapture.CapturePhotoToStorageFileAsync(myImageEncodingProperty, myFile)
myPictureFiles = Await mySubFolder.GetFilesAsync()
Index = myPictureFiles.Count
saveBmp = New BitmapImage
saveBmp.SetSource(Await myPictureFiles(Index - 1).OpenReadAsync)
Image1.Source = saveBmp
claudiaListBox.IsEnabled = True
claudiaListBox.Focus(Xaml.FocusState.Keyboard)
Await CameraRestart()
Catch
DBClickErrorShow()
End Try
End Sub
クラウディアの画像を表示して、拡大縮小、移動を行う処理(ClaudiaShowタスク処理)
Private Async Functiobb ClaudiaShow() As Task
claudiaImage = Await StorageFile.GetFileFromApplicationUriAsync(New Uri("ms-appx:///Images/" & claudiaImageFileName))
myBmp = New BitmapImage
myBmp.SetSource(Await claudiaImage.OpenReadAsync)
myClaudiaImage = New Image
With myClaudiaImage
.Width = 81
.Height = 249
.Source = myBmp
.RenderTransform = New CompositeTransform
.ManipulationMode = ManipulationModes.All
.SetValue(Canvas.ZIndexProperty, 20)
End With
Canvas1.Children.Add(myClaudiaImage)
AddHandler myClaudiaImage.ManipulationDelta, Sub(mySender As Object, myArgs As ManipulationDeltaRoutedEventArgs)
gouseiButton.IsEnabled = True
myTrans = DirectCast(myClaudiaImage.RenderTransform, CompositeTransform)
myTrans.TranslateX = myTrans.TranslateX + myArgs.Delta.Translation.X
myTrans.TranslateY = myTrans.TranslateY + myArgs.Delta.Translation.Y
myTrans.ScaleX = myTrans.ScaleX * myArgs.Delta.Scale
myTrans.ScaleY = myTrans.ScaleY * myArgs.Delta.Scale
End Sub
claudiaListBox.IsEnabled = True
End Function
以降、上記コードの中身を詳細に見ていこう。
まず、非同期処理で行われるためメソッドの先頭にAsyncを追加している。
メンバー変数「claudiaImage」に、StorageFile.GetFileFromApplicationUriAsyncメソッドで、ソリューション・エクスプローラーのImagesフォルダー内にある、メンバー変数「claudiaImageFileName」の画像を、URIを指定して参照させる。
新しいBitmapImageのインスタンスmyBmpオブジェクトを作成する。myBmp.SetSourceメソッドに、「Await claudiaImage.OpenReadAsync」と指定して、ファイルの内容を読むために、現在のファイルのランダムアクセスストリームを開く。
新しいImageのインスタンス、myClaudiaImageオブジェクトを作成する。
[Width]と[Height]プロパティの値を指定する。[Source]プロパティにmyBmpオブジェクトを指定する。UIElementの描画位置に影響する変換情報を設定する[RenderTransform]プロパティに、オブジェクトに複数の変換操作を適用する、新しいCompositeTransformオブジェクトを指定する。
ジェスチャーとともに、UIElementの動作および操作に使用される値を設定する、[ManipulationMode]プロパティに、全ての対話モードを有効にする「ManipulationModes.All」を指定する。[ZIndexProperty]に「20」を指定して、クラウディアの画像が一番前面に来るようにする。
Canvas1にクラウディアの画像を追加する。
AddHandlerステートメントで、操作中に入力デバイスが位置を変更した時に発生するManipulationDeltaイベントにイベントハンドラを追加する。イベントハンドラ内では以下の処理を行う。
[合成保存]ボタンの使用を可能にする。TranslateXとTranslateYで、x軸とy軸にそって並行移動する距離を設定する。ScaleXとScaleYで、オブジェクトを拡大縮小する値を設定する。これによって、クラウディア画像は、ピンチで拡大縮小、移動が可能になる。
最後に、クラウディアの画像の表示されているリストボックスの使用を可能にしている。
Copyright © ITmedia, Inc. All Rights Reserved.

