カメラで撮った写真に各種フィルタをかける

2012年1月25日(水)
PROJECT KySS

[カメラ起動]ボタンがタップされた時の処理

ボタンの文字で条件分岐を行います。ボタンの文字が[カメラ起動]の場合は、Showメソッドでカメラ機能を起動します。[元に戻す]の場合は、Image1~Image4コントロールを非表示にし、Image5コントロールのみ表示します。ボタンの文字を[カメラ起動]とします。
  Private Sub Button1_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
    myCameraTask.Show()
    Case "元に戻す"
      Image5.Visibility = Windows.Visibility.Visible
      Image1.Visibility = Windows.Visibility.Collapsed
      Image2.Visibility = Windows.Visibility.Collapsed
      Image3.Visibility = Windows.Visibility.Collapsed
      Image4.Visibility = Windows.Visibility.Collapsed
      Button1.Content = "カメラ起動"
    End Select
  End Sub

Image5をホールドしてコンテキストメニューのMenuItemをクリックした時の処理

MenuItemのHeaderの値で条件分岐を行います。
Headerの値が、「各種イメージフィルタ」であった場合は、Image5コントロールを非表示にし、Image1~Image4コントロールを表示します。ボタンの文字を[元に戻す]とします。それ以外の場合は、Image5コントロールを表示します。
  Private Sub myMenuItem_Click(sender As Object, e As EventArgs)
    Dim selectHeader = DirectCast(sender, MenuItem).Header
    Select Case selectHeader.ToString
      Case "各種イメージフィルタ"
        Image5.Visibility = Windows.Visibility.Collapsed
        Image1.Visibility = Windows.Visibility.Visible
        Image2.Visibility = Windows.Visibility.Visible
        Image3.Visibility = Windows.Visibility.Visible
        Image4.Visibility = Windows.Visibility.Visible
        Button1.Content = "元に戻す"
      Case Else
        Image5.Visibility = Windows.Visibility.Visible
        Exit Sub
    End Select
  End Sub

Image1がホールドされた時の処理。

Image1を引数に、コンテキストメニューを表示する、contextMenuShowプロシージャを実行します。
  Private Sub Image1_Hold(sender As Object, e As System.Windows.Input.GestureEventArgs) Handles Image1.Hold
    contextMenuShow(Image1)
  End Sub

Image2がホールドされた時の処理。

Image2を引数に、コンテキストメニューを表示する、contextMenuShowプロシージャを実行します。
  Private Sub Image2_Hold(sender As Object, e As System.Windows.Input.GestureEventArgs) Handles Image2.Hold
    contextMenuShow(Image2)
  End Sub

Image3がホールドされた時の処理。

Image3を引数に、コンテキストメニューを表示する、contextMenuShowプロシージャを実行します。
  Private Sub Image3_Hold(sender As Object, e As System.Windows.Input.GestureEventArgs) Handles Image3.Hold
    contextMenuShow(Image3)
  End Sub

Image4がホールドされた時の処理。

Image4を引数に、コンテキストメニューを表示する、contextMenuShowプロシージャを実行します。
  Private Sub Image4_Hold(sender As Object, e As System.Windows.Input.GestureEventArgs) Handles Image4.Hold
    contextMenuShow(Image4)
  End Sub

コンテキストメニューを表示する処理。引数としてホールドされたImageコントロールを指定します。

UIElementとして宣言したimageControlにホールドされたImageコントロールを参照させておきます。
新しいMeuItemのインスタンスmyMenuItemオブジェクトを作成します。MenuItemクラス型の、新しいリストであるmyMenuItemListを作成します。新しいContextMenuのインスタンス_myContextmenuオブジェクトを作成します。MenuItemのオブジェクトであるmyMenuItemのHeaderプロパティに、「PicturesHubに保存」と指定します。MeuItem型のリストであるmyMenuItemListオブジェクトに、AddメソッドでmyMenuItemオブジェクトを追加します。ContextMenuクラスのオブジェクト_myContextMenuオブジェクトのItemsSourceプロパティに、myMenuItemListオブジェクトを指定します。Opacityプロパティに0.7を指定し表示されるメニューの背景を半透明化しています。ContextMenuService.SetContextMenuメソッドで、ホールドされたImageオブジェクトの ContextMenu プロパティの値を設定します。IsOpenメソッドでContextMenuを開きます。
AddHandlerステートメントでMenuItemがクリックされた時に、_myMenuItem_Clickを実行するよう指定します。
  Private Sub contextMenuShow(myControl As UIElement)
    imageControl = myControl
    Dim myMenuItem As New MenuItem
    Dim myMenuItemList As New List(Of MenuItem)
    Dim _myContextMenu As New ContextMenu
    myMenuItem.Header = "PicturesHUBに保存"
    myMenuItemList.Add(myMenuItem)
    _myContextMenu.ItemsSource = myMenuItemList
    _myContextMenu.Opacity = 0.7
    ContextMenuService.SetContextMenu(myControl, _myContextMenu)
    _myContextMenu.IsOpen = True
 
    AddHandler myMenuItem.Click, AddressOf _myMenuItem_Click
  End Sub

