Поделиться через


Последовательность фотографий переменной

В этой статье показано, как записать переменную последовательность фотографий, которая позволяет записывать несколько кадров изображений в быстром последовательности и настраивать каждый кадр для использования различных параметров фокуса, вспышки, ISO, экспозиции и компенсации воздействия. Эта функция позволяет создавать такие сценарии, как создание образов с высоким динамическим диапазоном (HDR).

Если вы хотите записать образы HDR, но не хотите реализовать собственный алгоритм обработки, можно использовать API AdvancedPhotoCapture для использования возможностей HDR, встроенных в Windows. Дополнительные сведения см. в разделе с фотозахватом с высоким динамическим диапазоном (HDR).

Примечание.

В этой статье рассматриваются основные понятия и код, описанные в разделе "Базовый" фото, видео и аудиозапись с помощью MediaCapture, в котором описаны шаги по реализации базового фото и видеозахвата. Рекомендуется ознакомиться с основным шаблоном захвата мультимедиа в этой статье, прежде чем перейти к более сложным сценариям захвата. В коде этой статьи предполагается, что приложение уже имеет экземпляр MediaCapture, который был правильно инициализирован.

Настройка приложения для использования записи последовательности переменных фотографий

Помимо пространств имен, необходимых для базового захвата мультимедиа, реализация записи последовательности переменных фотографий требует следующих пространств имен.

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

Объявите переменную-член для хранения объекта VariablePhotoSequenceCapture , который используется для запуска записи последовательности фотографий. Объявите массив объектов SoftwareBitmap для хранения каждого захваченного изображения в последовательности. Кроме того, объявите массив для хранения объекта CapturedFrameControlValues для каждого кадра. Это можно использовать алгоритмом обработки изображений для определения параметров, используемых для записи каждого кадра. Наконец, объявите индекс, который будет использоваться для отслеживания того, какой образ в последовательности в настоящее время фиксируется.

VariablePhotoSequenceCapture _photoSequenceCapture;
SoftwareBitmap[] _images;
CapturedFrameControlValues[] _frameControlValues;
int _photoIndex;

Подготовка записи последовательности фотографий переменной

После инициализации MediaCapture убедитесь, что на текущем устройстве поддерживаются переменные последовательности фотографий, получая экземпляр ПеременнойPhotoSequenceController из videoDeviceController записи мультимедиа и проверив поддерживаемое свойство.

var varPhotoSeqController = _mediaCapture.VideoDeviceController.VariablePhotoSequenceController;

if (!varPhotoSeqController.Supported)
{
    ShowMessageToUser("Variable Photo Sequence is not supported");
    return;
}

Получите объект FrameControlCapabilities из контроллера последовательности фотографий переменной. Этот объект имеет свойство для каждого параметра, который можно настроить для каждого кадра последовательности фотографий. Например:

В этом примере будет задано другое значение компенсации воздействия для каждого кадра. Чтобы убедиться, что компенсация воздействия поддерживается для последовательностей фотографий на текущем устройстве, проверьте свойство "Поддерживаемый" объекта FrameCapabilionCapabilities, доступ к которому осуществляется через свойство ExposureCompensation.

var frameCapabilities = varPhotoSeqController.FrameCapabilities;

if (!frameCapabilities.ExposureCompensation.Supported)
{
    ShowMessageToUser("EVCompenstaion is not supported in FrameController");
    return;
}

Создайте новый объект FrameController для каждого кадра, который требуется записать. В этом примере фиксируется три кадра. Задайте значения для элементов управления, которые нужно изменить для каждого кадра. Затем очистите коллекцию DesiredFrameControllers объекта VariablePhotoSequenceController и добавьте каждый контроллер кадра в коллекцию.

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 и Остановлены.

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. Задайте переменную состояния записи приложения и обновите пользовательский интерфейс, чтобы отключить запуск другого захвата во время выполнения этой записи.

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++;
}

Обработка завершения записи последовательности переменных фотографий

Событие "Остановлено " вызывается, когда все кадры в последовательности были записаны. Обновите состояние записи приложения и обновите пользовательский интерфейс, чтобы пользователь могли инициировать новые записи. На этом этапе вы можете передать захваченные изображения и значения элементов управления кадрами в код обработки изображений.

void OnStopped(object s, object e)
{
    _isRecording = false;
    MyPostProcessingFunction(_images, _frameControlValues, 3);
}

Обновление контроллеров кадров

Если вы хотите выполнить запись другой переменной последовательности фотографий с разными параметрами кадра, вам не нужно полностью повторно инициализировать переменнуюPhotoSequenceCapture. Можно очистить коллекцию 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;