画像に各種フィルタを適用して保存するWindowsアプリを作る
ピクチャライブラリへのアクセス許可の設定
今回のサンプルはピクチャライブラリにアクセスするため、「画像ライブラリ」へのアクセス許可が必要になります。ソリューションエクスプローラー内にpackage.appxmanifestというファイルがありますので、このファイルをダブルクリックします。「機能」タブをクリックし、「画像ライブラリ」にチェックを付けます(図7)。
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト2 (MainWindow.xaml.vb)
Option Strict On
エフェクトを使用可能にするSoftBuild.Media名前空間をインポートします。WriteableBitmapEffectorに含まれる名前空間です。
Imports Softbuild.Media
ファイル、フォルダ、およびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。
Imports Windows.Storage Public NotInheritable Class MainPage Inherits Page
BitmapImageクラス型である新しいリストのインスタンス、myImageListメンバ変数を宣言します。
Dim myImageList As New List(Of BitmapImage)
ファイルを表すIstorageFileインターフェース型の、インデックスによってアクセスできる読み取り専用のコレクションを表す、IReadOnlyList(Of Out T)インターフェース型のメンバ変数myPictureFilesを宣言します。
Dim myPictureFiles As IReadOnlyList(Of IStorageFile)
文字列型の新しいリストであるmySubFolderメンバ変数を宣言します。
Dim fileNameList As New List(Of String)
フォルダとその内容を操作し、その情報を提供するクラスである、StorageFolder型のメンバ変数mySubFolderを宣言します。
Dim mySubFolder As StorageFolder
WriteableBitmapクラス型のメンバ変数mySourceを宣言します。WriteableBitmapクラスは、書き込みおよび更新が可能な、BitmapSourceを提供するクラスです。
Dim mySource As WriteableBitmap
ページがアクティブになった時の処理
ピクチャライブラリにアクセスします。GetFileAsyncメソッドで、ピクチャライブラリ内のファイルを取得し、コレクション変数myPictureFilesに格納しておきます。CountプロパティでmyPictureFiles内のファイルの個数を取得し、ファイルが存在する場合は[一覧]ボタンの使用を可能にし、それ以外の場合は使用を不可とします。
CreateFolderAsyncメソッドで、ピクチャライブラリ内にageRecordというサブフォルダを作成します。
CreationCollisionOption.OpenIfExistsと指定します。すでに同名フォルダが存在する場合はそのフォルダ名を返し、ない場合はフォルダを作成してくれます。
GetFileAsyncメソッドでageRecordsサブフォルダ内のファイルを取得して、コレクション変数mySubPictureFiles変数に格納します。
コレクション変数mySubPictureFiles変数内のファイル名を変数myFileで取得しながら、反復処理を行います。
BitmapImageクラスの新しいインスタンスbmpオブジェクトを作成します。
SetSourceメソッドにAwait myFile.OpenReadAsyncと指定して、ランダムアクセス用のストリームを開きます。
BitmapImage型のリストであるmyImageListにAddメソッドでbmpオブジェクトを追加していきます。
文字列型のリストであるfileNameListにGetFileNameメソッドでファイル名を取得して追加していきます。
Imageの新しいインスタンスmyImageオブジェクトを作成し、Marginには0を指定し、WidthとHeightの値を指定します。
Sourceプロパティにbmpオブジェクトを指定し、GridViewコントロールにAddメソッドでmyImageオブジェクトを追加します。
GridViewコントロールに横一列でageRecordsサブフォルダ内の画像が一覧で表示されます。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) Dim pictureFolder As StorageFolder = KnownFolders.PicturesLibrary Dim myPictureFiles As IReadOnlyList(Of IStorageFile) = Await pictureFolder.GetFilesAsync() If myPictureFiles.Count> 0 Then ichiranButton.IsEnabled = True Else ichiranButton.IsEnabled = False End If mySubFolder = Await pictureFolder.CreateFolderAsync("ageRecords", CreationCollisionOption.OpenIfExists) Dim mySubPictureFiles As IReadOnlyList(Of IStorageFile) = Await mySubFolder.GetFilesAsync() For Each myFile In mySubPictureFiles Dim bmp As New BitmapImage bmp.SetSource(Await myFile.OpenReadAsync) myImageList.Add(bmp) fileNameList.Add(Path.GetFileName(myFile.Path)) Dim myImage As New Image myImage.Width = 320 myImage.Height = 240 myImage.Source = bmp GridView1.Items.Add(myImage) Next End Sub
GridViewの画像一覧から任意の画像が選択された時の処理
各種フィルタボタンの使用を可能にします。
BitmapImageのリストであるmyImageListオブジェクトで、GridViewの選択されたインデックスに対応する画像を取得して変数selectImageに格納します。
ImageのSourceプロパティにselectImageを指定します。
これで、Imageコントロールに実寸大の画像が表示されます。
Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged bakumatsuButton.IsEnabled = True grayButton.IsEnabled = True negativeButton.IsEnabled = True sepiaButton.IsEnabled = True SaturationButton.IsEnabled = True VignettingButton.IsEnabled = True ToycameraButton.IsEnabled = True PosterizeButton.IsEnabled = True contrastButton.IsEnabled = True Dim selectImage = myImageList(GridView1.SelectedIndex) Image1.Source = selectImage messageTextBlock.Text = String.Empty End Sub
画像を日付で検索する際に、日付を入力して[OK]ボタンをクリックした時の処理
画像のファイル名を格納しているfileNameListコレクション内を、ファイル名を格納していく変数resultで反復処理を行います。
変数selectTextにSubStringメソッドで先頭から10文字を取得します。ファイル名は
「2012-08-20 06-03-57.512.jpg」といった形式になっていますので、先頭から10文字を取得すると、「2012-08-20」という値が取得されます。
この値を格納している変数selectTextの値がsearchTextBoxに入力された値と同じであれば、反復処理を抜け、1ずつ加算されていた変数noの値をGridViewのSelectedIndexの値に指定します。Image1にもGridViewで選択された画像が表示されます。
ScrollIntoViewメソッドでGridViewを指定した画像の位置までスクロールします。
同じファイル名が見つかった時にはExit Forすることが肝心です。Exit Forを書き忘れると、最後の画像ファイル名が取得されます。
Private Sub okButton_Click(sender As Object, e As RoutedEventArgs) Handles okButton.Click Dim no As Integer = 0 For Each resut In fileNameList.ToList Dim selectText = resut.Substring(0, 10) If selectText = searchTextBox.Text Then GridView1.SelectedIndex = no GridView1.ScrollIntoView(GridView1.Items(no)) Exit For End If no+=1 Next End Sub
GridViewから選択された画像を取得する関数
GetFileAsyncメソッドで、ageRecordsサブフォルダから、画像ファイル名を格納しているFileNameList内の、GridViewから選択したインデックスに対応するファイル名を取得し、変数imageFileで参照します。
WriteableBitmapExtensions.FromStreamAsyncメソッドを使って、GridViewから選択された画像を読み込み戻り値とします。
非同期で処理されるため、メソッドの先頭にAsyncを追加します。
Private Async Function GetTestImageAsync() As Task(Of WriteableBitmap) Dim imageFile As StorageFile = Await mySubFolder.GetFileAsync(fileNameList(GridView1.SelectedIndex)) Return Await WriteableBitmapExtensions.FromStreamAsync(Await imageFile.OpenReadAsync) End Function
[幕末風]ボタンがクリックされた時の処理
WriteableBitmap変数myBmpで、GetTestImageAsync関数の戻り値を取得します。GridViewから選択された画像ファイルが取得されます。
WriteableBitmap型のメンバ変数mySourceにEffectBakumatsuAsyncを指定します。
ImageのSourceプロパティにmySourceを指定します。幕末風なエフェクトのかかった画像が表示されます。
[Effect適用後の画像保存]ボタンの使用を可能にします。
非同期で処理が行われるためメソッドの先頭にAsyncを追加します。
Private Async Sub bakumatsuButton_Click(sender As Object, e As RoutedEventArgs) Handles bakumatsuButton.Click Dim myBmp = Await GetTestImageAsync() mySource = Await myBmp.EffectBakumatsuAsync Image1.Source = mySource saveButton.IsEnabled = True End Sub
画像に各種フィルタを適用して保存するWindows8サンプルアプリ
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Webカメラで撮影した写真をセピア調に演出するアプリを作る
- お気に入りの写真に登場する、仲良しクラウディアちゃん
- 撮影した写真と手持ちの画像を合成して保存するサンプルアプリ
- 場所と写真を記録するプログラムを作って思い出のシーンを保存しよう
- ピクチャライブラリ内の画像を指定して表示する+1つのサンプル
- 撮影した写真の管理ができるマイフォトアプリを作る
- 国内ニュースの取得・表示と、人名から画像検索を行う2つのサンプルをつくる
- CountDownControlを使ってカウントダウン後にカメラのシャッターを切る
- 画像の任意の部分をトリミングして保存するプログラムを作る
- PCで撮影した写真を並べて最適な1枚を選べるプログラムをつくる