カメラで撮った写真に各種フィルタをかける
2012年1月25日(水)
次に、MainPage.xamlを展開して表示される、MainPage.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト2 (MainPage.xaml.vb)
Option Strict On ランチャーやチューザーに関するクラスの含まれる、Microsoft.Phone.Tasks名前空間をインポートします。 Imports Microsoft.Phone.Tasks Imports System.Windows.Media.Imaging Imports Microsoft.Phone イメージを読み込んだり、操作したりするコントロールやクラスが含まれた、基本の名前空間であるImageToolsをインポートします。ImageTools.Filtering名前空間には、セピア、グレースケール、反転フィルタなどの画像フィルタが含まれています Imports ImageTools Imports ImageTools.Filtering 仮想ファイルシステムを作成および使用するための型が含まれている、System.IO.IsolatedStorage名前空間をインポートします。分離ストレージによって、安全なクライアント側のストレージが提供されます。 Imports System.IO.IsolatedStorage 曲、アルバム、再生リスト、ピクチャの列挙、再生、表示するためのクラスが含まれた、Microsoft.Xna.Framework.Media名前空間をインポートします。この名前空間をインポートしていないとMediaLibrayクラスが使用できませんので、注意してください。 Imports Microsoft.Xna.Framework.Media Imports System.IO Inherits PhoneApplicationPage ' コンストラクター Public Sub New() InitializeComponent() End Sub カメラを起動するCameraCaptureTaskクラス用メンバ変数myCameraTaskを宣言します。 Dim myCameraTask As CameraCaptureTask loadImage、filterImageを、Image クラスのピクセルを格納してファイルやストリームのサイズ変更、またカッティングのような操作からイメージを読み込む機能を提供するクラスであるExtendedImageクラス用メンバ変数として宣言します。 Dim loadImage As ExtendedImage Dim filterImage As ExtendedImage BitmapImageクラス用メンバ変数として、myImageを宣言します。BitmapImageクラスは、イメージを読み込むためのBitmapSourceを提供するクラスです。 Dim myImage As BitmapImage ContextMenuクラスの新しいインスタンス、myContextMenuオブジェクトをメンバ変数として宣言します。ContextMenuコントロールは、コントロールのコンテキストに固有の機能を公開するポップアップメニューを表示するコントロールです。このコントロールは、Silverlight for Windows Phone Toolkit - Nov 2011.msiに含まれていますので、下記URLよりダウンロードしてインストールしてください。 http://silverlight.codeplex.com/releases/view/75888 Dim myContextMenu As New ContextMenu 新しいMenuItemクラスのインスタンスmyMenuItem1をメンバ変数として宣言します。MenuItemクラスは、ContextMenu 内に表示される個別の項目を表すクラスです。 Dim myMenuItem1 As New MenuItem MenuItemクラス型の新しいリストであるmenuItemListをメンバ変数として宣言します。 Dim menuItemList As New List(Of MenuItem) UIElementクラス型のオブジェクト変数myControlをメンバ変数として宣言します。UIElementクラスは、Silverlightのオブジェクトの基本クラスです。Silverlightで使用する各コントロールは、基本的に全てUIElementになります。 Dim imageControl As UIElement
ページがアクティブになった時の処理
新しいCameraCaptureTaskのインスタンスを作成します。AddHandlerステートメントで、タスクが完了した時のCompletedイベントハンドラを追加します。Completedイベント内では完了イベントがTaskResult.OKで、正常に完了した場合は以下の処理を行います。 新しいBitmapImageのインスタンスmyImageを作成します。chooser での選択の結果は引数で渡されるので、SetSourceメソッドで、渡された画像を BitmapImage オブジェクトに格納します。Image1~Image5のSourceプロパティに、chooserで選択した画像を格納しているBitmapImageオブジェクトを指定します。Picturesで選択した画像が表示されます。ただし、Image1~Image4は非表示となっていますので、表面上はImage5の画像のみ表示されています。 BitmapImageのインスタンスmyImageで初期化された、新しいWriteableBitmapオブジェクトwbを作成します。WriteableBitmapクラスは、書き込みおよび更新が可能な BitmapSource を提供するクラスです。 新しいExtendedImageクラスのインスタンスを作成します。SetPixelsメソッドで、loadImageオブジェクトに画像のピクセル配列を設定します。書式は下記の通りです。 ImageBase.SetPixels(画像の新しいPixelWidth(0より大きい),画像の新しいPixelHeight(0より大きい), 色のバイト配列) wb.ToByteArrayメソッドは、WriteableBitmap byte()に変換するメソッドです。[参照の追加(R)]から、WriteableBitmapEXWinPhone.dllを追加していなければ、wb.ToByteArrayメソッドが使用できませんので、注意してください。 Sepiaクラスとしてfilter変数を宣言します。新しいSepiaクラスのインスタンスを作成します。画像のピクセル配列の設定されたloadImageで初期化された、新しいExtendedImageを作成します。Sepia.Applyメソッドで、指定されたRectangleの領域で画像へのフィルタが適用されます。Applyメソッドの書式は下記の通りです。 Sepia.Apply(フィルタを適用するターゲットとなるイメージ,元のイメージ, フィルタが適用されるべき画像の領域を定義するRectangle) Rectangleは下記の値で初期化されます。 New ImageToos.Rectangle(Rectangleの左上隅のx座標(通常0), Rectangleの左上隅のy座標(通常0),元のイメージのPixelWidth,元のイメージのPixelHeight) フィルタの適用されたイメージを、ToBitmapメソッドでBitmapに変換し、Image1のSourceプロパティに指定します。 Inverter、Grayscale、Brightnessについても同じ処理を繰り返します。Brightnessは輝度を表し、このサンプルでは輝度に50を与えて初期化しています。値は-255~255の範囲の値を指定できます。 AddHandlerステートメントで、Image5がホールドされた時のイベントハンドラを追加します。イベントハンドラ内では、以下の処理を行います。 MenuItemクラスのオブジェクト、myMenuItem1のHeaderプロパティに「各種イメージフィルタ」と指定し、MeuItemクラス型として作成したmenuItemListリストに、AddメソッドでmyMenuItem1オブジェクトを追加します。ContextMenuクラスのオブジェクトmyContextMenuオブジェクトのItemsSourceプロパティに、myMenuItemListオブジェクトを指定します。Opacityプロパティに0.7を指定し表示されるメニューの背景を半透明化しています。ContextMenuService.SetContextMenuメソッドで、Image5オブジェクトの ContextMenu プロパティの値を設定します。 IsOpenメソッドでContextMenuを開きます。 AddHandlerステートメントでMenuItemがクリックされた時に、myMenuItem_Clickを実行するよう指定します。 Protected Overrides Sub OnNavigatedTo(e As System.Windows.Navigation.NavigationEventArgs) myCameraTask = New CameraCaptureTask AddHandler myCameraTask.Completed, Sub(resultSender As Object, resultArgs As PhotoResult) If resultArgs.TaskResult = TaskResult.OK Then myImage = New BitmapImage myImage.SetSource(resultArgs.ChosenPhoto) Image1.Source = myImage Image2.Source = myImage Image3.Source = myImage Image4.Source = myImage Image5.Source = myImage Dim wb As WriteableBitmap = New WriteableBitmap(myImage) loadImage = New ExtendedImage loadImage.SetPixels(myImage.PixelWidth, myImage.PixelHeight, wb.ToByteArray()) Dim filter As Sepia filter = New Sepia filterImage = New ExtendedImage(loadImage) filter.Apply(filterImage, loadImage, New ImageTools.Rectangle(0, 0, loadImage.PixelWidth, loadImage.PixelHeight)) Dim bitmap = filterImage.ToBitmap Image1.Source = bitmap Dim filter2 As Inverter filter2 = New Inverter filterImage = New ExtendedImage(loadImage) filter2.Apply(filterImage, loadImage, New ImageTools.Rectangle(0, 0, loadImage.PixelWidth, loadImage.PixelHeight)) Dim bitmap2 = filterImage.ToBitmap Image2.Source = bitmap2 Dim filter3 As Grayscale filter3 = New GrayscaleRMY filterImage = New ExtendedImage(loadImage) filter3.Apply(filterImage, loadImage, New ImageTools.Rectangle(0, 0, loadImage.PixelWidth, loadImage.PixelHeight)) Dim bitmap3 = filterImage.ToBitmap Image3.Source = bitmap3 Dim filter4 As Brightness filter4 = New Brightness(50) filterImage = New ExtendedImage(loadImage) filter4.Apply(filterImage, loadImage, New ImageTools.Rectangle(0, 0, loadImage.PixelWidth, loadImage.PixelHeight)) Dim bitmap4 = filterImage.ToBitmap Image4.Source = bitmap4 AddHandler Image5.Hold, Sub(imageSender As Object, imageArgs As System.Windows.Input.GestureEventArgs) myMenuItem1.Header = "各種イメージフィルタ" menuItemList.Add(myMenuItem1) myContextMenu.ItemsSource = menuItemList myContextMenu.Opacity = 0.7 ContextMenuService.SetContextMenu(Image5, myContextMenu) myContextMenu.IsOpen = True End Sub AddHandler myMenuItem1.Click, AddressOf myMenuItem_Click Else Exit Sub End If End Sub MyBase.OnNavigatedTo(e) End Sub
「カメラで撮った写真に各種フィルタをかける」サンプルプログラム
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。