読み込んだ画像に装飾を施し、PictureHUBに保存する

2011年12月12日(月)
PROJECT KySS

[画像読み込み]ボタンがタップされた時の処理

新しいPhotoChooserTaskのインスタンス、photoTaskオブジェクトを生成します。Showメソッドで実行します。 
AddHandlerステートメントで、タスクが完了した時のCompletedイベントハンドラを追加します。Completedイベント内では、完了イベントがTaskResult.OKで、正常に完了した場合は以下の処理を行います。
chooser での選択の結果は引数で渡されますので、SetSourceメソッドで、渡された画像を BitmapImage オブジェクトに格納します。Image1のSourceプロパティにchooserで選択した画像を格納している、BitmapImageオブジェクトを指定します。Picturesで選択した画像が表示されます。

  Private Sub callImageButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles callImageButton.Click
    Dim photoTask As New PhotoChooserTask
    AddHandler photoTask.Completed, Sub(photoSender As Object, photoArgs As PhotoResult)
                                      If photoArgs.TaskResult = TaskResult.OK Then
                                        Dim bmp As New BitmapImage
                                        bmp.SetSource(photoArgs.ChosenPhoto)
                                        Image1.Source = bmp
                                      End If
                                    End Sub
    photoTask.Show()
  End Sub

ページが読み込まれた時の処理

XElement.LoadメソッドでXML文書ファイル(ImageFilter.xml)を読み込みます。ImageFilterクラス型の新しいリストであるmyFilterImageオブジェクトを作成します。
Descendants メソッドで、子孫要素である全ての <画像名> 要素のコレクションに対して、各要素を変数 result に格納しながら、ImageFilter クラスの各プロパティに、<画像名>要素の値や、<画像名>要素の属性”filename”の値を指定し、AddメソッドでmyFilterImageオブジェクトに追加していきます。
ListBoxのItemsSourceプロパティにmyFilterImageオブジェクトを指定します。これでListBoxコントロール内にグッズとその名称が表示されます。
  Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    xmldoc = XElement.Load("ImageFilter.xml")
    Dim myFilterImage As New List(Of ImageFilter)
 
    For Each result In From c In xmldoc.Descendants("画像名") Select c
      With myFilterImage
        .Add(New ImageFilter With {.画像名 = result.Value, .fileName = "Image/" & result.Attribute("fileName").Value})
      End With
    Next
    ListBox1.ItemsSource = myFilterImage
  End Sub

スライダーの値が変化した時の処理

オブジェクトの幅を取得して変数photoOriginalWidthに格納します。
スライダーの値の変化に伴って、オブジェクトの幅も変化させます。変化した値をmyScale変数に格納します。
新しいScaleTransformクラスのインスタンスmyScaleTransformオブジェクトを作成します。ScaleTransformクラスは、オブジェクトを変形させるクラスです。
xとy 軸のスケールファクターを表す、ScaleYとScaleXプロパティに、myScaleの値を指定します。オブジェクト、この場合グッズの画像のRenderTransformプロパティにmyScaleTransformオブジェクトを指定して、変形を適用させます。RenderTransformプロパティは、オブジェクトの変換情報を設定するプロパティです。
  Private Sub Slider1_ValueChanged(sender As Object, e As System.Windows.RoutedPropertyChangedEventArgs(Of Double)) Handles Slider1.ValueChanged
    Dim photoOriginalWidth As Double = CDbl(createImage.GetValue(FrameworkElement.ActualWidthProperty))
 
    myScale = (photoOriginalWidth + (Slider1.Value - 160)) / photoOriginalWidth
 
    Dim myScaleTransform As New ScaleTransform
    myScaleTransform.ScaleY = myScale
    myScaleTransform.ScaleX = myScale
    createImage.RenderTransform = myScaleTransform
  End Sub

[全クリア]ボタンがタップされた時の処理

InkPresenter内をクリアします。画像も配置されていた装飾もクリアされます。Sliderの値を160に設定します。最大値(Maximum)を320に設定していますので、スライダーのバーが中央に位置します。
  Private Sub clearButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles clearButton.Click
    InkPresenter1.Children.Clear()
    Slider1.Value = 160
  End Sub

ListBoxから任意のグッズ(画像)が選択された時の処理

ListBoxから選択された項目のインデックスに対応する<画像名>要素の属性”filename”の値を取得し、変数myImageに格納しておきます。新しいImageのインスタンスcreateImageオブジェクトを作成します。Width、Heightプロパティを指定し、SourceプロパティにImageフォルダ内の変数myImageに該当する画像を指定します。InkPresenterにcreateImageオブジェクトを追加します。Sliderコントロールの使用を可能とします。
新しい、MouseDragElementBehaviorクラスのインスタンスbehaviorオブジェクトを作成します。MouseDragElementBehaviorクラスは、アタッチされた要素を、マウスのドラッグのジェスチャに応答して要素の上に再配置するクラスです。
Attachメソッドで指定されたオブジェクトにアタッチします。この場合、ListBoxから選択され配置された画像にアタッチすることになるため、配置された画像は、どの場所にでもドラッグが可能になります。
  Private Sub ListBox1_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox1.SelectionChanged
 
    Dim myImage As String = xmldoc.Descendants("画像名")(ListBox1.SelectedIndex).Attribute("fileName").Value
    createImage = New Image
    With createImage
        .Width = 193
        .Height = 70
        .Source = New BitmapImage(New Uri("Image/" & myImage, UriKind.Relative))
    End With
    InkPresenter1.Children.Add(createImage)
 
    Slider1.IsEnabled = True
 
    Dim behaivior As New MouseDragElementBehavior
    behaivior.Attach(createImage)
  End Sub

[保存]ボタンがタップされた時の処理

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

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

ピクチャへのアクセスを提供する新しいMediaLibrayクラスのインスタンス、myLibrayを作成します。分離ストレージ内のファイルを表すIsolatedStorageFileStreamクラス用オブジェクト変数myStream変数を用意し、IsolatedStorageFile.OpenFileメソッドで、fileNameに格納されているJPEGファイルを、指定したファイルアクセスを使用して指定したモードで開きます。MediaLibrary.SavePictureメソッドで、ストリームオブジェクトに含まれる画像を、メディアライブラリーに保存し、その保存した画像をピクチャオブジェクトとして返します。保存した旨のメッセージを表示します。
 
  Private Sub saveButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles saveButton.Click
    Dim fileName As String = DateTime.Now.ToString("yyyyMMddHHmmss") & ".jpg"
 
    myWriteableBitmap = New WriteableBitmap(InkPresenter1, Nothing)
    Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication
    If storage.FileExists(fileName) = True Then
      storage.DeleteFile(fileName)
    End If
    Using myStream As IsolatedStorageFileStream = storage.CreateFile(fileName)
      System.Windows.Media.Imaging.Extensions.SaveJpeg(myWriteableBitmap, myStream, myWriteableBitmap.PixelWidth, myWriteableBitmap.PixelHeight, 0, 85)
    End Using
    Dim myLibray As New MediaLibrary
    Using myStream As IsolatedStorageFileStream = storage.OpenFile(fileName, IO.FileMode.Open, IO.FileAccess.Read)
      myLibray.SavePicture(fileName, myStream)
      MessageBox.Show("PicturesHubに保存しました。")
    End Using
  End Sub
End Class
  • 「読み込んだ画像に装飾を施し、PictureHUBに保存する」サンプルプログラム

四国の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メルマガ会員のサービス内容を見る

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