ハイ ダイナミック レンジ (HDR) とローライトの写真のキャプチャHigh dynamic range (HDR) and low-light photo capture

この記事では、AdvancedPhotoCapture クラスを使って、ハイ ダイナミック レンジ (HDR) の写真をキャプチャする方法について説明します。This article shows you how to use the AdvancedPhotoCapture class to capture high dynamic range (HDR) photos. 最終的な画像の処理が完了する前に、この API を使って、HDR キャプチャから参照フレームを取得することもできます。This API also allows you to obtain a reference frame from the HDR capture before the processing of the final image is complete.

HDR キャプチャに関連したその他の記事を以下に示します。Other articles related to HDR capture include:

注意

Windows 10、バージョン 1709 以降では、ビデオ録画と AdvancedPhotoCapture の使用の同時実行がサポートされています。Starting with Windows 10, version 1709, recording video and using AdvancedPhotoCapture concurrently is supported. これは、それより前のバージョンではサポートされていません。This is not supported in previous versions. この変更により、LowLagMediaRecording と**AdvancedPhotoCapture** の準備を同時に実行できるようになりました。This change means that you can have a prepared LowLagMediaRecording and AdvancedPhotoCapture at the same time. MediaCapture.PrepareAdvancedPhotoCaptureAsyncAdvancedPhotoCapture.FinishAsync の呼び出しの間に、ビデオ録画を開始または停止できます。You can start or stop video recording between calls to MediaCapture.PrepareAdvancedPhotoCaptureAsync and AdvancedPhotoCapture.FinishAsync. またビデオの録画中に、AdvancedPhotoCapture.CaptureAsync を呼び出すこともできます。You can also call AdvancedPhotoCapture.CaptureAsync while video is recording. ただし、ビデオの録画中の HDR 写真のキャプチャなど、一部の AdvancedPhotoCapture のシナリオでは、HDR キャプチャによって一部のビデオ フレームが変更され、好ましくないユーザー エクスペリエンスが生じることがあります。However, some AdvancedPhotoCapture scenarios, like capturing an HDR photo while recording video would cause some video frames to be altered by the HDR capture, resulting in a negative user experience. このため、ビデオの録画中は、AdvancedPhotoControl.SupportedModes によって返されるモードが通常とは異なります。For this reason, the list of modes returned by the AdvancedPhotoControl.SupportedModes will be different while video is recording. ビデオ録画を開始または停止した場合は、直後にこの値をチェックして、目的のモードが現在のビデオ録画状態でサポートされていることを確認する必要があります。You should check this value immediately after starting or stopping video recording to ensure that the desired mode is supported in the current video recording state.

注意

Windows 10、バージョン 1709 以降では、AdvancedPhotoCapture を HDR モードに設定すると、FlashControl.Enabled プロパティの設定が無視されるため、フラッシュが作動しません。Starting with Windows 10, version 1709, when the AdvancedPhotoCapture is set to HDR mode, the setting of the FlashControl.Enabled property is ignored and the flash is never fired. また他のキャプチャ モードでは、FlashControl.Enabled の場合、AdvancedPhotoCapture 設定が上書きされ、通常の写真がフラッシュを使ってキャプチャされます。For other capture modes, if the FlashControl.Enabled, it will override the AdvancedPhotoCapture settings and cause a normal photo to be captured with flash. Auto が true に設定されている場合、AdvancedPhotoCapture がフラッシュを使用できるかどうかは、現在のシーン条件に対してカメラのドライバーに設定された既定の動作に依存します。If Auto is set to true, the AdvancedPhotoCapture may or may not use flash, depending on the camera driver's default behavior for the conditions in the current scene. 以前のリリースでは、AdvancedPhotoCapture のフラッシュ設定が、常に FlashControl.Enabled の設定を上書きします。On previous releases, the AdvancedPhotoCapture flash setting always overrides the FlashControl.Enabled setting.

注意

この記事の内容は、写真やビデオの基本的なキャプチャ機能を実装するための手順を紹介した「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.

AdvancedPhotoCapture クラスの使い方を示す、ユニバーサル Windows のサンプルがあります。コンテキスト内で API を使用する方法を確認したり、独自のアプリを作成し始めたりすることができます。There is a Universal Windows Sample demonstrating the use of the AdvancedPhotoCapture class that you can use to see the API used in context or as a starting point for your own app. 詳しくは、「カメラの高度なキャプチャのサンプル」をご覧ください。For more information see, Camera Advanced Capture sample.

高度な写真キャプチャの名前空間Advanced photo capture namespaces

この記事のコード例では、基本的なメディア キャプチャに必要な名前空間に加え、次の名前空間の API を使用します。The code examples in this article use APIs in the following namespaces in addition to the namespaces required for basic media capture.

using Windows.Media.Core;
using Windows.Media.Devices;

HDR 写真キャプチャHDR photo capture

HDR 写真キャプチャが現在のデバイスでサポートされているかどうかを調べるDetermine if HDR photo capture is supported on the current device

この記事で説明されている HDR キャプチャ手法には、AdvancedPhotoCapture オブジェクトが使われています。The HDR capture technique described in this article is performed using the AdvancedPhotoCapture object. デバイスによっては、AdvancedPhotoCapture での HDR キャプチャがサポートされません。Not all devices support HDR capture with AdvancedPhotoCapture. 現在アプリを実行しているデバイスが、この手法をサポートしているかどうかを調べるには、MediaCapture オブジェクトの VideoDeviceController を取得し、その AdvancedPhotoControl プロパティを取得します。Determine if the device on which your app is currently running supports the technique by getting the MediaCapture object's VideoDeviceController and then getting the AdvancedPhotoControl property. ビデオ デバイス コントローラーの SupportedModes コレクションに AdvancedPhotoMode.Hdr が含まれているかどうかを確認してください。コレクションに含まれている場合、AdvancedPhotoCapture を使った HDR キャプチャがサポートされています。Check the video device controller's SupportedModes collection to see if it includes AdvancedPhotoMode.Hdr. If it does, HDR capture using AdvancedPhotoCapture is supported.

bool _hdrSupported;
private void IsHdrPhotoSupported()
{
    _hdrSupported = _mediaCapture.VideoDeviceController.AdvancedPhotoControl.SupportedModes.Contains(Windows.Media.Devices.AdvancedPhotoMode.Hdr);
}

AdvancedPhotoCapture オブジェクトを構成して準備するConfigure and prepare the AdvancedPhotoCapture object

AdvancedPhotoCapture インスタンスにはコード内の複数の場所からアクセスする必要があるため、そのオブジェクトを保持するメンバー変数を宣言する必要があります。Because you will need to access the AdvancedPhotoCapture instance from multiple places within your code, you should declare a member variable to hold the object.

private AdvancedPhotoCapture _advancedCapture;

アプリのコードで、MediaCapture オブジェクトを初期化した後、AdvancedPhotoCaptureSettings オブジェクトを作成し、そのモードを AdvancedPhotoMode.Hdr に設定します。作成した AdvancedPhotoCaptureSettings オブジェクトを AdvancedPhotoControl オフジェクトの Configure メソッドに渡して呼び出します。In your app, after you have initialized the MediaCapture object, create an AdvancedPhotoCaptureSettings object and set the mode to AdvancedPhotoMode.Hdr. Call the AdvancedPhotoControl object's Configure method, passing in the AdvancedPhotoCaptureSettings object you created.

MediaCapture オブジェクトの PrepareAdvancedPhotoCaptureAsync を呼び出す際に ImageEncodingProperties オブジェクトを渡し、キャプチャで使うエンコードの種類を指定します。Call the MediaCapture object's PrepareAdvancedPhotoCaptureAsync, passing in an ImageEncodingProperties object specifying the type of encoding the capture should use. ImageEncodingPropertiesクラスは、 MediaCaptureでサポートされているイメージエンコーディングを作成するための静的メソッドを提供します。The ImageEncodingProperties class provides static methods for creating the image encodings that are supported by MediaCapture.

PrepareAdvancedPhotoCaptureAsync からは AdvancedPhotoCapture オブジェクトが返されます。写真キャプチャの初期化にはこのオブジェクトを使うことになります。PrepareAdvancedPhotoCaptureAsync returns the AdvancedPhotoCapture object you will use to initiate photo capture. 後ほど説明する OptionalReferencePhotoCapturedAllPhotosCaptured のハンドラーは、このオブジェクトを使って登録することができます。You can use this object to register handlers for the OptionalReferencePhotoCaptured and AllPhotosCaptured which are discussed later in this article.

if (_hdrSupported == false) return;

// Choose HDR mode
var settings = new AdvancedPhotoCaptureSettings { Mode = AdvancedPhotoMode.Hdr };

// Configure the mode
_mediaCapture.VideoDeviceController.AdvancedPhotoControl.Configure(settings);

// Prepare for an advanced capture
_advancedCapture = 
    await _mediaCapture.PrepareAdvancedPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Nv12));

// Register for events published by the AdvancedCapture
_advancedCapture.AllPhotosCaptured += AdvancedCapture_AllPhotosCaptured;
_advancedCapture.OptionalReferencePhotoCaptured += AdvancedCapture_OptionalReferencePhotoCaptured;

HDR 写真をキャプチャするCapture an HDR photo

HDR 写真をキャプチャするには、AdvancedPhotoCapture オブジェクトの CaptureAsync メソッドを呼び出します。Capture an HDR photo by calling the AdvancedPhotoCapture object's CaptureAsync method. このメソッドから返される AdvancedCapturedPhoto オブジェクトの Frame プロパティに、キャプチャされた写真が格納されています。This method returns an AdvancedCapturedPhoto object that provides the captured photo in its Frame property.

try
{

    // Start capture, and pass the context object
    AdvancedCapturedPhoto advancedCapturedPhoto = await _advancedCapture.CaptureAsync();

    using (var frame = advancedCapturedPhoto.Frame)
    {
        // Read the current orientation of the camera and the capture time
        var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(
            _rotationHelper.GetCameraCaptureOrientation());
        var fileName = String.Format("SimplePhoto_{0}_HDR.jpg", DateTime.Now.ToString("HHmmss"));
        await SaveCapturedFrameAsync(frame, fileName, photoOrientation);
    }
}
catch (Exception ex)
{
    Debug.WriteLine("Exception when taking an HDR photo: {0}", ex.ToString());
}

ほとんどの写真アプリは、他のアプリやデバイスで正しく表示できるように、キャプチャされた写真の回転情報を画像ファイルにエンコードします。Most photography apps will want to encode a captured photo's rotation into the image file so that it can be displayed correctly by other apps and devices. 次の例は、CameraRotationHelper ヘルパー クラスを使用して、ファイルの正しい向きを計算する方法を示しています。This example shows the use of the helper class CameraRotationHelper to calculate the proper orientation for the file. このクラスの全容については、「MediaCapture を使ってデバイスの向きを処理する」で説明しています。This class is described and listed in full in the article Handle device orientation with MediaCapture.

画像をディスクに保存する SaveCapturedFrameAsync ヘルパー メソッドについては、この記事で後述しています。The SaveCapturedFrameAsync helper method, which saves the image to disk, is discussed later in this article.

必要に応じて参照フレームを取得するGet optional reference frame

HDR プロセスは複数のフレームをキャプチャします。そのすべてのフレームがキャプチャされると、それらが単一の画像として合成されます。The HDR process captures multiple frames and then composites them into a single image after all of the frames have been captured. フレームがキャプチャされた後、HDR プロセス全体が完了する前に、OptionalReferencePhotoCaptured イベントを処理することでそのフレームにアクセスすることができます。You can get access to a frame after it is captured but before the entire HDR process is complete by handling the OptionalReferencePhotoCaptured event. HDR 写真の最終的な結果だけが目的であれば、この処理は不要です。You don't need to do this if you are only interested in the final HDR photo result.

重要

