写真とビデオのキャプチャのための手動カメラ制御Manual camera controls for photo and video capture

この記事では、光学式手ブレ補正やスムーズ ズームなど、写真とビデオのキャプチャに関する拡張シナリオを可能にするために、手動デバイス制御を使う方法について説明します。This article shows you how to use manual device controls to enable enhanced photo and video capture scenarios including optical image stabilization and smooth zoom.

この記事で説明するコントロールはすべて、同じパターンを使ってアプリに追加されます。The controls discussed in this article are all added to your app using the same pattern. まず、アプリが実行されている現在のデバイスで、コントロールがサポートされているかどうかを確認します。First, check to see if the control is supported on the current device on which your app is running. コントロールがサポートされている場合は、コントロールに対して必要なモードを設定します。If the control is supported, set the desired mode for the control. 一般的に、現在のデバイスで特定のコントロールがサポートされていない場合は、ユーザーがその機能を有効にできるような UI 要素を無効または非表示にする必要があります。Typically, if a particular control is unsupported on the current device, you should disable or hide the UI element that allows the user to enable the feature.

この記事のコードは、カメラの手動コントロール SDK のサンプルを基にしています。The code in this article was adapted from the Camera Manual Controls SDK sample. このサンプルをダウンロードし、該当するコンテキストで使用されているコードを確認することも、サンプルを独自のアプリの開始点として使用することもできます。You can download the sample to see the code used in context or to use the sample as a starting point for your own app.

注意

この記事の内容は、写真やビデオの基本的なキャプチャ機能を実装するための手順を紹介した「MediaCapture を使った基本的な写真、ビデオ、およびオーディオのキャプチャ」で取り上げた概念やコードに基づいています。This article builds on concepts and code discussed in Basic photo, video, and audio capture with MediaCapture, which describes the steps for implementing basic photo and video capture. そちらの記事で基本的なメディア キャプチャのパターンを把握してから、高度なキャプチャ シナリオに進むことをお勧めします。We recommend that you familiarize yourself with the basic media capture pattern in that article before moving on to more advanced capture scenarios. この記事で紹介しているコードは、MediaCapture のインスタンスが既に作成され、適切に初期化されていることを前提としています。The code in this article assumes that your app already has an instance of MediaCapture that has been properly initialized.

この記事で説明するデバイス制御 API はすべて、Windows.Media.Devices 名前空間のメンバーです。All of the device control APIs discussed in this article are members of the Windows.Media.Devices namespace.

using Windows.Media.Devices;

露出Exposure

ExposureControl によって、写真やビデオのキャプチャ時に使用されるシャッター速度を設定できます。The ExposureControl allows you to set the shutter speed used during photo or video capture.

この例では、スライダー コントロールを使って現在の露出値を調整し、チェック ボックスを使って自動露出調整のオンとオフを切り替えます。This example uses a Slider control to adjust the current exposure value and a checkbox to toggle automatic exposure adjustment.

<Slider Name="ExposureSlider" ValueChanged="ExposureSlider_ValueChanged"/>
<TextBlock Name="ExposureTextBlock" Text="{Binding ElementName=ExposureSlider,Path=Value}"/>
<CheckBox Name="ExposureAutoCheckBox" Content="Auto" Checked="ExposureCheckBox_CheckedChanged" Unchecked="ExposureCheckBox_CheckedChanged"/>

現在のキャプチャ デバイスで ExposureControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the ExposureControl by checking the Supported property. コントロールがサポートされている場合は、この機能の UI を表示し、有効にすることができます。If the control is supported, you can show and enable the UI for this feature. 自動露出調整が現在アクティブであるかどうかを示すために、チェック ボックスのオンの状態を Auto プロパティの値に設定します。Set the checked state of the checkbox to indicate if automatic exposure adjustment is currently active to the value of the Auto property.

露出値は、デバイスでサポートされている範囲内である必要があり、サポートされているステップ サイズのインクリメントである必要があります。The exposure value must be within the range supported by the device and must be an increment of the supported step size. 現在のデバイスでサポートされている値を取得するには、MinMax、および Step プロパティを確認します。これらのプロパティは、対応するスライダー コントロールのプロパティを設定するために使用されます。Get the supported values for the current device by checking the Min, Max, and Step properties, which are used to set the corresponding properties of the slider control.

値が設定されたときにイベントがトリガーされないように、ValueChanged イベント ハンドラーの登録を解除した後、スライダー コントロールの値を ExposureControl の現在値に設定します。Set the slider control's value to the current value of the ExposureControl after unregistering the ValueChanged event handler so that the event is not triggered when the value is set.

var exposureControl = _mediaCapture.VideoDeviceController.ExposureControl;

if (exposureControl.Supported)
{
    ExposureAutoCheckBox.Visibility = Visibility.Visible;
    ExposureSlider.Visibility = Visibility.Visible;

    ExposureAutoCheckBox.IsChecked = exposureControl.Auto;

    ExposureSlider.Minimum = exposureControl.Min.Ticks;
    ExposureSlider.Maximum = exposureControl.Max.Ticks;
    ExposureSlider.StepFrequency = exposureControl.Step.Ticks;

    ExposureSlider.ValueChanged -= ExposureSlider_ValueChanged;
    var value = exposureControl.Value;
    ExposureSlider.Value = value.Ticks;
    ExposureSlider.ValueChanged += ExposureSlider_ValueChanged;
}
else
{
    ExposureAutoCheckBox.Visibility = Visibility.Collapsed;
    ExposureSlider.Visibility = Visibility.Collapsed;
}

ValueChanged イベント ハンドラーで、コントロールの現在の値を取得し、SetValueAsync を呼び出して露出値を設定します。In the ValueChanged event handler, get the current value of the control and the set the exposure value by calling SetValueAsync.

private async void ExposureSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = TimeSpan.FromTicks((long)(sender as Slider).Value);
    await _mediaCapture.VideoDeviceController.ExposureControl.SetValueAsync(value);
}

自動露出チェック ボックスの CheckedChanged イベント ハンドラーで、SetAutoAsync を呼び出してブール値を渡すことにより、自動露出調整のオンとオフを切り替えます。In the CheckedChanged event handler of the auto exposure checkbox, turn automatic exposure adjustment on or off by calling SetAutoAsync and passing in a boolean value.

private async void ExposureCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
    if(! _isPreviewing)
    {
        // Auto exposure only supported while preview stream is running.
        return;
    }

    var autoExposure = ((sender as CheckBox).IsChecked == true);
    await _mediaCapture.VideoDeviceController.ExposureControl.SetAutoAsync(autoExposure);
}

重要

自動露出モードは、プレビュー ストリームが実行中であるときにのみサポートされます。Automatic exposure mode is only supported while the preview stream is running. 自動露出をオンにする前に、プレビュー ストリームが実行されていることを確認します。Check to make sure that the preview stream is running before turning on automatic exposure.

露出補正Exposure compensation

ExposureCompensationControl によって、写真やビデオのキャプチャ時に使用される露出補正を設定できます。The ExposureCompensationControl allows you to set the exposure compensation used during photo or video capture.

この例では、スライダー コントロールを使って、現在の露出補正値を調整します。This example uses a Slider control to adjust the current exposure compensation value.

<Slider Name="EvSlider" ValueChanged="EvSlider_ValueChanged"/>
<TextBlock Text="{Binding ElementName=EvSlider,Path=Value}" Name="EvTextBlock"/>

現在のキャプチャ デバイスで ExposureCompensationControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the ExposureCompensationControl by checking the Supported property. コントロールがサポートされている場合は、この機能の UI を表示し、有効にすることができます。If the control is supported, you can show and enable the UI for this feature.

露出補正値は、デバイスでサポートされている範囲内である必要があり、サポートされているステップ サイズのインクリメントである必要があります。The exposure compensation value must be within the range supported by the device and must be an increment of the supported step size. 現在のデバイスでサポートされている値を取得するには、MinMax、および Step プロパティを確認します。これらのプロパティは、対応するスライダー コントロールのプロパティを設定するために使用されます。Get the supported values for the current device by checking the Min, Max, and Step properties, which are used to set the corresponding properties of the slider control.

値が設定されたときにイベントがトリガーされないように、ValueChanged イベント ハンドラーの登録を解除した後、スライダー コントロールの値を ExposureCompensationControl の現在値に設定します。Set slider control's value to the current value of the ExposureCompensationControl after unregistering the ValueChanged event handler so that the event is not triggered when the value is set.

var exposureCompensationControl = _mediaCapture.VideoDeviceController.ExposureCompensationControl;

