方法: Windows Phone 用のアプリケーションでカメラのフォーカスを使用する

2012/02/09

Windows Phone OS 7.1 を使用して、プログラムによってデバイス カメラにアクセスできます。このトピックでは、プログラムによってオートフォーカスを開始する方法および Windows Phone アプリケーションでタッチ フォーカス機能を有効にする方法について説明します。これは、「方法: Windows Phone 用の基本的なカメラ アプリケーションを作成する」の続きであり、このトピックで既に基本的なカメラ プロジェクトを作成していることを前提としています。

このトピックは 2 つの部分で構成されています。

  1. Initiating Auto-Focus

  2. Enabling Touch Focus with FocusAtPoint

ヒントヒント:

このトピックは、基本的なカメラのサンプルに対応しています。完全なプロジェクトをダウンロードするには、「Windows Phone のコード サンプル」を参照してください。

このセクションでは、[AF] ボタンがタップされたときにオートフォーカスを開始するために、UI にボタンを追加し、分離コード ファイルに必要なロジックを追加します。[AF] ボタンのイベント ハンドラーは、OnNavigatedTo メソッドで追加され、OnNavigatingFrom メソッドで削除されます。すべてのデバイスでオートフォーカスがサポートされているわけではないので、IsFocusSupported プロパティを使用して、この API が使用できるかどうかを確認します。キャプチャの実行中にフォーカスを調整しようとすると例外が発生します。Focus()()()() メソッドの呼び出しで try/catch 構文を使用してください。

注注:

このトピックは、C# 開発を基にしていますが、Visual Basic のコードも提供しています。

オートフォーカスを開始するには

  1. 方法: Windows Phone 用の基本的なカメラ アプリケーションを作成する」で作成した基本的なカメラのプロジェクトを開きます。

  2. メイン ページの XAML ファイルである MainPage.xaml ファイルで、ShutterButton というの名前の Button 要素の下にある StackPanel 要素に次のコードを追加します。このコードはカメラのフォーカス用のボタンです。

    <Button Name="AFButton" Content="AF" Click="focus_Clicked" FontSize="26" FontWeight="ExtraBold" Height="75"/>
    
    
    

    このボタンをクリックすると、focus_Clicked メソッドが呼び出されます。このメソッドについては後で説明します。

    注注:

    この演習のソフトウェア オートフォーカス ボタンは、プログラムによる PhotoCamera API へのアクセスの方法を示すためだけのものです。エンド ユーザーのエクスペリエンスを最適化するには、この機能用に、アプリケーションでカメラのハードウェア シャッター ボタンを使用することをお勧めします。ハードウェア シャッター ボタンの実装方法の詳細については、「方法: Windows Phone でハードウェア カメラのシャッター ボタンにアクセスする」を参照してください。

  3. メイン ページの分離コード ファイル (MainPage.xaml.cs) 内で、OnNavigatedTo(NavigationEventArgs) メソッドに以下のコードを追加します。このコードは AutoFocusCompleted イベント ハンドラーを実装します。

      
    // The event is fired when auto-focus is complete.
    cam.AutoFocusCompleted += new EventHandler<CameraOperationCompletedEventArgs>(cam_AutoFocusCompleted);
    
    
  4. MainPage.xaml.cs 内で、Disable UI コメントのすぐ下にある OnNavigatedTo メソッドに以下のコードを追加します。

    AFButton.IsEnabled = false;
    

    このコードはオートフォーカス ボタンを無効にします。これは、デバイス上でカメラが利用不可能である場合に使用されます。

  5. MainPage.xaml.cs で、Dispose メソッドを呼び出した後、以下のコードを OnNavigatingFrom(NavigatingCancelEventArgs) メソッドに追加します。このコードにより、カメラに関係するメモリを解放できます。

    cam.AutoFocusCompleted -= cam_AutoFocusCompleted;
    
    
  6. MainPage.xaml.cs で、次のコードを MainPage クラスに追加します。このコードは、カメラのフォーカス操作を開始することによって、focus_Clicked イベントのイベント ハンドラーを実装します。

        // Provide auto-focus in the viewfinder.
        private void focus_Clicked(object sender, System.Windows.RoutedEventArgs e)
        {
            if (cam.IsFocusSupported == true)
            {
                //Focus when a capture is not in progress.
                try
                {
                    cam.Focus();
                }
                catch (Exception focusError)
                {
                    // Cannot focus when a capture is in progress.
                    this.Dispatcher.BeginInvoke(delegate()
                    {
                        txtDebug.Text = focusError.Message;
                    });
                }
            }
            else
            {
                // Write message to UI.
                this.Dispatcher.BeginInvoke(delegate()
                {
                    txtDebug.Text = "Camera does not support programmable auto focus.";
                });
            }
        }
    
    
  7. MainPage.xaml.cs で、次のコードを MainPage クラスに追加します。このコードは、AutoFocusCompleted イベント ハンドラーを実装し、txtDebug という名前の TextBlock にメッセージを書き込みます。アプリケーション UI は別のスレッドで実行されているので、BeginInvoke メソッドが必要です。

    注注:

    フォーカス操作が完了すると、AutoFocusCompleted イベントが発生します。Focus()()()() および FocusAtPoint(Double, Double) のいずれのメソッドもフォーカス操作を開始します。

        void cam_AutoFocusCompleted(object sender, CameraOperationCompletedEventArgs e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                // Write message to UI.
                txtDebug.Text = "Auto focus has completed.";
    
            });
        }
    
    
  8. デバイスで、[デバッグ] メニューの [デバッグ開始] をクリックしてアプリケーションを実行します。

