次に、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)

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30