虫眼鏡でズームするサンプルとその応用
次に、MainPage.xamlを展開して表示されるMainPage.xaml.vbをダブルクリックして、リスト4のコードを記述します。
ロジックコードを記述する
リスト4 (MainPage.xaml.vb)
Option Strict On Imports Microsoft.Devices Imports System.Windows.Media.Imaging Imports System.Windows.Threading Partial Public Class MainPage Inherits PhoneApplicationPage ' コンストラクター Public Sub New() InitializeComponent() End Sub
myCameraを、PhotoCameraクラスのメンバ変数として宣言します。このクラスは、カメラアプリケーションの基本カメラ機能を提供し、イメージ・キャプチャ、フォーカス、解像度、フラッシュ・モードなどの機能を有効にして構成するためのメンバが含まれています。
Dim myCamera As PhotoCamera
WriteableBitmap型のメンバ変数wbを宣言します。このクラスは、書き込み更新することのできるBitmapSourceを提供するクラスです。
Dim wb As WriteableBitmap
新しいDispatcherTimerクラスのインスタンスmyTimerを、メンバ変数として宣言します。このクラスは、指定した時間の間隔で処理されるタイマーを表します。
Dim myTimer As New DispatcherTimer
ページがアクティブになった時呼び出されるメソッド
RadioButtonにチェックが入り、MainPage.xamlが呼び出された時、MainPage.xamlから渡された文字データを受け取ります。文字データは、NavigationContextのQueryStringに、Dictionaryとして提供されます。
ContainsKeyメソッドで、指定したキーワード(この場合zoom)が Dictionary に格納されているかどうかを判断します。格納されている場合は、送信時のキーワード(zoom)をもとに渡された文字列情報の値(param(“zoom”))を取得し、ScaleTransformのScaleXとScaleYプロパティに指定します。
Zoomの値が0の場合はtoubaiRadioButtonにチェックが入り、3の場合は、sanbaiRadioButtonにチェックが入ります。
PhotoCamera.IsCameraTypeSupportedメソッドで、指定された種類のカメラがデバイスでサポートされているかどうかを判断します。
カメラが背面、または前面に配置されている場合は、新しいPhotoCameraのインスタンスmyCameraを作成します。AddHandlerステートメントで、カメラ オブジェクトが初期化された時に発生するInitializedイベントに、イベントハンドラを追加します。
VideoBrushのSetSourceメソッドでmyCameraオブジェクトを指定します。カメラが付いていない場合は、別スレッドからメッセージを表示します。
Protected Overrides Sub OnNavigatedTo(e As System.Windows.Navigation.NavigationEventArgs) Dim myParam As IDictionary(Of String, String) = NavigationContext.QueryString If myParam.ContainsKey("zoom") = True Then myZoom.ScaleX = CDbl(myParam("zoom")) myZoom.ScaleY = CDbl(myParam("zoom")) Select Case CDbl(myParam("zoom")) Case 0 toubaiRadioButton.IsChecked = True Case 3 sanbaiRadioButton.IsChecked = True End Select End If If (PhotoCamera.IsCameraTypeSupported(CameraType.Primary) = True Or PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) = True) Then myCamera = New PhotoCamera AddHandler myCamera.Initialized, AddressOf myCamera_Initialized myVideoBrush.SetSource(myCamera) Else Me.Dispatcher.BeginInvoke(Sub() MessageBox.Show("カメラの使用ができません。") Exit Sub End Sub) End If MyBase.OnNavigatedTo(e) End Sub
ページがアクティブでなくなった時に呼び出されるメソッド
myCameraオブジェクトに関連付けが無い場合は、RemoveHandlerメソッドでInitializedイベントを削除します。
Protected Overrides Sub OnNavigatingFrom(e As System.Windows.Navigation.NavigatingCancelEventArgs) If myCamera IsNot Nothing Then RemoveHandler myCamera.Initialized, AddressOf myCamera_Initialized End If End Sub
カメラ オブジェクトが初期化された時に発生する処理
カメラ操作が成功した場合の処理です。別スレッドから以下の処理を行います。
mainImageを表示します。イメージの、現在での解像度の幅と高さで初期化されたWriteableBitmapの新しいインスタンス、wbを作成します。mainImageのSourceプロパティにはwbオブジェクトを指定し、カメラのフラッシュモードは自動に設定します。
タイマーのIntervalプロパティに0.1ミリセコンドを指定します。タイマーをスタートします。タイマー間隔が経過すると発生するTickイベントに、イベントハンドラを指定します。イベントハンドラ内では、以下の処理を行います。
イメージの、現在の解像度での幅と高さを乗算した配列を持つ、配列変数ARGBPxを宣言します。
GetPreviewBufferArgb32メソッドで、現在のファインダーARGBフレームをバッファにコピーします。
別スレッドより、CopyToメソッドを使って、バッファをWriteableBitmapへコピーします。
WriteableBitmap.Invalidateメソッドで、ビットマップ全体を再描画します。
Private Sub myCamera_Initialized(ByVal sender As Object, ByVal e As Microsoft.Devices.CameraOperationCompletedEventArgs) If e.Succeeded Then Deployment.Current.Dispatcher.BeginInvoke(Sub() mainImage.Visibility = Visibility.Visible wb = New WriteableBitmap(CInt(myCamera.PreviewResolution.Width), CInt(myCamera.PreviewResolution.Height)) Me.mainImage.Source = wb myCamera.FlashMode = FlashMode.Auto myTimer.Interval = TimeSpan.FromSeconds(0.1) AddHandler myTimer.Tick, Sub(mySender As Object, myArgs As EventArgs) Try Dim ARGBPx(CInt(myCamera.PreviewResolution.Width) * CInt(myCamera.PreviewResolution.Height) - 1) As Integer myCamera.GetPreviewBufferArgb32(ARGBPx) Deployment.Current.Dispatcher.BeginInvoke(Sub() ARGBPx.CopyTo(wb.Pixels, 0) wb.Invalidate() End Sub) Catch Exit Sub End Try End Sub myTimer.Start() End Sub) End If End Sub
mainImageがタップされた時の処理
カメラのフォーカスを合わせます。フォーカスが完了した時に発生するmyCamera_AutoFocusCompletedイベントハンドラを実行します。
Private Sub mainImage_Tap(sender As Object, e As System.Windows.Input.GestureEventArgs) Handles mainImage.Tap myCamera.Focus() AddHandler myCamera.AutoFocusCompleted, AddressOf myCamera_AutoFocusCompleted End Sub
カメラのフォーカスが合った時に発生する処理
RemoveHandlerステートメントで、myCamera_AutoFocusCompletedイベントハンドラを削除します。
Private Sub myCamera_AutoFocusCompleted(sender As Object, e As CameraOperationCompletedEventArgs) RemoveHandler myCamera.AutoFocusCompleted, AddressOf myCamera_AutoFocusCompleted End Sub
toubaiRadioButtonがチェックされた時の処理
タイマーを中止し、引数zoomに0の値を持たせて、MainPage.xamlに遷移します。
Private Sub toubaiRadioButton_Checked(sender As Object, e As System.Windows.RoutedEventArgs) Handles toubaiRadioButton.Checked myTimer.Stop() NavigationService.Navigate(New Uri(String.Format("/MainPage.xaml?zoom={0}", 0), UriKind.Relative)) End Sub
sanbaiRadioButtonがチェックされた時の処理
タイマーを中止し、引数zoomに3の値を持たせて、MainPage.xamlに遷移します。
Private Sub sanbaiRadioButton_Checked(sender As Object, e As System.Windows.RoutedEventArgs) Handles sanbaiRadioButton.Checked myTimer.Stop() NavigationService.Navigate(New Uri(String.Format("/MainPage.xaml?zoom={0}", 3), UriKind.Relative)) End Sub End Class
今回のサンプルは以上で終了です。
【参照リンク】
PROJECT KySSでは現在、16個のWindows PhoneアプリをMarketplaceに公開しています。試用版もありますので、興味のある方はお試しください。
→参照:Windows Phone App Information(PROJECT KySS)
画像の一部を拡大するサンプル
カメラで拡大表示するサンプル