if (exposureCompensationControl.Supported)
{
    EvSlider.Visibility = Visibility.Visible;
    EvSlider.Minimum = exposureCompensationControl.Min;
    EvSlider.Maximum = exposureCompensationControl.Max;
    EvSlider.StepFrequency = exposureCompensationControl.Step;

    EvSlider.ValueChanged -= EvSlider_ValueChanged;
    EvSlider.Value = exposureCompensationControl.Value;
    EvSlider.ValueChanged += EvSlider_ValueChanged;
}
else
{
    EvSlider.Visibility = Visibility.Collapsed;
}

ValueChanged イベント ハンドラーで、コントロールの現在の値を取得し、SetValueAsync を呼び出して露出値を設定します。In the ValueChanged event handler, get the current value of the control and the set the exposure value by calling SetValueAsync.

private async void EvSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = (sender as Slider).Value;
    await _mediaCapture.VideoDeviceController.ExposureCompensationControl.SetValueAsync((float)value);
}

FlashFlash

FlashControl によって、フラッシュを有効または無効にしたり、フラッシュを使うかどうかをシステムが動的に判断する、自動フラッシュを有効にしたりすることができます。The FlashControl allows you to enable or disable the flash or to enable automatic flash, where the system dynamically determines whether to use the flash. このコントロールによって、サポートされているデバイスで自動赤目軽減を有効にすることもできます。This control also allows you to enable automatic red eye reduction on devices that support it. これらの設定はすべて写真のキャプチャに適用されます。These settings all apply to capturing photos. TorchControl は、ビデオ キャプチャ時のトーチのオンとオフを切り替える別のコントロールです。The TorchControl is a separate control for turning the torch on or off for video capture.

この例では、一連のラジオ ボタンを使って、ユーザーがオン、オフ、自動のフラッシュ設定を切り替えることができるようにします。This example uses a set of radio buttons to allow the user to switch between on, off, and auto flash settings. 赤目軽減とビデオ トーチのオンとオフを切り替えるためのチェック ボックスも用意されています。A checkbox is also provided to allow toggling of red eye reduction and the video torch.

<RadioButton Name="FlashOnRadioButton" Content="On" Checked="FlashOnRadioButton_Checked"/>
<RadioButton Name="FlashAutoRadioButton" Content="Auto" Checked="FlashAutoRadioButton_Checked"/>
<RadioButton Name="FlashOffRadioButton" Content="Off" Checked="FlashOffRadioButton_Checked"/>
<CheckBox Name="RedEyeFlashCheckBox" Content="Red Eye" Visibility="Collapsed" Checked="RedEyeFlashCheckBox_CheckedChanged" Unchecked="RedEyeFlashCheckBox_CheckedChanged"/>
<CheckBox Name="TorchCheckBox" Content="Video Light" Visibility="Collapsed" Checked="TorchCheckBox_CheckedChanged" Unchecked="TorchCheckBox_CheckedChanged"/>

現在のキャプチャ デバイスで FlashControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the FlashControl by checking the Supported property. コントロールがサポートされている場合は、この機能の UI を表示し、有効にすることができます。If the control is supported, you can show and enable the UI for this feature. FlashControl がサポートされている場合でも、自動赤目軽減はサポートされている場合とサポートされていない場合があるため、UI を有効にする前に RedEyeReductionSupported プロパティを確認します。If the FlashControl is supported, automatic red eye reduction may or may not be supported, so check the RedEyeReductionSupported property before enabling the UI. TorchControl はフラッシュ コントロールとは別であるため、使用する前にその Supported プロパティも確認する必要があります。Because the TorchControl is separate from the flash control, you must also check its Supported property before using it.

フラッシュの各ラジオ ボタンの Checked イベント ハンドラーで、適切な対応するフラッシュの設定を有効または無効にします。In the Checked event handler for each of the flash radio buttons, enable or disable the appropriate corresponding flash setting. フラッシュが常に使用されるように設定するには、Enabled プロパティを true に、Auto プロパティを false に設定する必要があります。Note that to set the flash to always be used, you must set the Enabled property to true and the Auto property to false.

var flashControl = _mediaCapture.VideoDeviceController.FlashControl;

if (flashControl.Supported)
{
    FlashAutoRadioButton.Visibility = Visibility.Visible;
    FlashOnRadioButton.Visibility = Visibility.Visible;
    FlashOffRadioButton.Visibility = Visibility.Visible;

    FlashAutoRadioButton.IsChecked = true;

    if (flashControl.RedEyeReductionSupported)
    {
        RedEyeFlashCheckBox.Visibility = Visibility.Visible;
    }

    // Video light is not strictly part of flash, but users might expect to find it there
    if (_mediaCapture.VideoDeviceController.TorchControl.Supported)
    {
        TorchCheckBox.Visibility = Visibility.Visible;
    }
}
else
{
    FlashAutoRadioButton.Visibility = Visibility.Collapsed;
    FlashOnRadioButton.Visibility = Visibility.Collapsed;
    FlashOffRadioButton.Visibility = Visibility.Collapsed;
}

private void FlashOnRadioButton_Checked(object sender, RoutedEventArgs e)
{
    _mediaCapture.VideoDeviceController.FlashControl.Enabled = true;
    _mediaCapture.VideoDeviceController.FlashControl.Auto = false;
}

private void FlashAutoRadioButton_Checked(object sender, RoutedEventArgs e)
{
    _mediaCapture.VideoDeviceController.FlashControl.Enabled = true;
    _mediaCapture.VideoDeviceController.FlashControl.Auto = true;
}

private void FlashOffRadioButton_Checked(object sender, RoutedEventArgs e)
{
    _mediaCapture.VideoDeviceController.FlashControl.Enabled = false;
}

赤目軽減チェック ボックスのハンドラーで、RedEyeReduction プロパティを適切な値に設定します。In the handler for the red eye reduction checkbox, set the RedEyeReduction property to the appropriate value.

private void RedEyeFlashCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
    _mediaCapture.VideoDeviceController.FlashControl.RedEyeReduction = (RedEyeFlashCheckBox.IsChecked == true);
}

最後に、ビデオ トーチ チェック ボックスのハンドラーで、Enabled プロパティを適切な値に設定します。Finally, in the handler for the video torch checkbox, set the Enabled property to the appropriate value.

private void TorchCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
    _mediaCapture.VideoDeviceController.TorchControl.Enabled = (TorchCheckBox.IsChecked == true);

    if(! (_isPreviewing && _isRecording))
    {
        System.Diagnostics.Debug.WriteLine("Torch may not emit light if preview and video capture are not running.");
    }
}

注意

一部のデバイスでは、TorchControl.Enabled が true に設定されている場合でも、デバイスがプレビュー ストリームを実行中で、アクティブにビデオをキャプチャ中ではない限り、トーチは発光しません。On some devices the torch will not emit light, even if TorchControl.Enabled is set to true, unless the device has a preview stream running and is actively capturing video. 推奨される処理の順序は、ビデオのプレビューを有効にし、Enabled を true に設定してトーチを有効にした後、ビデオ キャプチャを開始するという順序です。The recommended order of operations is to turn on the video preview, turn on the torch by setting Enabled to true, and then initiate video capture. 一部のデバイスでは、プレビューを開始した後もトーチが点灯しません。On some devices the torch will light up after the preview is started. その他のデバイスでは、トーチはビデオのキャプチャを開始するまで点灯しません。On other devices, the torch may not light up until video capture is started.

フォーカスFocus

FocusControl オブジェクトでは、カメラのフォーカスを調整するためによく使用される 3 種類の方法である、連続オート フォーカス、タップしてフォーカス、手動フォーカスがサポートされています。Three different commonly used methods for adjusting the focus of the camera are supported by the FocusControl object, continuous autofocus, tap to focus, and manual focus. カメラ アプリでこれらの 3 つの方法がすべてをサポートされている可能性がありますが、分かりやすくするために、この記事ではそれぞれの手法を個別に説明します。A camera app may support all three of these methods, but for readability, this article discusses each technique separately. このセクションでは、フォーカス アシスト ライトを有効にする方法も説明します。This section also discusses how to enable the focus assist light.

連続オート フォーカスContinuous autofocus

連続オート フォーカスを有効にすると、カメラに対して、動的にフォーカスを調整して、写真やビデオの被写体にフォーカスを合わせ続けるように指示されます。Enabling continuous autofocus instructs the camera to adjust the focus dynamically to try to keep the subject of the photo or video in focus. この例では、ラジオ ボタンを使用して連続オート フォーカスのオンとオフを切り替えます。This example uses a radio button to toggle continuous autofocus on and off.

<RadioButton Content="CAF" Name="CafFocusRadioButton" Checked="CafFocusRadioButton_Checked"/>