このセクションでは、ビューファインダー内のタップされた位置でフォーカスを開始するために、UI にかっこ (ビューファインダー内のタップされた位置を示す) を追加し、分離コード ファイルに必要なロジックを追加します。Windows Phone SDK 7.1 では、FocusAtPoint(Double, Double) メソッドを使用して、タッチ フォーカスを実装します。

キャンバス タップのイベント ハンドラーは、OnNavigatedTo メソッドで追加されます。すべてのデバイスでタッチ フォーカスがサポートされているわけではないので、IsFocusAtPointSupported プロパティを使用して、この API が使用できるかどうかを確認します。キャプチャの実行中にフォーカスを調整しようとすると例外が発生します。FocusAtPoint(Double, Double) メソッドの呼び出しで try/catch 構文を使用してください。

注注:

このセクションでは、前のセクション「オートフォーカスを開始する」を完了していることを前提としています。

タッチ フォーカスを実装するには

  1. メイン ページの XAML ファイルである MainPage.xaml ファイルで、Canvas コントロール内の、viewfinderBrush という名前のビデオ ブラシを含む Canvas.Background 要素の下に、次のコードを追加します。

                <!-- Brackets for Touch Focus -->
                <TextBlock 
                    x:Name="focusBrackets" 
                    Text="[   ]" 
                    FontSize="40"
                    Visibility="Collapsed"/>
    
    

    このコードは、フォーカスが行われる場所を示すために使用されるかっこを含む TextBlock 要素です。このかっこは、カメラでフォーカスを設定するときにのみ表示されます。

  2. メイン ページの分離コード ファイル (MainPage.xaml.cs) 内で、OnNavigatedTo(NavigationEventArgs) メソッドに以下のコードを追加します。

        // The event is fired when the viewfinder is tapped (for focus).
        viewfinderCanvas.Tap += new EventHandler<GestureEventArgs>(focus_Tapped);
    
    

    このコードは、キャンバス タップのイベント ハンドラーを処理します。ユーザーがビューファインダー上をタップしてタッチ フォーカスを開始すると、focus_Tapped メソッドが呼び出されます。

  3. MainPage.xaml.cs で、次のコードを MainPage クラスに追加します。

            // Provide touch focus in the viewfinder.
            void focus_Tapped(object sender, GestureEventArgs e)
            {
                if (cam != null)
                {
                    if (cam.IsFocusAtPointSupported == true)
                    {
                        try
                        {
                            // Determine the location of the tap.
                            Point tapLocation = e.GetPosition(viewfinderCanvas);
    
                            // Position the focus brackets with the estimated offsets.
                            focusBrackets.SetValue(Canvas.LeftProperty, tapLocation.X - 30);
                            focusBrackets.SetValue(Canvas.TopProperty, tapLocation.Y - 28);
    
                            // Determine the focus point.
                            double focusXPercentage = tapLocation.X / viewfinderCanvas.Width;
                            double focusYPercentage = tapLocation.Y / viewfinderCanvas.Height;
    
                            // Show the focus brackets and focus at point.
                            focusBrackets.Visibility = Visibility.Visible;
                            cam.FocusAtPoint(focusXPercentage, focusYPercentage);
    
                            // Write a message to the UI.
                            this.Dispatcher.BeginInvoke(delegate()
                            {
                                txtDebug.Text = String.Format("Camera focusing at point: {0:N2} , {1:N2}", focusXPercentage, focusYPercentage);
                            });
                        }
                        catch (Exception focusError)
                        {
                            // Cannot focus when a capture is in progress.
                            this.Dispatcher.BeginInvoke(delegate()
                            {
                                // Write a message to the UI.
                                txtDebug.Text = focusError.Message;
                                // Hide focus brackets.
                                focusBrackets.Visibility = Visibility.Collapsed;
                            });
                        }
                    }
                    else
                    {
                        // Write a message to the UI.
                        this.Dispatcher.BeginInvoke(delegate()
                        {
                            txtDebug.Text = "Camera does not support FocusAtPoint().";
                        });
                    }
                }
            }
    
    

    このコードは、フォーカスを示すかっこを配置し (予測される座標を使用)、フォーカス ポイントを特定し、フォーカスを示すかっこを表示し、タップした位置に対応するポイントでフォーカスを開始します。

    かっこの X 座標と Y 座標は、textBlock コントロールの左上に対応します。かっこを配置するときに、タップ位置を囲むようにかっこを適切に配置するために、座標の値から一定の値が減算されます。

    FocusAtPoint(Double, Double) メソッドのパラメーターは、画像のパーセンテージに基づいています。このコードを簡素化するために、カメラのビューファインダーの画像は、意図的に、タップ イベントを発生させるコントロールと同じコントロール (viewfinderCanvas という名前の Canvas コントロール) に表示されています。このアプローチによって、focus_Tapped メソッドに渡される GestureEventArgs からの座標は、直接、Canvas コントロールの幅と高さを基準とした座標になります。

  4. MainPage.xaml.cs で、次のコードを、cam_AutoFocusCompleted メソッドの BeginInvoke 呼び出し内の txtDebug ステートメントの直後に追加します。

        // Hide the focus brackets.
        focusBrackets.Visibility = Visibility.Collapsed;
    
    

    このコードは、フォーカス操作が完了した後、フォーカスを示すかっこを非表示にします。

表示: