변수 사진 시퀀스
이 문서에서는 변수 사진 시퀀스를 캡처하는 방법을 설명합니다. 이를 통해 여러 이미지 프레임을 연속으로 빠르게 캡처하고 각 프레임에서 다양한 초점, 플래시, ISO, 노출 및 노출 보정 설정을 사용하도록 구성할 수 있습니다. 이 기능을 사용해 HDR(High Dynamic Range) 이미지 만들기 같은 시나리오를 사용할 수 있습니다.
HDR 이미지를 캡처하되, 고유한 처리 알고리즘을 구현하지 않으려면 AdvancedPhotoCapture API를 사용하여 Windows에 기본 제공되는 HDR 기능을 사용하면 됩니다. 자세한 내용은 HDR(High Dynamic Range) 사진 캡처를 참조하세요.
참고 항목
이 문서는 기본 사진 및 비디오 캡처 구현 단계를 설명하는 MediaCapture를 사용한 기본적인 사진, 비디오 및 오디오 캡처에 설명된 개념 및 코드를 토대로 작성되었습니다. 좀 더 수준 높은 캡처 시나리오를 진행하기 전에 해당 문서의 기본 미디어 캡처 패턴을 좀 더 잘 이해하는 것이 좋습니다. 이 문서의 코드는 앱에 적절히 초기화된 MediaCapture의 인스턴스가 이미 있다고 가정합니다.
변수 사진 시퀀스 캡처 기능을 사용하도록 앱 설정
변수 사진 시퀀스 캡처를 구현하려면 기본 미디어 캡처에 필요한 네임스페이스 외에 다음 네임스페이스도 필요합니다.
using Windows.Media.Capture.Core;
using Windows.Media.Devices.Core;
사진 시퀀스 캡처를 시작할 때 사용되는 VariablePhotoSequenceCapture 개체를 저장할 멤버 변수를 선언합니다. 시퀀스에 캡처된 각 이미지를 저장할 SoftwareBitmap 개체의 배열을 선언합니다. 또한 각 프레임마다 CapturedFrameControlValues 개체를 저장할 배열을 선언합니다. 이미지 처리 알고리즘에서 이를 사용하여 각 프레임을 캡처하는 데 사용된 설정을 확인할 수 있습니다. 마지막으로 시퀀스에서 현재 캡처되는 이미지를 추적하는 데 사용될 인덱스를 선언합니다.
VariablePhotoSequenceCapture _photoSequenceCapture;
SoftwareBitmap[] _images;
CapturedFrameControlValues[] _frameControlValues;
int _photoIndex;
변수 사진 시퀀스 캡처 준비
MediaCapture를 초기화한 후에는 미디어 캡처의 VideoDeviceController에서 VariablePhotoSequenceController의 인스턴스를 가져와 Supported 속성과 확인하여 변수 사진 시퀀스가 현재 디바이스에서 지원되는지 확인해야 합니다.
var varPhotoSeqController = _mediaCapture.VideoDeviceController.VariablePhotoSequenceController;
if (!varPhotoSeqController.Supported)
{
ShowMessageToUser("Variable Photo Sequence is not supported");
return;
}
변수 사진 시퀀스 컨트롤러에서 FrameControlCapabilities 개체를 가져옵니다. 이 개체는 사진 시퀀스의 프레임당 구성할 수 있는 모든 설정에 해당하는 속성이 있습니다. 여기에는 다음이 포함됩니다.
이 예제에서는 각 프레임당 서로 다른 노출 보정 값을 설정합니다. 현재 디바이스의 사진 시퀀스에 대해 노출 보정이 지원되는지 확인하려면 ExposureCompensation 속성을 통해 액세스한 FrameExposureCompensationCapabilities 개체의 Supported 속성을 확인합니다.
var frameCapabilities = varPhotoSeqController.FrameCapabilities;
if (!frameCapabilities.ExposureCompensation.Supported)
{
ShowMessageToUser("EVCompenstaion is not supported in FrameController");
return;
}
캡처하려는 각 프레임마다 새 FrameController 개체를 만듭니다. 이 예제에서는 프레임 세 개를 캡처합니다. 각 프레임마다 변경할 컨트롤의 값을 설정합니다. 그런 다음 VariablePhotoSequenceController의 DesiredFrameControllers 컬렉션을 지우고 각 프레임 컨트롤러를 컬렉션에 추가합니다.
var frame0 = new FrameController();
var frame1 = new FrameController();
var frame2 = new FrameController();
frame0.ExposureCompensationControl.Value = -1.0f;
frame1.ExposureCompensationControl.Value = 0.0f;
frame2.ExposureCompensationControl.Value = 1.0f;
varPhotoSeqController.DesiredFrameControllers.Clear();
varPhotoSeqController.DesiredFrameControllers.Add(frame0);
varPhotoSeqController.DesiredFrameControllers.Add(frame1);
varPhotoSeqController.DesiredFrameControllers.Add(frame2);
ImageEncodingProperties 개체를 만들어 캡처된 이미지에 사용할 인코딩을 설정합니다. 정적 메서드 MediaCapture.PrepareVariablePhotoSequenceCaptureAsync를 호출해 인코딩 속성을 전달합니다. 이 메서드는 VariablePhotoSequenceCapture 개체를 반환합니다. 마지막으로 PhotoCaptured 및 Stopped 이벤트에 해당하는 이벤트 처리기를 등록합니다.
try
{
var imageEncodingProperties = ImageEncodingProperties.CreateJpeg();
_photoSequenceCapture = await _mediaCapture.PrepareVariablePhotoSequenceCaptureAsync(imageEncodingProperties);
_photoSequenceCapture.PhotoCaptured += OnPhotoCaptured;
_photoSequenceCapture.Stopped += OnStopped;
}
catch (Exception ex)
{
ShowMessageToUser("Exception in PrepareVariablePhotoSequence: " + ex.Message);
}
변수 사진 시퀀스 캡처 시작
변수 사진 시퀀스의 캡처를 시작하려면 VariablePhotoSequenceCapture.StartAsync를 호출합니다. 캡처된 이미지 및 프레임 컨트롤 값을 저장할 배열을 초기화하고 현재 인덱스를 0으로 설정해야 합니다. 이 캡처가 진행되는 동안 앱의 기록 상태 변수를 설정하고 UI를 업데이트하여 다른 캡처가 시작되지 않도록 설정합니다.
private async void StartPhotoCapture()
{
_images = new SoftwareBitmap[3];
_frameControlValues = new CapturedFrameControlValues[3];
_photoIndex = 0;
_isRecording = true;
await _photoSequenceCapture.StartAsync();
}
캡처된 프레임 받기
캡처된 각 프레임에 PhotoCaptured 이벤트가 발생합니다. 프레임 컨트롤 값과 캡처된 이미지를 프레임에 저장한 다음 현재 프레임 인덱스를 늘립니다. 이 예제에서는 각 프레임의 SoftwareBitmap 표현을 가져오는 방법을 설명합니다. SoftwareBitmap 사용에 관한 자세한 내용은 이미징을 참조하세요.
void OnPhotoCaptured(VariablePhotoSequenceCapture s, VariablePhotoCapturedEventArgs args)
{
_images[_photoIndex] = args.Frame.SoftwareBitmap;
_frameControlValues[_photoIndex] = args.CapturedFrameControlValues;
_photoIndex++;
}
변수 사진 시퀀스 캡처의 완료 처리
시퀀스의 모든 프레임이 캡쳐되면 Stopped 이벤트가 발생합니다. 사용자가 새 캡처를 시작할 수 있도록 앱의 기록 상태를 업데이트하고 UI를 업데이트합니다. 이때 캡처된 이미지 및 프레임 컨트롤 값을 이미지 처리 코드에 전달할 수 있습니다.
void OnStopped(object s, object e)
{
_isRecording = false;
MyPostProcessingFunction(_images, _frameControlValues, 3);
}
프레임 컨트롤러 업데이트
프레임별 설정이 서로 다른 또 다른 변수 사진 시퀀스 캡처를 수행해야 할 경우 VariablePhotoSequenceCapture를 완전히 다시 초기화할 필요가 없습니다. DesiredFrameControllers 컬렉션을 지우고 새 프레임 컨트롤러를 추가하거나 기존 프레임 컨트롤러 값을 수정하면 됩니다. 다음 예제에서는 FrameFlashCapabilities 개체를 확인하여 현재 디바이스에서 변수 사진 시퀀스 프레임용 플래시 및 플래시 전원을 지원하는지 확인합니다. 지원되는 경우 각 프레임이 100% 전원으로 플래시를 사용하도록 업데이트됩니다. 각 프레임에 대해 설정되었던 노출 보정 값은 활성 상태를 유지합니다.
var varPhotoSeqController = _mediaCapture.VideoDeviceController.VariablePhotoSequenceController;
if (varPhotoSeqController.FrameCapabilities.Flash.Supported &&
varPhotoSeqController.FrameCapabilities.Flash.PowerSupported)
{
for (int i = 0; i < varPhotoSeqController.DesiredFrameControllers.Count; i++)
{
varPhotoSeqController.DesiredFrameControllers[i].FlashControl.Mode = FrameFlashMode.Enable;
varPhotoSeqController.DesiredFrameControllers[i].FlashControl.PowerPercent = 100;
}
}
변수 사진 시퀀스 캡처 정리
변수 사진 시퀀스 캡처를 완료하거나 앱이 일시 중단되면 FinishAsync를 호출하여 변수 사진 시퀀스 개체를 정리합니다. 개체의 이벤트 처리기 등록을 취소하고 null로 설정합니다.
await _photoSequenceCapture.FinishAsync();
_photoSequenceCapture.PhotoCaptured -= OnPhotoCaptured;
_photoSequenceCapture.Stopped -= OnStopped;
_photoSequenceCapture = null;
관련 항목