現在のキャプチャ デバイスで FocusControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the FocusControl by checking the Supported property. 次に、連続オート フォーカスがサポートされている場合は、SupportedFocusModes の一覧を確認して値 FocusMode.Continuous が含まれていることを確認します。この値が含まれている場合は、連続オート フォーカスのラジオ ボタンを表示します。Next, determine if continuous autofocus is supported by checking the SupportedFocusModes list to see if it contains the value FocusMode.Continuous, and if so, show the continuous autofocus radio button.

var focusControl = _mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{
    CafFocusRadioButton.Visibility = focusControl.SupportedFocusModes.Contains(FocusMode.Continuous) 
        ? Visibility.Visible : Visibility.Collapsed;
}
else
{
    CafFocusRadioButton.Visibility = Visibility.Collapsed;
}

連続オート フォーカス ラジオ ボタンの Checked イベント ハンドラーで、VideoDeviceController.FocusControl プロパティを使ってコントロールのインスタンスを取得します。In the Checked event handler for the continuous autofocus radio button, use the VideoDeviceController.FocusControl property to get an instance of the control. アプリが以前に LockAsync を呼び出して他のフォーカス モードのいずれかを有効にしていた場合は、UnlockAsync を呼び出してコントロールのロックを解除します。Call UnlockAsync to unlock the control in case your app has previously called LockAsync to enable one of the other focus modes.

新しい FocusSettings オブジェクトを作成し、Mode プロパティを Continuous に設定します。Create a new FocusSettings object and set the Mode property to Continuous. AutoFocusRange プロパティをアプリのシナリオに適した値またはユーザーが UI で選択した値に設定します。Set the AutoFocusRange property to a value appropriate for your app scenario or selected by the user from your UI. FocusSettings オブジェクトを Configure メソッドに渡し、FocusAsync を呼び出して連続オート フォーカスを開始します。Pass your FocusSettings object into the Configure method, and then call FocusAsync to initiate continuous autofocus.

private async void CafFocusRadioButton_Checked(object sender, RoutedEventArgs e)
{
    if(! _isPreviewing)
    {
        // Autofocus only supported while preview stream is running.
        return;
    }

    var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.UnlockAsync();
    var settings = new FocusSettings { Mode = FocusMode.Continuous, AutoFocusRange = AutoFocusRange.FullRange };
    focusControl.Configure(settings);
    await focusControl.FocusAsync();
}

重要

オート フォーカス モードは、プレビュー ストリームが実行中であるときにのみサポートされます。Autofocus mode is only supported while the preview stream is running. 連続オート フォーカスをオンにする前に、プレビュー ストリームが実行されていることを確認します。Check to make sure that the preview stream is running before turning on continuous autofocus.

タップしてフォーカスTap to focus

タップしてフォーカスの手法では、FocusControlRegionsOfInterestControl を使って、キャプチャ デバイスでフォーカスを合わせるキャプチャ フレームのサブ領域を指定します。The tap-to-focus technique uses the FocusControl and the RegionsOfInterestControl to specify a subregion of the capture frame where the capture device should focus. フォーカスの領域は、プレビュー ストリームが表示されている画面をユーザーがタップすることによって決定されます。The region of focus is determined by the user tapping on the screen displaying the preview stream.

この例では、ラジオ ボタンを使って、タップしてフォーカス モードを有効または無効にします。This example uses a radio button to enable and disable tap-to-focus mode.

<RadioButton Content="Tap" Name="TapFocusRadioButton" Checked="TapFocusRadioButton_Checked"/>

現在のキャプチャ デバイスで FocusControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the FocusControl by checking the Supported property. この手法を使うには、RegionsOfInterestControl がサポートされており、少なくとも 1 つの領域をサポートしている必要があります。The RegionsOfInterestControl must be supported, and must support at least one region, in order to use this technique. AutoFocusSupported および MaxRegions プロパティを確認して、タップしてフォーカスのラジオ ボタンを表示するか、非表示にするかを決定します。Check the AutoFocusSupported and MaxRegions properties to determine whether to show or hide the radio button for tap-to-focus.

var focusControl = _mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{
    TapFocusRadioButton.Visibility = (_mediaCapture.VideoDeviceController.RegionsOfInterestControl.AutoFocusSupported &&
                                      _mediaCapture.VideoDeviceController.RegionsOfInterestControl.MaxRegions > 0) 
                                      ? Visibility.Visible : Visibility.Collapsed;
}
else
{
    TapFocusRadioButton.Visibility = Visibility.Collapsed;
}

タップしてフォーカスのラジオ ボタンの Checked イベント ハンドラーで、VideoDeviceController.FocusControl プロパティを使ってコントロールのインスタンスを取得します。In the Checked event handler for the tap-to-focus radio button, use the VideoDeviceController.FocusControl property to get an instance of the control. アプリが以前に UnlockAsync を呼び出して連続オート フォーカスを有効にしていた場合は、LockAsync を呼び出してコントロールをロックし、ユーザーが画面をタップしてフォーカスを変更するまで待機します。Call LockAsync to lock the control in case your app has previously called UnlockAsync to enable continuous autofocus, and then wait for the user to tap the screen to change the focus.

private async void TapFocusRadioButton_Checked(object sender, RoutedEventArgs e)
{
    // Lock focus in case Continuous Autofocus was active when switching to Tap-to-focus
    var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.LockAsync();
    // Wait for user tap
}

この例は、ユーザーが画面をタップすると領域にフォーカスを合わせ、ユーザーがもう一度タップすると、トグルのように、その領域からフォーカスを削除します。This example focuses on a region when the user taps the screen, and then removes the focus from that region when the user taps again, like a toggle. 現在のトグルの状態を追跡するには、ブール変数を使います。Use a boolean variable to track the current toggled state.

bool _isFocused = false;

次の手順では、ユーザーが画面をタップしたときのイベントをリッスンします。そのためには、現在キャプチャ プレビュー ストリームを表示している CaptureElementTapped イベントを処理します。The next step is to listen for the event when the user taps the screen by handling the Tapped event of the CaptureElement that is currently displaying the capture preview stream. カメラが現在プレビューを表示していない場合や、タップしてフォーカス モードが無効である場合は、何もせずにハンドラーから制御を戻します。If the camera isn't currently previewing, or if tap-to-focus mode is disabled, return from the handler without doing anything.

場合、追跡変数 _isFocusedが false に切り替えられた場合は、カメラがフォーカスを処理中に現在と (によって決定されます、 FocusState プロパティ、 FocusControl)、タップ、フォーカスを設定するプロセスを開始します。If the tracking variable _isFocused is toggled to false, and if the camera isn't currently in the process of focus (determined by the FocusState property of the FocusControl), begin the tap-to-focus process. ハンドラーに渡されるイベント引数から、ユーザーのタップの位置を取得します。Get the position of the user's tap from the event args passed into the handler. また、この例では、この機会を利用して、フォーカスが設定される領域のサイズを取得します。This example also uses this opportunity to pick the size of the region that will be focused upon. この場合、サイズは、キャプチャ要素の最小サイズの 1/4 です。In this case, the size is 1/4 of the smallest dimension of the capture element. タップの位置と領域のサイズを、次のセクションで定義される TapToFocus ヘルパー メソッドに渡します。Pass the tap position and the region size into the TapToFocus helper method that is defined in the next section.

場合、 _isFocused切り替えが設定されているユーザーは、true にタップ以前のリージョンからフォーカスをオフにする必要があります。If the _isFocused toggle is set to true, the user tap should clear the focus from the previous region. これは、次に示す TapUnfocus ヘルパー メソッドで行われます。This is done in the TapUnfocus helper method shown below.

private async void PreviewControl_Tapped(object sender, TappedRoutedEventArgs e)
{
    if (!_isPreviewing || (TapFocusRadioButton.IsChecked != true)) return;

    if (!_isFocused && _mediaCapture.VideoDeviceController.FocusControl.FocusState != MediaCaptureFocusState.Searching)
    {
        var smallEdge = Math.Min(Window.Current.Bounds.Width, Window.Current.Bounds.Height);

        // Choose to make the focus rectangle 1/4th the length of the shortest edge of the window
        var size = new Size(smallEdge / 4, smallEdge / 4);
        var position = e.GetPosition(sender as UIElement);

        // Note that at this point, a rect at "position" with size "size" could extend beyond the preview area. The following method will reposition the rect if that is the case
        await TapToFocus(position, size);
    }
    else
    {
        await TapUnfocus();
    }
}

TapToFocusヘルパー メソッドは、最初のセット、 _isFocusedスクリーンのタップなど、[次へ] がタップされたリージョンからフォーカスを解放できるように、true に切り替えます。In the TapToFocus helper method, first set the _isFocused toggle to true so that the next screen tap will release the focus from the tapped region.

このヘルパー メソッドの次のタスクでは、フォーカス コントロールに割り当てられるプレビュー ストリーム内の四角形を決定します。The next task in this helper method is to determine the rectangle within the preview stream that will be assigned to the focus control. これには 2 つのステップが必要です。This requires two steps. 最初のステップは、CaptureElement コントロール内でプレビュー ストリームが占有する四角形を特定することです。The first step is to determine the rectangle that the preview stream takes up within the CaptureElement control. これは、プレビュー ストリームのサイズとデバイスの向きに依存します。This depends on the dimensions of the preview stream and the orientation of the device. ヘルパー メソッド GetPreviewStreamRectInControl (このセクションの最後に示されている) は、このタスクを実行し、プレビュー ストリームが含まれている四角形を返します。The helper method GetPreviewStreamRectInControl, shown at the end of this section, performs this task and returns the rectangle containing the preview stream.

TapToFocus の次のタスクは、CaptureElement.Tapped イベント ハンドラーで特定された、タップの位置と目的のフォーカスの四角形のサイズを、キャプチャ ストリーム内の座標に変換することです。The next task in TapToFocus is to convert the tap location and desired focus rectangle size, which were determined within the CaptureElement.Tapped event handler, into coordinates within capture stream. ConvertUiTapToPreviewRect ヘルパー メソッド (このセクションで後で説明されている) は、フォーカスが要求されている四角形をキャプチャ ストリームの座標で返します。The ConvertUiTapToPreviewRect helper method, shown later in this section, performs this conversion and returns the rectangle, in capture stream coordinates, where the focus will be requested.

ターゲットの四角形が取得されたら、Bounds プロパティを前の手順で取得されたターゲットの四角形に設定して、新しい RegionOfInterest オブジェクトを作成します。Now that the target rectangle has been obtained, create a new RegionOfInterest object, setting the Bounds property to the target rectangle obtained in the previous steps.

キャプチャ デバイスの FocusControl を取得します。Get the capture device's FocusControl. 新しい FocusSettings オブジェクトを作成し、FocusControl でサポートされていることを確認した後、ModeAutoFocusRange を目的の値に設定します。Create a new FocusSettings object and set the Mode and AutoFocusRange to your desired values, after checking to make sure that they are supported by the FocusControl. 最後に、FocusControlConfigure を呼び出して、設定をアクティブにし、指定された領域へのフォーカスを開始するようにデバイスに通知します。Call Configure on the FocusControl to make your settings active and signal the device to begin focusing on the specified region.

次に、キャプチャ デバイスの RegionsOfInterestControl を取得し、SetRegionsAsync を呼び出してアクティブな領域を設定します。Next, get the capture device's RegionsOfInterestControl and call SetRegionsAsync to set the active region. サポートされているデバイスでは複数の対象領域を設定できますが、この例では単一の領域のみを設定します。Multiple regions of interest can be set on devices that support it, but this example only sets a single region.

最後に、FocusControlFocusAsync を呼び出して、フォーカス設定を開始します。Finally, call FocusAsync on the FocusControl to initiate focusing.

重要

タップによるフォーカスを実装する場合、操作の順序が重要になります。When implementing tap to focus, the order of operations is important. これらの API は、次の順序で呼び出す必要があります。You should call these APIs in the following order:

  1. FocusControl.ConfigureFocusControl.Configure
  2. RegionsOfInterestControl.SetRegionsAsyncRegionsOfInterestControl.SetRegionsAsync
  3. FocusControl.FocusAsyncFocusControl.FocusAsync
public async Task TapToFocus(Point position, Size size)
{
    _isFocused = true;

    var previewRect = GetPreviewStreamRectInControl();
    var focusPreview = ConvertUiTapToPreviewRect(position, size, previewRect);

    // Note that this Region Of Interest could be configured to also calculate exposure 
    // and white balance within the region
    var regionOfInterest = new RegionOfInterest
    {
        AutoFocusEnabled = true,
        BoundsNormalized = true,
        Bounds = focusPreview,
        Type = RegionOfInterestType.Unknown,
        Weight = 100,
    };


    var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
    var focusRange = focusControl.SupportedFocusRanges.Contains(AutoFocusRange.FullRange) ? AutoFocusRange.FullRange : focusControl.SupportedFocusRanges.FirstOrDefault();
    var focusMode = focusControl.SupportedFocusModes.Contains(FocusMode.Single) ? FocusMode.Single : focusControl.SupportedFocusModes.FirstOrDefault();
    var settings = new FocusSettings { Mode = focusMode, AutoFocusRange = focusRange };
    focusControl.Configure(settings);

    var roiControl = _mediaCapture.VideoDeviceController.RegionsOfInterestControl;
    await roiControl.SetRegionsAsync(new[] { regionOfInterest }, true);

    await focusControl.FocusAsync();
}

TapUnfocus ヘルパー メソッドで、RegionsOfInterestControl を取得し、ClearRegionsAsync を呼び出して、TapToFocus ヘルパー メソッドでコントロールに登録された領域をクリアします。In the TapUnfocus helper method, obtain the RegionsOfInterestControl and call ClearRegionsAsync to clear the region that was registered with the control within the TapToFocus helper method. 次に、FocusControl を取得し、FocusAsync を呼び出して、対象領域を指定せずにデバイスで再びフォーカスを設定できるようにします。Then, get the FocusControl and call FocusAsync to cause the device to refocus without a region of interest.

private async Task TapUnfocus()
{
    _isFocused = false;

    var roiControl = _mediaCapture.VideoDeviceController.RegionsOfInterestControl;
    await roiControl.ClearRegionsAsync();

    var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.FocusAsync();
}

GetPreviewStreamRectInControl ヘルパー メソッドは、プレビュー ストリームの解像度とデバイスの向きを使い、コントロールがストリームの縦横比を維持するために提供する可能性があるレターボックス化されたパディングをトリミングして、プレビュー ストリームを含むプレビュー要素内の四角形を特定します。The GetPreviewStreamRectInControl helper method uses the resolution of the preview stream and the orientation of the device to determine the rectangle within the preview element that contains the preview stream, trimming off any letterboxed padding that the control may provide to maintain the stream's aspect ratio. このメソッドは、「MediaCapture を使った基本的な写真、ビデオ、およびオーディオのキャプチャ」に示されている基本的なメディア キャプチャのコード例で定義されているクラス メンバー変数を使います。This method uses class member variables defined in the basic media capture example code found in Basic photo, video, and audio capture with MediaCapture.

public Rect GetPreviewStreamRectInControl()
{
    var result = new Rect();

    var previewResolution = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

    // In case this function is called before everything is initialized correctly, return an empty result
    if (PreviewControl == null || PreviewControl.ActualHeight < 1 || PreviewControl.ActualWidth < 1 ||
        previewResolution == null || previewResolution.Height == 0 || previewResolution.Width == 0)
    {
        return result;
    }

    var streamWidth = previewResolution.Width;
    var streamHeight = previewResolution.Height;

    // For portrait orientations, the width and height need to be swapped
    if (_displayOrientation == DisplayOrientations.Portrait || _displayOrientation == DisplayOrientations.PortraitFlipped)
    {
        streamWidth = previewResolution.Height;
        streamHeight = previewResolution.Width;
    }

    // Start by assuming the preview display area in the control spans the entire width and height both (this is corrected in the next if for the necessary dimension)
    result.Width = PreviewControl.ActualWidth;
    result.Height = PreviewControl.ActualHeight;

    // If UI is "wider" than preview, letterboxing will be on the sides
    if ((PreviewControl.ActualWidth / PreviewControl.ActualHeight > streamWidth / (double)streamHeight))
    {
        var scale = PreviewControl.ActualHeight / streamHeight;
        var scaledWidth = streamWidth * scale;

        result.X = (PreviewControl.ActualWidth - scaledWidth) / 2.0;
        result.Width = scaledWidth;
    }
    else // Preview stream is "wider" than UI, so letterboxing will be on the top+bottom
    {
        var scale = PreviewControl.ActualWidth / streamWidth;
        var scaledHeight = streamHeight * scale;

        result.Y = (PreviewControl.ActualHeight - scaledHeight) / 2.0;
        result.Height = scaledHeight;
    }

    return result;
}

ConvertUiTapToPreviewRect ヘルパー メソッドは、引数として、タップ イベントの場所、目的のフォーカス領域のサイズ、GetPreviewStreamRectInControl ヘルパー メソッドで取得したプレビュー ストリームを含む四角形を受け取ります。The ConvertUiTapToPreviewRect helper method takes as arguments the location of the tap event, the desired size of the focus region, and the rectangle containing the preview stream obtained from the GetPreviewStreamRectInControl helper method. このメソッドは、これらの値とデバイスの現在の向きを使って、目的の地域を含むプレビュー ストリーム内の四角形を計算します。This method uses these values and the device's current orientation to calculate the rectangle within the preview stream that contains the desired region. ここでも、このメソッドは、「MediaCapture を使った写真とビデオのキャプチャ」に示されている基本的なメディア キャプチャのコード例で定義されているクラス メンバー変数を使います。Once again, this method uses class member variables defined in the basic media capture example code found in Capture Photos and Video with MediaCapture.

private Rect ConvertUiTapToPreviewRect(Point tap, Size size, Rect previewRect)
{
    // Adjust for the resulting focus rectangle to be centered around the position
    double left = tap.X - size.Width / 2, top = tap.Y - size.Height / 2;

    // Get the information about the active preview area within the CaptureElement (in case it's letterboxed)
    double previewWidth = previewRect.Width, previewHeight = previewRect.Height;
    double previewLeft = previewRect.Left, previewTop = previewRect.Top;

    // Transform the left and top of the tap to account for rotation
    switch (_displayOrientation)
    {
        case DisplayOrientations.Portrait:
            var tempLeft = left;

            left = top;
            top = previewRect.Width - tempLeft;
            break;
        case DisplayOrientations.LandscapeFlipped:
            left = previewRect.Width - left;
            top = previewRect.Height - top;
            break;
        case DisplayOrientations.PortraitFlipped:
            var tempTop = top;

            top = left;
            left = previewRect.Width - tempTop;
            break;
    }

    // For portrait orientations, the information about the active preview area needs to be rotated
    if (_displayOrientation == DisplayOrientations.Portrait || _displayOrientation == DisplayOrientations.PortraitFlipped)
    {
        previewWidth = previewRect.Height;
        previewHeight = previewRect.Width;
        previewLeft = previewRect.Top;
        previewTop = previewRect.Left;
    }

    // Normalize width and height of the focus rectangle
    var width = size.Width / previewWidth;
    var height = size.Height / previewHeight;

    // Shift rect left and top to be relative to just the active preview area
    left -= previewLeft;
    top -= previewTop;

    // Normalize left and top
    left /= previewWidth;
    top /= previewHeight;

    // Ensure rectangle is fully contained within the active preview area horizontally
    left = Math.Max(left, 0);
    left = Math.Min(1 - width, left);

    // Ensure rectangle is fully contained within the active preview area vertically
    top = Math.Max(top, 0);
    top = Math.Min(1 - height, top);

    // Create and return resulting rectangle
    return new Rect(left, top, width, height);
}

手動フォーカスManual focus

手動フォーカスの手法では、スライダー コントロールを使って、キャプチャ デバイスの現在フォーカスの深度を設定します。The manual focus technique uses a Slider control to set the current focus depth of the capture device. ラジオ ボタンを使って、手動フォーカスのオンとオフを切り替えます。A radio button is used to toggle manual focus on and off.

<Slider Name="FocusSlider" IsEnabled="{Binding ElementName=ManualFocusRadioButton,Path=IsChecked}" ValueChanged="FocusSlider_ValueChanged"/>
<TextBlock Text="{Binding ElementName=FocusSlider,Path=Value,FallbackValue='0'}"/>
<RadioButton Content="Manual" Name="ManualFocusRadioButton" Checked="ManualFocusRadioButton_Checked" IsChecked="False"/>

現在のキャプチャ デバイスで FocusControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the FocusControl by checking the Supported property. コントロールがサポートされている場合は、この機能の UI を表示し、有効にすることができます。If the control is supported, you can show and enable the UI for this feature.

フォーカス値は、デバイスでサポートされている範囲内である必要があり、サポートされているステップ サイズのインクリメントである必要があります。The focus value must be within the range supported by the device and must be an increment of the supported step size. 現在のデバイスでサポートされている値を取得するには、MinMax、および Step プロパティを確認します。これらのプロパティは、対応するスライダー コントロールのプロパティを設定するために使用されます。Get the supported values for the current device by checking the Min, Max, and Step properties, which are used to set the corresponding properties of the slider control.

値が設定されたときにイベントがトリガーされないように、ValueChanged イベント ハンドラーの登録を解除した後、スライダー コントロールの値を FocusControl の現在値に設定します。Set the slider control's value to the current value of the FocusControl after unregistering the ValueChanged event handler so that the event is not triggered when the value is set.

var focusControl = _mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{
    FocusSlider.Visibility = Visibility.Visible;
    ManualFocusRadioButton.Visibility = Visibility.Visible;

    FocusSlider.Minimum = focusControl.Min;
    FocusSlider.Maximum = focusControl.Max;
    FocusSlider.StepFrequency = focusControl.Step;
    

    FocusSlider.ValueChanged -= FocusSlider_ValueChanged;
    FocusSlider.Value = focusControl.Value;
    FocusSlider.ValueChanged += FocusSlider_ValueChanged;
}
else
{
    FocusSlider.Visibility = Visibility.Collapsed;
    ManualFocusRadioButton.Visibility = Visibility.Collapsed;
}

アプリが以前に UnlockAsync を呼び出してフォーカスのロックを解除していた場合は、手動フォーカスのラジオ ボタンの Checked イベント ハンドラーで、FocusControl オブジェクトを取得し、LockAsync を呼び出します。In the Checked event handler for the manual focus radio button, get the FocusControl object and call LockAsync in case your app had previously unlocked the focus with a call to UnlockAsync.

private async void ManualFocusRadioButton_Checked(object sender, RoutedEventArgs e)
{
    var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.LockAsync();
}

手動フォーカス スライダーの ValueChanged イベント ハンドラーで、コントロールの現在の値を取得し、SetValueAsync を呼び出してフォーカス値を設定します。In the ValueChanged event handler of the manual focus slider, get the current value of the control and the set the focus value by calling SetValueAsync.

private async void FocusSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = (sender as Slider).Value;
    await _mediaCapture.VideoDeviceController.FocusControl.SetValueAsync((uint)value);
}

フォーカス ライトの有効化Enable the focus light

サポートされているデバイスで、デバイスのフォーカスを支援するフォーカス アシスト ライトを有効にすることができます。On devices that support it, you can enable a focus assist light to help the device focus. この例では、チェック ボックスを使って、フォーカス アシスト ライトを有効または無効にします。This example uses a checkbox to enable or disable the focus assist light.

<CheckBox Content="Assist Light" Name="FocusLightCheckBox" IsEnabled="{Binding ElementName=TapFocusRadioButton,Path=IsChecked}"
                  Checked="FocusLightCheckBox_CheckedChanged" Unchecked="FocusLightCheckBox_CheckedChanged"/>

現在のキャプチャ デバイスで FlashControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the FlashControl by checking the Supported property. また、AssistantLightSupported を確認してアシスト ライトがサポートされていることも確認します。Also check the AssistantLightSupported to make sure the assist light is also supported. これらがいずれもサポートされている場合は、この機能の UI を表示し、有効にすることができます。If these are both supported, you can show and enable the UI for this feature.

var focusControl = _mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{

    FocusLightCheckBox.Visibility = (_mediaCapture.VideoDeviceController.FlashControl.Supported &&
                                     _mediaCapture.VideoDeviceController.FlashControl.AssistantLightSupported) ? Visibility.Visible : Visibility.Collapsed;
}
else
{
    FocusLightCheckBox.Visibility = Visibility.Collapsed;
}

CheckedChanged イベント ハンドラーで、キャプチャ デバイスの FlashControl オブジェクトを取得します。In the CheckedChanged event handler, get the capture devices FlashControl object. AssistantLightEnabled プロパティを設定して、フォーカス ライトを有効または無効にします。Set the AssistantLightEnabled property to enable or disable the focus light.

private void FocusLightCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
    var flashControl = _mediaCapture.VideoDeviceController.FlashControl;

    flashControl.AssistantLightEnabled = (FocusLightCheckBox.IsChecked == true);
}

ISO 速度ISO speed

IsoSpeedControl によって、写真やビデオのキャプチャ時に使用される ISO 速度を設定できます。The IsoSpeedControl allows you to set the ISO speed used during photo or video capture.

この例では、スライダー コントロールを使って現在の露出補正値を調整し、チェック ボックスを使って自動 ISO 速度調整のオンとオフを切り替えます。This example uses a Slider control to adjust the current exposure compensation value and a checkbox to toggle automatic ISO speed adjustment.

