Webカメラで撮影した写真をセピア調に演出するアプリを作る
戻る(←)アイコンがタップされた時の処理
ピクチャライブラリにアクセスし、ピクチャライブラリ内にsepiaという文字を含んだファイル名がある場合は、「Folder」アイコンの使用を可能にし、それ以外は不可とします。
myFrameを非表示、「Sepia調に変換」ボタンを使用可、「Attach Camera」アイコンを使用可、GridViewを表示状態にします。
Webカメラのデバイス名が表示されているComboBox内の、先頭のデバイスを選択状態にします。よって、リアカメラを選択していた場合でも、戻る(←)アイコンをタップして、元の画面に戻った際は、フロントカメラが選択されていることになります。これは、どのデバイスが先頭に来るかによって異なります。
非同期処理で行われるためメソッドの先頭にAsyncを追加します。
Private Async Sub backButton_Click(sender As Object, e As RoutedEventArgs) Handles backButton.Click Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary Dim myPictureFiles = Await myFolder.GetFilesAsync() For Each myPhoto In myPictureFiles If myPhoto.Path.Contains("sepia") Then ichiranButton.IsEnabled = True Else ichiranButton.IsEnabled = False End If Next myFrame.Visibility = Xaml.Visibility.Collapsed changeSepiaButton.IsEnabled = True shutterButton.IsEnabled = True GridView1.Visibility = Xaml.Visibility.Visible cameraComboBox.SelectedIndex = 0 End Sub
WriteableBitmapExtensions.FromStreamAsyncメソッドを使って、リソース内の画像を読み込む関数
ピクチャライブラリのSepiaSourceImageサブフォルダにアクセスし、GetFilesAsyncメソッドでファイルを取得して、コレクション変数_myPictureFilesに格納します。
メンバ変数fileNameListをクリアしておきます。
ファイル名を格納している_myPictureFilesコレクション変数内のファイルを、変数myPtotoFileに格納しながら、以下の処理を繰り返します。
fileNameListオブジェクトにAddメソッドで、フルパス付のファイル名をPathプロパティで取得し、Path.GetFileNameWithoutExtensionメソッドで、パスと拡張子を除いたファイル名に、文字列「.jpg」を連結して追加していきます。
fileNameListオブジェクト内に格納されたファイル名で、GridView1.SelectedIndexに該当するファイルを、GetFileAsyncメソッドで取得し、imageFileで参照します。
WriteableBitmapExtensions.FromStreamAsyncメソッドでリソース内の画像を読み込み、戻り値とします。非同期処理で行われるため関数の先頭にAsyncを追加します。
Private Async Function GetTestImageAsync() As Task(Of WriteableBitmap) Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary Dim mySubFolder As StorageFolder = Await myFolder.CreateFolderAsync("SepiaSourceImage", CreationCollisionOption.OpenIfExists) Dim _myPictureFiles = Await mySubFolder.GetFilesAsync fileNameList.Clear() For Each myPhotoFile In _myPictureFiles fileNameList.Add(Path.GetFileNameWithoutExtension(myPhotoFile.Path) & ".jpg") Next Dim imageFile As StorageFile = Await mySubFolder.GetFileAsync(fileNameList(GridView1.SelectedIndex)) Return Await WriteableBitmapExtensions.FromStreamAsync(Await imageFile.OpenReadAsync) End Function
「Sepia調に変換」ボタンがクリックされた時の処理
GetTestImageAsync関数を呼び出し、読み込んだ画像ファイルを、myBmpで参照します。
myBmp.EffectSepiaメソッドでSepia調に変換された画像を、メンバ変数mySourceで参照します。
Image1のSourceプロパティにmySourceを指定します。これで、Image1にセピア調に変換された画像が表示されます。「Save」アイコンの使用を可能にします。
Private Async Sub changeSepiaButton_Click(sender As Object, e As RoutedEventArgs) Handles changeSepiaButton.Click Dim myBmp = Await GetTestImageAsync() mySource = myBmp.EffectSepia Image1.Source = mySource saveButton.IsEnabled = True End Sub
「Save」アイコンがタップされた時の処理
Image1.Sourceの値をDirectCastでWriteableBitmapにキャストして、myBmpオブジェクトで参照します。
SaveAsyncメソッドで、保存する場所をピクチャライブラリ内、保存する画像形式をPngに指定し、保存するファイル名を、文字列「sepia」を先頭に追加した「yyyy年MM月dd日HH時mm分ss秒」形式とし、Widthを640、Heightを480として保存します。
「sepia2013年01月01日10時10分10秒.png」といった形式の画像ファイルが保存されます。
「ピクチャフォルダー内に保存しました。」のメッセージを表示し、「Folder」アイコンの使用を可能に、「Save」アイコンの使用を不可とします。非同期処理で行われるためメソッドの先頭にAsyncを追加します。
Private Async Sub saveButton_Click(sender As Object, e As RoutedEventArgs) Handles saveButton.Click Dim myBmp = DirectCast(Image1.Source, WriteableBitmap) Await myBmp.SaveAsync(ImageDirectories.PicturesLibrary, ImageFormat.Png, "sepia" & DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒"), 640, 480) Dim message As New MessageDialog("ピクチャフォルダ内に保存しました。") Await message.ShowAsync ichiranButton.IsEnabled = True saveButton.IsEnabled = False End Sub
「Folder」アイコンがタップされた時の処理
myFrameを表示状態にします。「Sepia調に変換」ボタンの使用を不可、「AttachCamera」アイコンの使用を不可、GridView1を非表示状態にします。
NavigateメソッドでIchiranShowPageに遷移します。値は何も渡さないのでNothingを指定します。
Private Sub ichiranButton_Click(sender As Object, e As RoutedEventArgs) Handles ichiranButton.Click myFrame.Visibility = Xaml.Visibility.Visible changeSepiaButton.IsEnabled = False shutterButton.IsEnabled = False GridView1.Visibility = Xaml.Visibility.Collapsed myFrame.Navigate(GetType(IchiranShowPage), Nothing) End Sub End Class
次に、ソリューションエクスプローラー内のIchiranShowPage.xamlを展開して表示される、IchiranShowPage.xaml.vbをダブルクリックしてリスト4のコードを記述します。
ロジックコードを記述する
リスト4 (IchiranShowPage.xaml.vb)
Option Strict On Imports Windows.Storage Imports Windows.UI Imports Windows.UI.Popups Public NotInheritable Class IchiranShowPage Inherits Page
ページがアクティブになった時の処理
「ファイル名」と「削除」ボタンの付いたセピア調に変換された画像を一覧表示する、DataShowプロシージャを実行します。
Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) DataShow() End Sub
「ファイル名」と「削除」ボタンの付いたセピア調に変換された画像を一覧表示する処理
ピクチャライブラリにアクセスします。GetFilesAsyncメソッドでピクチャライブラリ内の画像を取得して、コレクション変数myPictureFilesに格納します。
ファイルを格納しているmyPictureFilesコレクション内のファイルを、変数myPhotoに格納しながら、以下の処理を繰り返します。ファイル名に「sepia」という文字列が含まれている場合の処理です。
新しいBitmapImageのインスタンスbmpオブジェクトを作成します。SetSourceメソッドに、
Await myPhoto.OpenReadAsync
と指定し、OpenReadAsyncメソッドで、現在のファイルのランダムアクセスストリームを開きBitmapSourceのソースイメージに設定します。
新しいImageのインスタンスmyImageを作成します。Widthに640、Heightに480、StretchにNone、Sourceプロパティにbmpオブジェクトを指定します。
新しいTextBlockのインスタンスmyTextBlockオブジェクトを作成します。
文字サイズに20、文字色にBeige、Textプロパティに、パスと拡張子を除いたファイル名から、SubStringメソッドで6文字目から20文字取り出し、指定します。
「sepia2013年01月01日10時10分10秒.png」形式から、sepiaの文字と拡張子を除いたファイル名になります。中央揃えとしておきます。
新しいButtonのいインスタンスmyButtonを作成します。Contentに「削除」、文字サイズに18、Tagプロパティには、パスと拡張子を除いたファイル名に、文字列「.png」を追加した値を指定しておきます。中央揃えとしておきます。
新しいStackPanelのインスタンスmyStackPanelオブジェクトを作成します。
Marginに5を指定して余白を設けます。
Addメソッドで、myStackPanelオブジェクトに、myImage、myTextBlock、myButtonオブジェクトを追加します。
GridView1にAddメソッドでmyStackPanelオブジェクトを追加します。
これで、セピア調の画像にファイル名と削除ボタンの付いた画像の一覧がGridView内に表示されます。
AddHandlerステートメントで「削除」ボタンがクリックされた時のイベントハンドラを追加します。
イベントハンドラ内では以下の処理を行います。
Buttonの情報を格納しているdeSenderオブジェクトをDirectCastでButtonにキャストして、そのTagプロパティの値を取得して、変数myFileNameに格納しておきます。
GetFileAsyncメソッドで、変数myFileNameに格納されている画像ファイルを取得し変数delImageNameで参照します。
DeleteAsyncメソッドで参照していたファイルを削除します。
「削除しました。」のメッセージを表示し、GridView内をクリアします。
画面を再描画するために、DataShowプロシージャを実行します。
Private Async Sub DataShow() Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary Dim myPictureFiles = Await myFolder.GetFilesAsync() For Each myPhoto In myPictureFiles If myPhoto.Path.Contains("sepia") Then Dim bmp As New BitmapImage bmp.SetSource(Await myPhoto.OpenReadAsync) Dim myImage As New Image myImage.Width = 640 myImage.Height = 480 myImage.Stretch = Stretch.None myImage.Source = bmp Dim myTextBlock As New TextBlock With myTextBlock .FontSize = 20 .Foreground = New SolidColorBrush(Colors.Beige) .Text = Path.GetFileNameWithoutExtension(myPhoto.Path).Substring(5, 20) .HorizontalAlignment = Xaml.HorizontalAlignment.Center End With Dim myButton As New Button With myButton .Content = "削除" .FontSize = 18 .Tag = Path.GetFileNameWithoutExtension(myPhoto.Path) & ".png" .HorizontalAlignment = Xaml.HorizontalAlignment.Center End With Dim myStackPanel As New StackPanel myStackPanel.Margin = New Thickness(5) myStackPanel.Children.Add(myImage) myStackPanel.Children.Add(myTextBlock) myStackPanel.Children.Add(myButton) GridView1.Items.Add(myStackPanel) AddHandler myButton.Click, Async Sub(delSender As Object, delArgs As RoutedEventArgs) Dim myFileName As String = CStr(DirectCast(delSender, Button).Tag) Dim delImageName = Await myFolder.GetFileAsync(myFileName) Await delImageName.DeleteAsync Dim myMessage As New MessageDialog("削除しました。") Await myMessage.ShowAsync GridView1.Items.Clear() DataShow() End Sub End If Next End Sub End Class
アイコンの作成
詳細については、「自分の現在位置を取得して表示するサンプルプログラム」の記事を参照してください。
今回はここまでです。ありがとうございました。
セピア調の写真を作るアプリ