Image1~Image4をホールドしてコンテキストメニューのMenuItemをクリックした時の処理

MenuItemのHeaderプロパティの値で条件分岐を行います。
メニューが「PicturesHUBに保存」の場合の処理です。
PicturesHUBに保存するファイル名を現在の「年月日時間分秒.jpg」とし、変数imageFileNameに格納しておきます。
ホールドされたImageコントロールで初期化された、新しいWriteableBitmapのオブジェクト、myWriteableBitmapを作成します。WriteableBitmapクラスの第2引数には、ビットマップに特定の変換を適用するTransformを指定できますが、ここではNothingを指定します。WriteableBitmapクラスは、書き込みおよび更新が可能な BitmapSourceを提供するクラスです。
変数storageを、ファイルとディレクトリを格納している分離ストレージ領域を表すIsolateStorageFileクラスとして宣言します。FileExistsメソッドで、imageFileNameに格納しているファイルが存在しているかどうかをチェックし、存在している場合はDeleteFileメソッドで同名ファイルを削除します。
分離ストレージ内のファイルを表すIsolatedStorageFileStreamクラス用オブジェクト変数myStream変数を用意し、IsolatedStorageFile.CreateFileメソッドで、分離ストレージ内にimageFileName変数の持っているファイルを作成します。
Extensions.SaveJpegメソッドで、WriteableBitmapオブジェクトを、JPEGストリームにエンコードし、一時的に分離ストレージに保存します。これは、JPEGファイルのターゲットとなる幅と高さを設定するためのパラメータを持っています。書式は下記の通りです。

Extensions.SaveJpeg(WriteableBitmapオブジェクト,イメージデータストリーム,WriteableBitmapオブジェクトのPixelWidth, WriteableBitmapオブジェクトのPixelHeight,0(固定),0~100の間の写真の品質(70以上を指定))

ピクチャへのアクセスを提供する新しいMediaLibrayクラスのインスタンス、myLibrayを作成します。分離ストレージ内のファイルを表すIsolatedStorageFileStreamクラス用オブジェクト変数であるStream変数を用意し、IsolatedStorageFile.OpenFileメソッドで、imageFileNameに格納されているJPEGファイルを、指定したファイルアクセスを使用して指定したモードで開き、変数Streamで参照します。MediaLibrary.SavePictureメソッドで、ストリームオブジェクトに含まれる画像をメディアライブラリーに保存し、その保存した画像をピクチャオブジェクトとして返します。保存した旨のメッセージを表示します。 これで、分離ストレージ内の画像が、PicturesHUBに保存されます。
  Private Sub _myMenuItem_Click(sender As Object, e As EventArgs)
    Dim selectHeader = DirectCast(sender, MenuItem).Header
    Select Case selectHeader.ToString
      Case "PicturesHUBに保存"
        Dim imageFileName As String = DateTime.Now.ToString("yyyyMMddHHmmss") & ".jpg"
        Dim myWriteableBitmap As WriteableBitmap
        myWriteableBitmap = New WriteableBitmap(imageControl, Nothing)
 
        Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication
        If storage.FileExists(imageFileName) = True Then
          storage.DeleteFile(imageFileName)
        End If
        Using myStream As IsolatedStorageFileStream = storage.CreateFile(imageFileName)
          System.Windows.Media.Imaging.Extensions.SaveJpeg(myWriteableBitmap, myStream, myWriteableBitmap.PixelWidth, myWriteableBitmap.PixelHeight, 0, 85)
        End Using
 
        Dim myLibray As New MediaLibrary
        Using Stream As IsolatedStorageFileStream = storage.OpenFile(imageFileName, FileMode.Open, FileAccess.Read)
          myLibray.SavePicture(imageFileName, Stream)
          MessageBox.Show("PicturesHubに保存しました。")
        End Using
      Case Else
        Exit Sub
    End Select
  End Sub
End Class
  • 「カメラで撮った写真に各種フィルタをかける」サンプルプログラム

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています