从MediaCapture访问预览框架

我想抓住CaptureElement xaml元素中显示的预览帧。 我的CaptureElementsource设置为MediaCapture对象,我使用MediaCapture StartPreview()方法开始显示相机。 我想访问正在显示的帧而不将它们保存为img或video文件。 目标是从预览中捕获10 fps并将每个帧发送到另一个接受byte []的类

我尝试使用CapturePhotoToStorageFileAsync方法但是这不是一个可行的选项,因为我不想拍摄10张实际图像/秒。 我也不想使用ScreenCapture因为它将捕获的内容存储到video文件中。 理想情况下,我不想暂时将任何媒体文件存储在手机上。 在查看了MediaCapture的msdn MediaCapture ,我注意到有一个名为GetPreviewFrameAsync()方法,但Windows Phone 8.1中不存在此方法。 我也偶然发现了这个例子,但我并不完全理解它是如何工作的。

任何有关如何处理此问题的建议都非常感谢。

Microsoft github页面上有一个相关的示例,尽管它们的目标是Windows 10.您可能有兴趣迁移项目以获得此function。

GetPreviewFrame :此示例将捕获预览帧而不是完整的照片。 一旦它有预览框架,它就可以编辑它上面的像素。

以下是相关部分:

 private async Task GetPreviewFrameAsSoftwareBitmapAsync() { // Get information about the preview var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties; // Create the video frame to request a SoftwareBitmap preview frame var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height); // Capture the preview frame using (var currentFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame)) { // Collect the resulting frame SoftwareBitmap previewFrame = currentFrame.SoftwareBitmap; // Add a simple green filter effect to the SoftwareBitmap EditPixels(previewFrame); } } private unsafe void EditPixels(SoftwareBitmap bitmap) { // Effect is hard-coded to operate on BGRA8 format only if (bitmap.BitmapPixelFormat == BitmapPixelFormat.Bgra8) { // In BGRA8 format, each pixel is defined by 4 bytes const int BYTES_PER_PIXEL = 4; using (var buffer = bitmap.LockBuffer(BitmapBufferAccessMode.ReadWrite)) using (var reference = buffer.CreateReference()) { // Get a pointer to the pixel buffer byte* data; uint capacity; ((IMemoryBufferByteAccess)reference).GetBuffer(out data, out capacity); // Get information about the BitmapBuffer var desc = buffer.GetPlaneDescription(0); // Iterate over all pixels for (uint row = 0; row < desc.Height; row++) { for (uint col = 0; col < desc.Width; col++) { // Index of the current pixel in the buffer (defined by the next 4 bytes, BGRA8) var currPixel = desc.StartIndex + desc.Stride * row + BYTES_PER_PIXEL * col; // Read the current pixel information into b,g,r channels (leave out alpha channel) var b = data[currPixel + 0]; // Blue var g = data[currPixel + 1]; // Green var r = data[currPixel + 2]; // Red // Boost the green channel, leave the other two untouched data[currPixel + 0] = b; data[currPixel + 1] = (byte)Math.Min(g + 80, 255); data[currPixel + 2] = r; } } } } } 

并在课外宣布:

 [ComImport] [Guid("5b0d3235-4dba-4d44-865e-8f1d0e4fd04d")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] unsafe interface IMemoryBufferByteAccess { void GetBuffer(out byte* buffer, out uint capacity); } 

当然,您的项目必须允许所有这些的不安全代码才能工作。

仔细查看示例,了解如何获取所有详细信息。 或者,要进行演练,您可以观看最近//构建/会议中的摄像机会话 ,其中包括对一些摄像机示例的一些演练。