<Slider Name="IsoSlider" ValueChanged="IsoSlider_ValueChanged"/>
<TextBlock Text="{Binding ElementName=IsoSlider,Path=Value}" Visibility="{Binding ElementName=IsoSlider,Path=Visibility}"/>
<CheckBox Name="IsoAutoCheckBox" Content="Auto" Checked="IsoAutoCheckBox_CheckedChanged" Unchecked="IsoAutoCheckBox_CheckedChanged"/>

現在のキャプチャ デバイスで IsoSpeedControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the IsoSpeedControl by checking the Supported property. コントロールがサポートされている場合は、この機能の UI を表示し、有効にすることができます。If the control is supported, you can show and enable the UI for this feature. 自動 ISO 速度調整が現在アクティブであるかどうかを示すために、チェック ボックスのオンの状態を Auto プロパティの値に設定します。Set the checked state of the checkbox to indicate if automatic ISO speed adjustment is currently active to the value of the Auto property.

ISO 速度値は、デバイスでサポートされている範囲内である必要があり、サポートされているステップ サイズのインクリメントである必要があります。The ISO speed value must be within the range supported by the device and must be an increment of the supported step size. 現在のデバイスでサポートされている値を取得するには、MinMax、および Step プロパティを確認します。これらのプロパティは、対応するスライダー コントロールのプロパティを設定するために使用されます。Get the supported values for the current device by checking the Min, Max, and Step properties, which are used to set the corresponding properties of the slider control.

値が設定されたときにイベントがトリガーされないように、ValueChanged イベント ハンドラーの登録を解除した後、スライダー コントロールの値を IsoSpeedControl の現在値に設定します。Set the slider control's value to the current value of the IsoSpeedControl after unregistering the ValueChanged event handler so that the event is not triggered when the value is set.

private void UpdateIsoControlCapabilities()
{
    var isoSpeedControl = _mediaCapture.VideoDeviceController.IsoSpeedControl;

    if (isoSpeedControl.Supported)
    {
        IsoAutoCheckBox.Visibility = Visibility.Visible;
        IsoSlider.Visibility = Visibility.Visible;

        IsoAutoCheckBox.IsChecked = isoSpeedControl.Auto;
        
        IsoSlider.Minimum = isoSpeedControl.Min;
        IsoSlider.Maximum = isoSpeedControl.Max;
        IsoSlider.StepFrequency = isoSpeedControl.Step;

        IsoSlider.ValueChanged -= IsoSlider_ValueChanged;
        IsoSlider.Value = isoSpeedControl.Value;
        IsoSlider.ValueChanged += IsoSlider_ValueChanged;
    }
    else
    {
        IsoAutoCheckBox.Visibility = Visibility.Collapsed;
        IsoSlider.Visibility = Visibility.Collapsed;
    }
}

ValueChanged イベント ハンドラーで、コントロールの現在の値を取得し、SetValueAsync を呼び出して ISO 速度を設定します。In the ValueChanged event handler, get the current value of the control and the set the ISO speed value by calling SetValueAsync.

private async void IsoSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = (sender as Slider).Value;
    await _mediaCapture.VideoDeviceController.IsoSpeedControl.SetValueAsync((uint)value);
}

自動 ISO 速度チェック ボックスの CheckedChanged イベント ハンドラーで、SetAutoAsync を呼び出すことによって、自動 ISO 速度調整をオンにします。In the CheckedChanged event handler of the auto ISO speed checkbox, turn on automatic ISO speed adjustment by calling SetAutoAsync. 自動 ISO 速度調整をオフにするには、SetValueAsync を呼び出して、スライダー コントロールの現在の値を渡します。Turn automatic ISO speed adjustment off by calling SetValueAsync and passing in the current value of the slider control.

private async void IsoAutoCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
    var autoIso = (sender as CheckBox).IsChecked == true;

    if (autoIso)
    {
        await _mediaCapture.VideoDeviceController.IsoSpeedControl.SetAutoAsync();
    }
    else
    {
        await _mediaCapture.VideoDeviceController.IsoSpeedControl.SetValueAsync((uint)IsoSlider.Value);
    }
}

光学式手ブレ補正Optical image stabilization

光学式手ブレ補正 (OIS) は、ハードウェア キャプチャ デバイスを物理的に操作することで、キャプチャしたビデオ ストリームを補正します。これにより、デジタル補正より優れた結果が生まれます。Optical image stabilization (OIS) stabilizes a the captured video stream by mechanically manipulating the hardware capture device, which can provide a superior result than digital stabilization. OIS がサポートされていないデバイスでは、VideoStabilizationEffect を使用して、キャプチャしたビデオにデジタル手ブレ補正を行うことができます。On devices that don't support OIS, you can use the VideoStabilizationEffect to perform digital stabilization on your captured vide. 詳しくは、「ビデオ キャプチャの効果」をご覧ください。For more information, see Effects for video capture.

現在のデバイスで OIS がサポートされているかどうかを確認するには、OpticalImageStabilizationControl.Supported プロパティをチェックします。Determine if OIS is supported on the current device by checking the OpticalImageStabilizationControl.Supported property.

OIS コントロールでは、3 つのモード (オン、オフ、自動) がサポートされています。自動モードでは、OIS によってメディア キャプチャが改善されるかどうかをデバイスが動的に判断し、改善される場合は OIS が有効になります。The OIS control supports three modes: on, off, and automatic, which means that the device dynamically determines if OIS would improve the media capture and, if so, enables OIS. 現在のデバイスで特定のモードがサポートされているかどうかを確認するには、OpticalImageStabilizationControl.SupportedModes コレクションに目的のモードが含まれているかどうかをチェックします。To determine if a particular mode is supported on a device, check to see if the OpticalImageStabilizationControl.SupportedModes collection contains the desired mode.

OIS を有効または無効にするには、OpticalImageStabilizationControl.Mode を目的のモードに設定します。Enable or disable OIS by setting the OpticalImageStabilizationControl.Mode to the desired mode.

private void SetOpticalImageStabilizationMode(OpticalImageStabilizationMode mode)
{
    if (!_mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.Supported)
    {
        ShowMessageToUser("Optical image stabilization not available");
        return;
    }

    var stabilizationModes = _mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.SupportedModes;

    if (!stabilizationModes.Contains(mode))
    {
        ShowMessageToUser("Optical image stabilization setting not supported");
        return;
    }

    _mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.Mode = mode;
}

電源周波数Powerline frequency

一部のカメラ デバイスでは、現在の環境の AC 電源周波数を認識し、それに応じたアンチフリッカー処理をサポートします。Some camera devices support anti-flicker processing that depends on knowing the AC frequency of the powerlines in the current environment. 電源周波数の自動認識をサポートするデバイスもあれば、周波数を手動で設定する必要があるデバイスもあります。Some devices support automatic determination of the powerline frequency, while others require that the frequency be set manually. 次のコード例は、デバイスの電源周波数のサポートを判別し、必要に応じて、周波数を手動で設定する方法を示します。The following code example shows how to determine powerline frequency support on the device and, if needed, how to set the frequency manually.

まず PowerlineFrequency 型の出力パラメーターを渡して VideoDeviceController メソッド TryGetPowerlineFrequency を呼び出します。この呼び出しが失敗した場合、現在のデバイスでは電源周波数の制御がサポートされていません。First, call the VideoDeviceController method TryGetPowerlineFrequency, passing in an output parameter of type PowerlineFrequency; if this call fails, the powerline frequency control is not supported on the current device. 機能がサポートされている場合、自動モードの設定を試みることで、自動モードがサポートされているかどうかを確認できます。If the feature is supported, you can determine if automatic mode is available on the device by trying to set auto mode. これを行うには、値 Auto を渡して TrySetPowerlineFrequency を呼び出します。呼び出しに成功した場合、自動電源周波数機能がサポートされています。Do this by calling TrySetPowerlineFrequency and passing in the value Auto. If the call succeeds, that means that your auto powerline frequency is supported. デバイスで電源周波数の制御はサポートされているが、周波数の自動検出はサポートされていない場合、TrySetPowerlineFrequency を使って周波数を手動で設定できます。If the powerline frequency controller is supported on the device but automatic frequency detection is not, you can still manually set the frequency by using TrySetPowerlineFrequency. 次の例で、MyCustomFrequencyLookup は、デバイスの現在の場所における正しい周波数を判定するために実装するカスタム メソッドです。In this example, MyCustomFrequencyLookup is a custom method that you implement to determine the correct frequency for the device's current location.

 PowerlineFrequency getFrequency;

 if (! _mediaCapture.VideoDeviceController.TryGetPowerlineFrequency(out getFrequency))
 {
     // Powerline frequency is not supported on this device.
     return;
 }

 if (! _mediaCapture.VideoDeviceController.TrySetPowerlineFrequency(PowerlineFrequency.Auto))
 {
     // Set the frequency manually
     PowerlineFrequency setFrequency = MyCustomFrequencyLookup();
     if (_mediaCapture.VideoDeviceController.TrySetPowerlineFrequency(setFrequency))
     {
         System.Diagnostics.Debug.WriteLine(String.Format("Powerline frequency manually set to {0}.", setFrequency));
     }
 }