ハードウェア HDR をサポートしていて参照フレームを生成しないデバイスでは、OptionalReferencePhotoCaptured が発生しません。OptionalReferencePhotoCaptured is not raised on devices that support hardware HDR and therefore do not generate reference frames. アプリ側で、このイベントが生成されないケースに対処する必要があります。Your app should handle the case where this event is not raised.

参照フレームは CaptureAsync 呼び出しのコンテキストから離れて届くため、OptionalReferencePhotoCaptured ハンドラーにコンテキスト情報を渡すためのしくみが用意されています。Because the reference frame arrives out of context of the call to CaptureAsync, a mechanism is provided to pass context information to the OptionalReferencePhotoCaptured handler. まず、コンテキスト情報を保持するオブジェクトを呼び出す必要があります。First you should call an object that will contain your context information. このオブジェクトの名前と内容は自由に設定してください。The name and contents of this object is up to you. この例のオブジェクトには、キャプチャのファイル名とカメラの向きを追跡するためのメンバーが定義されています。This example defines an object that has members to track the file name and camera orientation of the capture.

public class MyAdvancedCaptureContextObject
{
    public string CaptureFileName;
    public PhotoOrientation CaptureOrientation;
}

コンテキスト オブジェクトの新しいインスタンスを作成して、そのメンバーにデータを設定した後、パラメーターとしてオブジェクトを受け取る CaptureAsync のオーバーロードにそのオブジェクトを渡します。Create a new instance of your context object, populate its members, and then pass it into the overload of CaptureAsync that accepts an object as a parameter.

// Read the current orientation of the camera and the capture time
var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(
        _rotationHelper.GetCameraCaptureOrientation());
var fileName = String.Format("SimplePhoto_{0}_HDR.jpg", DateTime.Now.ToString("HHmmss"));

// Create a context object, to identify the capture in the OptionalReferencePhotoCaptured event
var context = new MyAdvancedCaptureContextObject()
{
    CaptureFileName = fileName,
    CaptureOrientation = photoOrientation
};

// Start capture, and pass the context object
AdvancedCapturedPhoto advancedCapturedPhoto = await _advancedCapture.CaptureAsync(context);

OptionalReferencePhotoCaptured イベント ハンドラーで、OptionalReferencePhotoCapturedEventArgs オブジェクトの Context プロパティを、先ほど定義したコンテキスト オブジェクト クラスにキャストします。In the OptionalReferencePhotoCaptured event handler, cast the Context property of the OptionalReferencePhotoCapturedEventArgs object to your context object class. この例では、最終的な HDR 画像と区別するために参照フレーム画像のファイル名を変更した上で SaveCapturedFrameAsync ヘルパー メソッドを呼び出し、画像を保存しています。This example modifies the file name to distinguish the reference frame image from the final HDR image and then calls the SaveCapturedFrameAsync helper method to save the image.

private async void AdvancedCapture_OptionalReferencePhotoCaptured(AdvancedPhotoCapture sender, OptionalReferencePhotoCapturedEventArgs args)
{
    // Retrieve the context (i.e. what capture does this belong to?)
    var context = args.Context as MyAdvancedCaptureContextObject;

    // Remove "_HDR" from the name of the capture to create the name of the reference
    var referenceName = context.CaptureFileName.Replace("_HDR", "");

    using (var frame = args.Frame)
    {
        await SaveCapturedFrameAsync(frame, referenceName, context.CaptureOrientation);
    }
}

すべてのフレームがキャプチャされたときに通知を受け取るReceive a notification when all frames have been captured

HDR 写真のキャプチャには、2 つのステップがあります。The HDR photo capture has two steps. 複数のフレームをキャプチャするステップと、その後、それらのフレームが最終的な HDR 画像に加工するステップです。First, multiple frames are captured, and then the frames are processed into the final HDR image. ソース HDR フレームのキャプチャ中に別のキャプチャを開始することはできませんが、すべてのフレームがキャプチャされた後であれば、HDR の後処理が完了していなくても、キャプチャを開始することができます。You can't initiate another capture while the source HDR frames are still being captured, but you can initiate a capture after all of the frames have been captured but before the HDR post-processing is complete. HDR キャプチャが完了すると AllPhotosCaptured イベントが発生するので、そのタイミングで別のキャプチャを開始することができます。The AllPhotosCaptured event is raised when the HDR captures are complete, letting you know that you can initiate another capture. たとえば HDR キャプチャの開始時に UI のキャプチャ ボタンを無効にし、その後 AllPhotosCaptured が発生した時点で再度ボタンを有効にする、という使い方が考えられます。A typical scenario is to disable your UI's capture button when HDR capture begins and then reenable it when AllPhotosCaptured is raised.

private void AdvancedCapture_AllPhotosCaptured(AdvancedPhotoCapture sender, object args)
{
    // Update UI to enable capture button
}

AdvancedPhotoCapture オブジェクトのクリーンアップClean up the AdvancedPhotoCapture object

キャプチャが終了したら、MediaCapture オブジェクトを破棄する前に、FinishAsync を呼び出し、メンバー変数を null に設定して AdvancedPhotoCapture オブジェクトをシャットダウンする必要があります。When your app is done capturing, before disposing of the MediaCapture object, you should shut down the AdvancedPhotoCapture object by calling FinishAsync and setting your member variable to null.

await _advancedCapture.FinishAsync();
_advancedCapture = null;

ローライトの写真のキャプチャLow-light photo capture

Windows 10 バージョン 1607 以降では、AdvancedPhotoCapture により、ローライトの設定でキャプチャされた写真の品質を高める組み込みアルゴリズムを使って、写真をキャプチャすることが可能です。Starting with Windows 10, version 1607, AdvancedPhotoCapture can be used to capture photos using a built-in algorithm that enhances the quality of photos captured in low-light settings. AdvancedPhotoCapture クラスの低光量機能を使うと、システムは現在のシーンを評価し、必要に応じて、低光量の状況に合わせてアルゴリズムを適用します。When you use the low-light feature of the AdvancedPhotoCapture class, the system will evaluate the current scene and, if needed, apply an algorithm to compensate for low-light conditions. システムでアルゴリズムが必要ないと判断された場合は、通常のキャプチャが実行されます。If the system determines that the algorithm is not needed, a regular capture is performed instead.

低光量写真のキャプチャを使用する前に、現在アプリを実行しているデバイスがこの手法をサポートしているかどうかを調べます。このためには、MediaCapture オブジェクトの VideoDeviceController を取得し、その AdvancedPhotoControl プロパティを取得します。Before using low-light photo capture, determine if the device on which your app is currently running supports the technique by getting the MediaCapture object's VideoDeviceController and then getting the AdvancedPhotoControl property. ビデオ デバイス コントローラーの SupportedModes コレクションに AdvancedPhotoMode.LowLight が含まれているかどうかを確認してください。Check the video device controller's SupportedModes collection to see if it includes AdvancedPhotoMode.LowLight. コレクションに含まれている場合、AdvancedPhotoCapture を使ったローライトのキャプチャがサポートされています。If it does, low-light capture using AdvancedPhotoCapture is supported.

bool _lowLightSupported;
_lowLightSupported = 
_mediaCapture.VideoDeviceController.AdvancedPhotoControl.SupportedModes.Contains(Windows.Media.Devices.AdvancedPhotoMode.LowLight);

次に、AdvancedPhotoCapture オブジェクトを格納するためのメンバー変数を宣言します。Next, declare a member variable to store the AdvancedPhotoCapture object.

private AdvancedPhotoCapture _advancedCapture;

アプリのコードで、MediaCapture オブジェクトを初期化した後、AdvancedPhotoCaptureSettings オブジェクトを作成し、そのモードを AdvancedPhotoMode.LowLight に設定します。In your app, after you have initialized the MediaCapture object, create an AdvancedPhotoCaptureSettings object and set the mode to AdvancedPhotoMode.LowLight. 作成した AdvancedPhotoCaptureSettings オブジェクトを AdvancedPhotoControl オブジェクトの Configure メソッドに渡して呼び出します。Call the AdvancedPhotoControl object's Configure method, passing in the AdvancedPhotoCaptureSettings object you created.

MediaCapture オブジェクトの PrepareAdvancedPhotoCaptureAsync を呼び出す際に ImageEncodingProperties オブジェクトを渡し、キャプチャで使うエンコードの種類を指定します。Call the MediaCapture object's PrepareAdvancedPhotoCaptureAsync, passing in an ImageEncodingProperties object specifying the type of encoding the capture should use.

if (_lowLightSupported == false) return;

// Choose LowLight mode
var settings = new AdvancedPhotoCaptureSettings { Mode = AdvancedPhotoMode.LowLight };
_mediaCapture.VideoDeviceController.AdvancedPhotoControl.Configure(settings);

// Prepare for an advanced capture
_advancedCapture = 
    await _mediaCapture.PrepareAdvancedPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Nv12));

写真をキャプチャするには、CaptureAsync を呼び出します。To capture a photo, call CaptureAsync.

AdvancedCapturedPhoto advancedCapturedPhoto = await _advancedCapture.CaptureAsync();
var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
var fileName = String.Format("SimplePhoto_{0}_LowLight.jpg", DateTime.Now.ToString("HHmmss"));
await SaveCapturedFrameAsync(advancedCapturedPhoto.Frame, fileName, photoOrientation);

前述の HDR の例のように、この例は CameraRotationHelper というヘルパー クラスを使って、画像にエンコードする必要がある回転値を特定し、他のアプリやデバイスで正しく表示できるようにします。Like the HDR example above, this example uses a helper class called CameraRotationHelper to determine the rotation value that should be encoded into the image so that it can be displayed properly by other apps and devices. このクラスの全容については、「MediaCapture を使ってデバイスの向きを処理する」で説明しています。This class is described and listed in full in the article Handle device orientation with MediaCapture.

画像をディスクに保存する SaveCapturedFrameAsync ヘルパー メソッドについては、この記事で後述しています。The SaveCapturedFrameAsync helper method, which saves the image to disk, is discussed later in this article.

AdvancedPhotoCapture オブジェクトを再構成しなくても低光量の写真を複数キャプチャすることができますが、キャプチャが終わったら FinishAsync を呼び出し、オブジェクトと、関連付けられているリソースをクリーンアップする必要があります。You can capture multiple low-light photos without reconfiguring the AdvancedPhotoCapture object, but when you are done capturing, you should call FinishAsync to clean up the object and associated resources.

await _advancedCapture.FinishAsync();
_advancedCapture = null;

AdvancedCapturedPhoto オブジェクトを操作するWorking with AdvancedCapturedPhoto objects

AdvancedPhotoCapture.CaptureAsync は、キャプチャした写真を表す AdvancedCapturedPhoto オブジェクトを返します。AdvancedPhotoCapture.CaptureAsync returns an AdvancedCapturedPhoto object representing the captured photo. このオブジェクトが公開するのは、画像を表す CapturedFrame オブジェクトを返す、Frame プロパティです。This object exposes the Frame property which returns a CapturedFrame object representing the image. OptionalReferencePhotoCaptured イベントも、イベント引数で CapturedFrame オブジェクトを提供します。The OptionalReferencePhotoCaptured event also provides a CapturedFrame object in its event args. この型のオブジェクトを取得した後は、SoftwareBitmap の作成や、ファイルへの画像の保存など、多くのことを実行できるようになります。After you get an object of this type, there are a number of things you can do with it, including creating a SoftwareBitmap or saving the image to a file.

CapturedFrame から SoftwareBitmap を取得するGet a SoftwareBitmap from a CapturedFrame

SoftwareBitmapCapturedFrame オブジェクトから取得するのは、オブジェクトの SoftwareBitmap プロパティにアクセスするだけなので、簡単です。It's trivial to get a SoftwareBitmap from a CapturedFrame object by simply accessing the SoftwareBitmap property of the object. ただし、AdvancedPhotoCapture での SoftwareBitmap の使用は、ほとんどのエンコード形式においてサポートされていないため、使用する前にプロパティが null になっていないことを確認する必要があります。However, most encoding formats do not support SoftwareBitmap with AdvancedPhotoCapture, so you should check and make sure the property is not null before using it.

