PhotoConfirmationCapturedEventArgs.Frame Property
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Gets the captured frame.
public:
property CapturedFrame ^ Frame { CapturedFrame ^ get(); };
CapturedFrame Frame();
public CapturedFrame Frame { get; }
var capturedFrame = photoConfirmationCapturedEventArgs.frame;
Public ReadOnly Property Frame As CapturedFrame
Property Value
The captured frame.
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));
}
}