ホワイト バランスWhite balance

WhiteBalanceControl によって、写真やビデオのキャプチャ時に使用されるホワイト バランスを設定できます。The WhiteBalanceControl allows you to set the white balance used during photo or video capture.

この例では、ComboBox コントロールを使って組み込みの色温度のプリセットを選択し、スライダー コントロールを使って手動でホワイト バランスを調整します。This example uses a ComboBox control to select from built-in color temperature presets and a Slider control for manual white balance adjustment.

<Slider Name="WbSlider" ValueChanged="WbSlider_ValueChanged"/>
<TextBlock Name="WbTextBox" Text="{Binding ElementName=WbSlider,Path=Value}" Visibility="{Binding ElementName=WbSlider,Path=Visibility}"/>
<ComboBox Name="WbComboBox" SelectionChanged="WbComboBox_SelectionChanged"/>

現在のキャプチャ デバイスで WhiteBalanceControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the WhiteBalanceControl by checking the Supported property. コントロールがサポートされている場合は、この機能の UI を表示し、有効にすることができます。If the control is supported, you can show and enable the UI for this feature. コンボ ボックスの項目を、ColorTemperaturePreset 列挙体の値に設定します。Set the items of the combo box to the values of the ColorTemperaturePreset enumeration. また、選ばれた項目を、Preset プロパティの現在の値に設定します。And set the selected item to the current value of the Preset property.

手動コントロールの場合、ホワイト バランス値は、デバイスでサポートされている範囲内である必要があり、サポートされているステップ サイズのインクリメントである必要があります。For manual control, the white balance value must be within the range supported by the device and must be an increment of the supported step size. 現在のデバイスでサポートされている値を取得するには、MinMax、および Step プロパティを確認します。これらのプロパティは、対応するスライダー コントロールのプロパティを設定するために使用されます。Get the supported values for the current device by checking the Min, Max, and Step properties, which are used to set the corresponding properties of the slider control. 手動コントロールを有効にする前に、サポートされている最小値と最大値の間の範囲がステップ サイズよりも大きいことを確認します。Before enabling manual control, check to make sure that the range between the minimum and maximum supported values is greater than the step size. このようになっていない場合、手動コントロールは、現在のデバイスではサポートされません。If it is not, manual control is not supported on the current device.

値が設定されたときにイベントがトリガーされないように、ValueChanged イベント ハンドラーの登録を解除した後、スライダー コントロールの値を WhiteBalanceControl の現在値に設定します。Set the slider control's value to the current value of the WhiteBalanceControl after unregistering the ValueChanged event handler so that the event is not triggered when the value is set.

           var whiteBalanceControl = _mediaCapture.VideoDeviceController.WhiteBalanceControl;

           if (whiteBalanceControl.Supported)
           {
               WbSlider.Visibility = Visibility.Visible;
               WbComboBox.Visibility = Visibility.Visible;

               if (WbComboBox.ItemsSource == null)
               {
                   WbComboBox.ItemsSource = Enum.GetValues(typeof(ColorTemperaturePreset)).Cast<ColorTemperaturePreset>();
               }

               WbComboBox.SelectedItem = whiteBalanceControl.Preset;

               if (whiteBalanceControl.Max - whiteBalanceControl.Min > whiteBalanceControl.Step)
               {

                   WbSlider.Minimum = whiteBalanceControl.Min;
                   WbSlider.Maximum = whiteBalanceControl.Max;
                   WbSlider.StepFrequency = whiteBalanceControl.Step;

                   WbSlider.ValueChanged -= WbSlider_ValueChanged;
                   WbSlider.Value = whiteBalanceControl.Value;
                   WbSlider.ValueChanged += WbSlider_ValueChanged;
               }
               else
               {
                   WbSlider.Visibility = Visibility.Collapsed;
               }
           }
           else
           {
               WbSlider.Visibility = Visibility.Collapsed;
               WbComboBox.Visibility = Visibility.Collapsed;
           }

色温度プリセットのコンボ ボックスの SelectionChanged イベント ハンドラーで、現在選択されているプリセットを取得し、SetPresetAsync を呼び出してコントロールの値を設定します。In the SelectionChanged event handler of the color temperature preset combo box, get the currently selected preset and set the value of the control by calling SetPresetAsync. 選択されたプリセット値が Manual でない場合は、手動のホワイト バランス スライダーを無効にします。If the selected preset value is not Manual, disable the manual white balance slider.

private async void WbComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if(!_isPreviewing)
    {
        // Do not set white balance values unless the preview stream is running.
        return;
    }

    var selected = (ColorTemperaturePreset)WbComboBox.SelectedItem;
    WbSlider.IsEnabled = (selected == ColorTemperaturePreset.Manual);
    await _mediaCapture.VideoDeviceController.WhiteBalanceControl.SetPresetAsync(selected);

}

ValueChanged イベント ハンドラーで、コントロールの現在の値を取得し、SetValueAsync を呼び出してホワイト バランス値を設定します。In the ValueChanged event handler, get the current value of the control and the set the white balance value by calling SetValueAsync.

private async void WbSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    if (!_isPreviewing)
    {
        // Do not set white balance values unless the preview stream is running.
        return;
    }

    var value = (sender as Slider).Value;
    await _mediaCapture.VideoDeviceController.WhiteBalanceControl.SetValueAsync((uint)value);
}

重要

ホワイト バランスの調整は、プレビュー ストリームが実行中であるときにのみサポートされます。Adjusting the white balance is only supported while the preview stream is running. ホワイト バランス値またはプリセットを設定する前に、プレビュー ストリームが実行されていることを確認します。Check to make sure that the preview stream is running before setting the white balance value or preset.

重要

ColorTemperaturePreset.Auto プリセット値は、ホワイト バランス レベルを自動調整するようにシステムに指示します。The ColorTemperaturePreset.Auto preset value instructs the system to automatically adjust the white balance level. ホワイト バランス レベルが各フレームで同じである必要がある写真シーケンスのキャプチャなど、一部のシナリオでは、現在の自動値にコントロールをロックすることもできます。For some scenarios, such as capturing a photo sequence where the white balance levels should be the same for each frame, you may want to lock the control to the current automatic value. これを行うには、SetPresetAsync を呼び出して、Manual プリセットを指定します。SetValueAsync を使って、コントロールの値を設定しないでください。To do this, call SetPresetAsync and specify the Manual preset and do not set a value on the control using SetValueAsync. これにより、デバイスは現在の値にロックされます。This will cause the device to lock the current value. 現在のコントロールの値を読み取って、返された値を SetValueAsync に渡すことはしないでください。この値が正しいことは保証されないためです。Do not attempt to read the current control value and then pass the returned value into SetValueAsync because this value is not guaranteed to be correct.

ズームZoom

ZoomControl によって、写真やビデオのキャプチャ時に使用されるズーム レベルを設定できます。The ZoomControl allows you to set the zoom level used during photo or video capture.

この例では、スライダー コントロールを使って、現在のズーム レベルを調整します。This example uses a Slider control to adjust the current zoom level. 次のセクションでは、画面上のピンチ ジェスチャに基づいてズームを調整する方法を示します。The following section shows how to adjust zoom based on a pinch gesture on the screen.

<Slider Name="ZoomSlider" Grid.Row="0" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Stretch" ValueChanged="ZoomSlider_ValueChanged"/>
<TextBlock Grid.Row="1" HorizontalAlignment="Center" Text="{Binding ElementName=ZoomSlider,Path=Value}"/>

現在のキャプチャ デバイスで ZoomControl がサポートされているかどうかを確認するには、Supported プロパティを確認します。Check to see if the current capture device supports the ZoomControl by checking the Supported property. コントロールがサポートされている場合は、この機能の UI を表示し、有効にすることができます。If the control is supported, you can show and enable the UI for this feature.

ズーム レベル値は、デバイスでサポートされている範囲内である必要があり、サポートされているステップ サイズのインクリメントである必要があります。The zoom level value must be within the range supported by the device and must be an increment of the supported step size. 現在のデバイスでサポートされている値を取得するには、MinMax、および Step プロパティを確認します。これらのプロパティは、対応するスライダー コントロールのプロパティを設定するために使用されます。Get the supported values for the current device by checking the Min, Max, and Step properties, which are used to set the corresponding properties of the slider control.