SoftwareBitmap bitmap;
if (advancedCapturedPhoto.Frame.SoftwareBitmap != null)
{
    bitmap = advancedCapturedPhoto.Frame.SoftwareBitmap;
}

現在のリリースで、AdvancedPhotoCapture での SoftwareBitmap の使用をサポートしている唯一のエンコード形式は、非圧縮形式の NV12 です。In the current release, the only encoding format that supports SoftwareBitmap for AdvancedPhotoCapture is uncompressed NV12. したがってこの機能を使用する場合は、PrepareAdvancedPhotoCaptureAsync を呼び出す際にそのエンコーディングを指定する必要があります。So, if you want to use this feature, you must specify that encoding when you call PrepareAdvancedPhotoCaptureAsync.

_advancedCapture =
    await _mediaCapture.PrepareAdvancedPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Nv12));

もちろん、ファイルに画像を保存し、別個の手順で SoftwareBitmap にファイルを読み込むことも常に可能です。Of course, you can always save the image to a file and then load the file into a SoftwareBitmap in a separate step. SoftwareBitmap の操作について詳しくは、「ビットマップ画像の作成、編集、保存」をご覧ください。For more information about working with SoftwareBitmap, see Create, edit, and save bitmap images.

CapturedFrame をファイルに保存するSave a CapturedFrame to a file

CapturedFrame クラスは IInputStream インターフェイスを実装するので、BitmapDecoder への入力として使用できます。その後、BitmapEncoder を使えば画像データをディスクに書き込むことができます。The CapturedFrame class implements the IInputStream interface, so it can be used as the input to a BitmapDecoder, and then a BitmapEncoder can be used to write the image data to disk.

次の例では、ユーザーの画像ライブラリに新しいフォルダーが作成され、そのフォルダー内にファイルが作成されています。In the following example, a new folder in the user's pictures library is created and a file is created within this folder. このディレクトリにアクセスするためには、アプリが Pictures Library 機能をアプリ マニフェスト ファイルに含める必要があります。Note that your app will need to include the Pictures Library capability in your app manifest file in order to access this directory. すると、ファイル ストリームが指定のファイルに開かれます。A file stream is then opened to the specified file. 次に、CapturedFrame からデコーダーを作成するために BitmapDecoder.CreateAsync を呼び出します。Next, the BitmapDecoder.CreateAsync is called to create the decoder from the CapturedFrame. その後 CreateForTranscodingAsync がファイル ストリームとデコーダーからエンコーダーを作成します。Then CreateForTranscodingAsync creates an encoder from the file stream and the decoder.

次に、エンコーダーの BitmapProperties を使って画像ファイルに写真の向きをエンコードします。The next steps encode the orientation of the photo into the image file by using the BitmapProperties of the encoder. 画像をキャプチャする際の向きの処理について詳しくは、「MediaCapture を使ってデバイスの向きを処理する」をご覧ください。For more information about handling orientation when capturing images, see Handle device orientation with MediaCapture.

最後に、FlushAsync を呼び出すことで、画像をファイルに書き込みます。Finally, the image is written to the file with a call to FlushAsync.

private static async Task<StorageFile> SaveCapturedFrameAsync(CapturedFrame frame, string fileName, PhotoOrientation photoOrientation)
{
    var folder = await KnownFolders.PicturesLibrary.CreateFolderAsync("MyApp", CreationCollisionOption.OpenIfExists);
    var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);

    using (var inputStream = frame)
    {
        using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            var decoder = await BitmapDecoder.CreateAsync(inputStream);
            var encoder = await BitmapEncoder.CreateForTranscodingAsync(fileStream, decoder);
            var properties = new BitmapPropertySet {
                { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
            await encoder.BitmapProperties.SetPropertiesAsync(properties);
            await encoder.FlushAsync();
        }
    }
    return file;
}