連載
» 2013年10月30日 18時00分 公開

カメラでクラウディア(Webカメラと画像を合成保存)2カ月で160本作った還暦開発者が送る10のアプリ開発ノウハウ(1)(4/5 ページ)

[薬師寺国安,PROJECT KySS]

空白のページを作成してコントロールを配置して画像一覧画面にする(ImageIchiranPage.xaml)

 VS2013のメニューから、[プロジェクト(P)]→[新しい項目の追加(W)]と選択し、表示される「新しい項目の追加」画面で、左のWindows ストアを選択し、右の欄から「空白のページ」を選択する。「名前(N)」には「ImageIchiranPage.xaml」と指定し、[追加(A)]ボタンをクリックする(図14)。ImageIchiranPage.xamlは保存した画像を一覧するページだ。

図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>
リスト4 書き出され編集されたXAML(ImageIchiranPage.xaml)

 以上、全てをレイアウトしたのが図15だ。

図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.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。