如何获取MediaCapture的预览缓冲区 – 通用应用程序

Windows Phone Silverlight中,我使用PhotoCamera来获取缓冲区框架,当开始预览video时,在通用应用程序中我使用了MediaCapture,但是我不知道如何获得预览缓冲区。

谢谢

由于Windows运行时没有Silverlight的PhotoCaptureDevice类,因此非常有用的GetPreviewBufferARGB()GetPreviewBufferYCbCr()方法不可用。

您正在寻找的解决方案是使用MediaCapture.StartPreviewToCustomSinkAsync()方法,但是这需要C ++技能比我更好。 没有人似乎已经解决了这个问题,并分享了他们的代码。

现在有一个非常漂亮的解决方案 ,使用Lumia Imaging SDK ,不使用MediaCapture类,但可能会更好地解决您的问题。

先看看微软在Github上的例子 。 这工作得很好,但相当复杂,因为它既针对Windows 8.1也针对Windows Phone 8.1。

我已经写了一些简单的代码,只是针对Windows Phone,为我自己的理解。 这可能有帮助。

从一个新的C#Windows Phone 8.1(Store)应用程序开始,通过NuGet PM安装Lumia Imaging SDK。 这个例子在MainPage.xaml绘制一个带有x:Name="previewImage"的图像元素,所以确保你添加了这个元素。 您还需要将相关的导入到我认为是的MainPage.xaml.cs中。

 using Lumia.Imaging; using System.Threading.Tasks; using Windows.UI.Xaml.Media.Imaging; using Windows.UI.Core; using System.ComponentModel; 

然后,您只需在MainPage.xaml.cs的正确位置添加以下内容。

 private CameraPreviewImageSource _cameraPreviewImageSource; // Using camera as our image source private WriteableBitmap _writeableBitmap; private FilterEffect _effect; private WriteableBitmapRenderer _writeableBitmapRenderer; // renderer for our images private bool _isRendering = false; // Used to prevent multiple renderers running at once public MainPage() { this.InitializeComponent(); this.NavigationCacheMode = NavigationCacheMode.Required; startCameraPreview(); } private async Task startCameraPreview() { // Create a camera preview image source (from the Lumia Imaging SDK) _cameraPreviewImageSource = new CameraPreviewImageSource(); await _cameraPreviewImageSource.InitializeAsync(string.Empty); // use the first available camera (ask me if you want code to access other camera) var previewProperties = await _cameraPreviewImageSource.StartPreviewAsync(); _cameraPreviewImageSource.PreviewFrameAvailable += drawPreview; // call the drawPreview method every time a new frame is available // Create a preview bitmap with the correct aspect ratio using the properties object returned when the preview started. var width = 640.0; var height = (width / previewProperties.Width) * previewProperties.Height; var bitmap = new WriteableBitmap((int)width, (int)height); _writeableBitmap = bitmap; // Create a BitmapRenderer to turn the preview Image Source into a bitmap we hold in the PreviewBitmap object _effect = new FilterEffect(_cameraPreviewImageSource); _effect.Filters = new IFilter[0]; // null filter for now _writeableBitmapRenderer = new WriteableBitmapRenderer(_effect, _writeableBitmap); } private async void drawPreview(IImageSize args) { // Prevent multiple rendering attempts at once if (_isRendering == false) { _isRendering = true; await _writeableBitmapRenderer.RenderAsync(); // Render the image (with no filter) // Draw the image onto the previewImage XAML element await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { previewImage.Source = _writeableBitmap; // previewImage is an image element in MainPage.xaml _writeableBitmap.Invalidate(); // force the PreviewBitmap to redraw }); _isRendering = false; } } 

您可能想知道…我如何抓住previewBuffer? 你不需要!

_writeableBitmap对象始终保存来自相机的最新帧,所以你可以_writeableBitmap做任何事情。

我的其他答案仍然适用于面向Windows 8.1的通用应用程序 – 但对于那些针对具有UWP应用程序的Windows 10的用户,现在有一个更简单的答案。

在UWP中抓取预览框架很容易并且有很好的记录 – 从现有的MediaCapture对象中可以完成三行。

 // Get information about the preview var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties; // Create a video frame in the desired format for the preview frame VideoFrame videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Height, (int)previewProperties.Width); // Grave a preview frame VideoFrame previewFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame);