Photo​Confirmation​Captured​Event​Args Photo​Confirmation​Captured​Event​Args Photo​Confirmation​Captured​Event​Args Class

Definition

Provides data for the PhotoConfirmationCaptured event.

public sealed class PhotoConfirmationCapturedEventArgs : IPhotoConfirmationCapturedEventArgspublic sealed class PhotoConfirmationCapturedEventArgs : IPhotoConfirmationCapturedEventArgsPublic NotInheritable Class PhotoConfirmationCapturedEventArgs Implements IPhotoConfirmationCapturedEventArgs
Attributes
Windows 10 requirements
Device family
Windows 10 (introduced v10.0.10240.0)
API contract
Windows.Foundation.UniversalApiContract (introduced v1)

Remarks

Handle the MediaCapture.PhotoConfirmationCaptured event to get an instance of this class.

Properties

CaptureTimeOffset CaptureTimeOffset CaptureTimeOffset

Gets the time offset from when capture began to the capture of the frame associated with the event.

public TimeSpan CaptureTimeOffset { get; }public TimeSpan CaptureTimeOffset { get; }Public ReadOnly Property CaptureTimeOffset As TimeSpan
Value
TimeSpan TimeSpan TimeSpan

The time offset from when capture began to the capture of the frame associated with the event.

Attributes

Frame Frame Frame

Gets the captured frame.

public CapturedFrame Frame { get; }public CapturedFrame Frame { get; }Public ReadOnly Property Frame As CapturedFrame
Value
CapturedFrame CapturedFrame CapturedFrame

The captured frame.

Attributes

Remarks

The data returned in the Frame property is raw pixel data. In other words, it does not include an image file format header. Because of this, you can't pass the captured frame's stream to the bitmap's SetSourceAsync method directly. Instead, you must copy the pixel data manually into the bitmap's pixel buffer. The following code snippets show you how to copy the image data and provide a helper class that performs the operation.

First, you need to enable photo confirmation and hook up the PhotoConfirmationCaptured event.

private void EnablePhotoConfirmation()
{
    _mediaCapture.VideoDeviceController.PhotoConfirmationControl.Enabled = true;
    _mediaCapture.PhotoConfirmationCaptured += PhotoConfirmationCaptured;
}
void PhotoConfirmationCaptured(MediaCapture sender, PhotoConfirmationCapturedEventArgs args)
{
    using (ManualResetEventSlim evt = new ManualResetEventSlim(false))
    {
        CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            try
            {
                WriteableBitmap bmp = new WriteableBitmap(unchecked((int)args.Frame.Width), unchecked((int)args.Frame.Height));
                using (var istream = args.Frame.AsStream())
                using (var ostream = bmp.PixelBuffer.AsStream())
                {
                    await istream.CopyStreamToAsync(ostream);
                }
            }
            finally
            {
                evt.Set();
            }

        });

        evt.Wait();
    }

}

The following code snippet shows the helper class that defines the extension methods for the copying captured frame data into the writeable bitmap's pixel data stream. The class provides synchronous and asynchronous methods and overloads that allow you to specify a copy buffer size or use a default size.


public static class StreamEx
{
    public static void CopyStreamTo(this Stream inputStream, Stream outputStream)
    {
        inputStream.CopyStreamTo(outputStream, 4096);
    }

    public static void CopyStreamTo(this Stream inputStream, Stream outputStream, int bufferSize)
    {
        if (inputStream == null)
        {
            throw new ArgumentNullException("inputStream");
        }

        if (!inputStream.CanSeek)
        {
            throw new ArgumentException("Cannot seek in the input stream.", "inputStream");
        }

        if (!inputStream.CanRead)
        {
            throw new ArgumentException("Input stream is not readable.", "inputStream");
        }

        if (outputStream == null)
        {
            throw new ArgumentNullException("outputStream");
        }

        if (!outputStream.CanSeek)
        {
            throw new ArgumentException("Cannot seek in the output stream.", "outputStream");
        }

        if (!outputStream.CanWrite)
        {
            throw new ArgumentException("Output stream is not writeable.", "outputStream");
        }

        if (bufferSize <= 0)
        {
            throw new ArgumentOutOfRangeException("bufferSize", "Buffer size is equal to zero or negative.");
        }

        inputStream.Seek(0, SeekOrigin.Begin);
        outputStream.Seek(0, SeekOrigin.Begin);

        byte[] buffer = new byte[bufferSize];
        while (inputStream.Position < inputStream.Length)
        {
            int bytesRead = inputStream.Read(buffer, 0, buffer.Length);
            outputStream.Write(buffer, 0, bytesRead);
        }
    }

    public static Task CopyStreamToAsync(this Stream inputStream, Stream outputStream)
    {
        return Task.Run(() => CopyStreamTo(inputStream, outputStream));
    }

    public static Task CopyStreamToAsync(this Stream inputStream, Stream outputStream, int bufferSize)
    {
        return Task.Run(() => CopyStreamTo(inputStream, outputStream, bufferSize));
    }
}