HDR (High dynamic range) 및 낮은 밝은 사진 캡처High dynamic range (HDR) and low-light photo capture

이 문서에서는 AdvancedPhotoCapture 클래스를 사용 하 여 HDR (high dynamic range) 사진을 캡처하는 방법을 보여 줍니다.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. MediaCaptureAdvancedPhotoCapture async 호출 사이에 비디오 기록을 시작 하거나 중지할 수 있습니다.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 모드 에서 반환 되는 모드 목록이 다릅니다.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 속성의 설정이 무시 되 고 플래시는 실행 되지 않습니다.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이 사용 하도록설정 되 면 AdvancedPhotoCapture 설정을 재정의 하 고 flash로 일반적인 사진을 캡처합니다.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 가 flash를 사용할 수도 있고 사용 하지 않을 수도 있습니다.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 flash 설정이 항상 FlashControl 설정을 재정의 합니다.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.

컨텍스트에서 사용 되는 API를 확인 하거나 사용자 고유의 앱에 대 한 시작 점으로 사용할 수 있는 AdvancedPhotoCapture 클래스의 사용을 보여 주는 유니버설 Windows 샘플이 있습니다.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이 포함 되어 있는지 확인 합니다. 이 경우 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로 설정 합니다. AdvancedPhotoControl 개체의 Configure 메서드를 호출 하 여 사용자가 만든 AdvancedPhotoCaptureSettings 개체를 전달 합니다.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

AdvancedPhotoCapture 개체의 CaptureAsync 메서드를 호출 하 여 HDR 사진을 캡처합니다.Capture an HDR photo by calling the AdvancedPhotoCapture object's CaptureAsync method. 이 메서드는 프레임 속성에서 캡처된 사진을 제공 하는 AdvancedCapturedPhoto 개체를 반환 합니다.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. 프레임을 캡처한 후 OptionalReferencePhotoCaptured 이벤트를 처리 하 여 전체 HDR 프로세스가 완료 되기 전에 프레임에 대 한 액세스 권한을 얻을 수 있습니다.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.

중요

OptionalReferencePhotoCaptured 는 하드웨어 HDR를 지 원하는 장치에서 발생 하지 않으므로 참조 프레임을 생성 하지 않습니다.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;
}

Context 개체의 새 인스턴스를 만들고 해당 멤버를 채운 다음 개체를 매개 변수로 허용 하는 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 개체의 컨텍스트 속성을 컨텍스트 개체 클래스로 캐스팅 합니다.In the OptionalReferencePhotoCaptured event handler, cast the Context property of the OptionalReferencePhotoCapturedEventArgs object to your context object class. 이 예제에서는 파일 이름을 수정 하 여 최종 HDR 이미지와 참조 프레임 이미지를 구분 하 고 SaveCapturedFrameAsync helper 메서드를 호출 하 여 이미지를 저장 합니다.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 사진 캡처에는 두 단계가 있습니다.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. AllPhotosCaptured 이벤트는 HDR 캡처가 완료 될 때 발생 하며,이를 통해 다른 캡처를 시작할 수 있다는 것을 알 수 있습니다.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 개체를 삭제 하기 전에, AdvancedPhotoCapture 개체를 종료 하 고 멤버 변수를 null로 설정 하 여 해당 개체를 종료 해야 합니다.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이 포함 되어 있는지 확인 합니다.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로 설정 합니다.In your app, after you have initialized the MediaCapture object, create an AdvancedPhotoCaptureSettings object and set the mode to AdvancedPhotoMode.LowLight. AdvancedPhotoControl 개체의 Configure 메서드를 호출 하 여 사용자가 만든 AdvancedPhotoCaptureSettings 개체를 전달 합니다.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 개체를 다시 구성 하지 않고 적은 수의 작은 사진을 캡처할 수 있지만 캡처가 완료 되 면, 개체 및 연결 된 리소스를 정리 하기 위해 다음 비동기 를 호출 해야 합니다.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. 이 형식의 개체를 가져온 후 에는 해당 개체를 사용 하 여 다양 한 작업을 수행할 수 있습니다.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에서에서의 비트맵 가져오기Get a SoftwareBitmap from a CapturedFrame

단순히 개체의 \bitmap 속성에 액세스 하 여 CapturedFrame 개체에서 지 속성 비트맵 을 가져오는 것이 간단 합니다.It's trivial to get a SoftwareBitmap from a CapturedFrame object by simply accessing the SoftwareBitmap property of the object. 그러나 대부분의 인코딩 형식은 AdvancedPhotoCapture에서 \bitmap 을 지원 하지 않으므로이 속성을 사용 하기 전에 해당 속성이 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 에 대 한 \bitmap 비트맵 을 지 원하는 인코딩 형식만 압축 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));

물론, 언제 든 지 이미지를 파일에 저장 한 다음 별도의 단계로 파일을 파일에 로드할 수 있습니다.Of course, you can always save the image to a file and then load the file into a SoftwareBitmap in a separate step. \Bitmap으로 작업 하는 방법에 대 한 자세한 내용은 비트맵 이미지 만들기, 편집 및 저장을 참조 하세요.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. 앱은이 디렉터리에 액세스 하기 위해 앱 매니페스트 파일에 그림 라이브러리 기능을 포함 해야 합니다.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. 그런 다음 bitmapdecoder에서 를 호출 하 여 CapturedFrame에서 디코더를 만듭니다.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;
}