値が設定されたときにイベントがトリガーされないように、ValueChanged イベント ハンドラーの登録を解除した後、スライダー コントロールの値を ZoomControl の現在値に設定します。Set the slider control's value to the current value of the ZoomControl after unregistering the ValueChanged event handler so that the event is not triggered when the value is set.

var zoomControl = _mediaCapture.VideoDeviceController.ZoomControl;

if (zoomControl.Supported)
{
    ZoomSlider.Visibility = Visibility.Visible;

    ZoomSlider.Minimum = zoomControl.Min;
    ZoomSlider.Maximum = zoomControl.Max;
    ZoomSlider.StepFrequency = zoomControl.Step;
    
    ZoomSlider.ValueChanged -= ZoomSlider_ValueChanged;
    ZoomSlider.Value = zoomControl.Value;
    ZoomSlider.ValueChanged += ZoomSlider_ValueChanged;
}
else
{
    ZoomSlider.Visibility = Visibility.Collapsed;
}

ValueChanged イベント ハンドラーで、Value プロパティをズーム スライダー コントロールの現在の値に設定して、ZoomSettings クラスの新しいインスタンスを作成します。In the ValueChanged event handler, create a new instance of the ZoomSettings class, setting the Value property to the current value of the zoom slider control. ZoomControlSupportedModes プロパティに ZoomTransitionMode.Smooth が含まれている場合、デバイスがズーム レベルのスムーズな切り替えをサポートしていることを意味します。If the SupportedModes property of the ZoomControl contains ZoomTransitionMode.Smooth, it means the device supports smooth transitions between zoom levels. このモードではユーザー エクスペリエンスが向上するため、通常、ZoomSettings オブジェクトの Mode プロパティにはこの値を使います。Since this modes provides a better user experience, you will typically want to use this value for the Mode property of the ZoomSettings object.

最後に、ZoomSettings オブジェクトを、ZoomControl オブジェクトの Configure メソッドに渡すことによって、現在のズーム設定を変更します。Finally, change the current zoom settings by passing your ZoomSettings object into the Configure method of the ZoomControl object.

private void ZoomSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var level = (float)ZoomSlider.Value;
    var settings = new ZoomSettings { Value = level };

    var zoomControl = _mediaCapture.VideoDeviceController.ZoomControl;
    if (zoomControl.SupportedModes.Contains(ZoomTransitionMode.Smooth))
    {
        settings.Mode = ZoomTransitionMode.Smooth;
    }
    else
    {
        settings.Mode = zoomControl.SupportedModes.First();
    }

    zoomControl.Configure(settings);
}

ピンチ ジェスチャを使ったスムーズなズームSmooth zoom using pinch gesture

前のセクションで説明したように、スムーズ ズームがサポートされているキャプチャ デバイスでスムーズ ズーム モードを使用すると、異なるデジタル ズーム レベル間での切り替えがスムーズになります。これによりユーザーは、キャプチャ操作中にズーム レベルを動的に調整することができます。切り替えを個々に行う必要がなく、不快感もありません。As discussed in the previous section, on devices that support it, smooth zoom mode allows the capture device to smoothly transition between digital zoom levels, allowing the user to dynamically adjust the zoom level during the capture operation without discrete and jarring transitions. このセクションでは、ピンチ ジェスチャに応答してズーム レベルを調整する方法について説明します。This section describes how to adjust the zoom level in response to a pinch gesture.

まず、ZoomControl.Supported プロパティをチェックして、現在のデバイスでデジタル ズーム コントロールがサポートされているかどうかを確認します。First, determine if the digital zoom control is supported on the current device by checking the ZoomControl.Supported property. 次に、ZoomControl.SupportedModes の値として ZoomTransitionMode.Smooth が含まれているかどうかをチェックすることによって、スムーズ ズーム モードが利用可能かどうかを確認します。Next, determine if smooth zoom mode is available by checking the ZoomControl.SupportedModes to see if it contains the value ZoomTransitionMode.Smooth.

private bool IsSmoothZoomSupported()
{
    if (!_mediaCapture.VideoDeviceController.ZoomControl.Supported)
    {
        ShowMessageToUser("Digital zoom is not supported on this device.");
        return false;
    }

    var zoomModes = _mediaCapture.VideoDeviceController.ZoomControl.SupportedModes;

    if (!zoomModes.Contains(ZoomTransitionMode.Smooth))
    {
        ShowMessageToUser("Smooth zoom not supported");
        return false;
    }

    return true;
}

マルチタッチ操作対応デバイスでは、2 本指でのピンチ ジェスチャに基づいてズーム倍率を調整するのが一般的です。On a multi-touch enabled device, a typical scenario is to adjust the zoom factor based on a two-finger pinch gesture. ピンチ ジェスチャを有効にするには、CaptureElement コントロールの ManipulationMode プロパティを ManipulationModes.Scale に設定します。Set the ManipulationMode property of the CaptureElement control to ManipulationModes.Scale to enable the pinch gesture. 次に、ピンチ ジェスチャでサイズ変更されたときに発生する ManipulationDelta イベントを登録します。Then, register for the ManipulationDelta event which is raised when the pinch gesture changes size.

private void RegisterPinchGestureHandler()
{
    if (!IsSmoothZoomSupported())
    {
        return;
    }

    // Enable pinch/zoom gesture for the preview control
    PreviewControl.ManipulationMode = ManipulationModes.Scale;
    PreviewControl.ManipulationDelta += PreviewControl_ManipulationDelta;
}

ManipulationDelta イベント用のハンドラーでは、ユーザーのピンチ ジェスチャの変化に基づいてズーム倍率を更新します。In the handler for the ManipulationDelta event, update the zoom factor based on the change in the user's pinch gesture. ManipulationDelta.Scale 値は、ピンチ ジェスチャによるズーム倍率の変化を表します。たとえば、ピンチ サイズがわずかに大きくなった場合は 1.0 よりわずかに大きい数値、ピンチ サイズがわずかに小さくなった場合は 1.0 よりわずかに小さい数値になります。The ManipulationDelta.Scale value represents the change in scale of the pinch gesture such that a small increase in the size of the pinch is a number slightly larger than 1.0 and a small decrease in the pinch size is a number slightly smaller than 1.0. この例では、ズーム コントロールの現在の値にスケール デルタを掛けています。In this example, the current value of the zoom control is multiplied by the scale delta.

ズーム倍率を設定する前に、デバイスでサポートされている (ZoomControl.Min プロパティで示されている) 最小値より小さい値になっていないか確認する必要があります。Before setting the zoom factor, you must make sure that the value is not less than the minimum value supported by the device as indicated by the ZoomControl.Min property. また、値が ZoomControl.Max 値以下であることを確認します。Also, make sure that the value is less than or equal to the ZoomControl.Max value. 最後に、行う必要があります、ズームの倍率がで示されている、デバイスでサポートされるズーム ステップ サイズの倍数であることを確認、 手順プロパティ。Finally, you must make sure that the zoom factor is a multiple of the zoom step size supported by the device as indicated by the Step property. ズーム倍率がこれらの要件を満たしていない場合は、キャプチャ デバイスでズーム レベルを設定しようとすると、例外がスローされます。If your zoom factor does not meet these requirements, an exception will be thrown when you attempt to set the zoom level on the capture device.

キャプチャ デバイスでズーム レベルを設定するには、新しい ZoomSettings オブジェクトを作成します。Set the zoom level on the capture device by creating a new ZoomSettings object. Mode プロパティを ZoomTransitionMode.Smooth に設定し、Value プロパティを目的のズーム倍率に設定します。Set the Mode property to ZoomTransitionMode.Smooth and then set the Value property to your desired zoom factor. 最後に、ZoomControl.Configure を呼び出して、デバイスの新しいズーム値を設定します。Finally, call ZoomControl.Configure to set the new zoom value on the device. デバイスは新しいズーム値への切り替えをスムーズに行います。The device will smoothly transition to the new zoom value.

private void PreviewControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var zoomControl = _mediaCapture.VideoDeviceController.ZoomControl;

    // Example zoom factor calculation based on size of scale gesture
    var zoomFactor = zoomControl.Value * e.Delta.Scale;

    if (zoomFactor < zoomControl.Min) zoomFactor = zoomControl.Min;
    if (zoomFactor > zoomControl.Max) zoomFactor = zoomControl.Max;
    zoomFactor = zoomFactor - (zoomFactor % zoomControl.Step);

    var settings = new ZoomSettings();
    settings.Mode = ZoomTransitionMode.Smooth;
    settings.Value = zoomFactor;

    _mediaCapture.VideoDeviceController.ZoomControl.Configure(settings);

}