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

psf*_*sfx 2 windows windows-store win-universal-app

在Windows手机silverlight中,我在启动预览视频时使用PhotoCamera获取缓冲帧,在通用应用程序中我使用MediaCapture,但我不知道如何获取预览缓冲区.

谢谢

tho*_*rth 8

由于Windows运行时没有Silverlight的PhotoCaptureDevice课,非常有用GetPreviewBufferARGB()GetPreviewBufferYCbCr()方法不可用.

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

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

首先查看Microsoft 在Github上示例.这很好用但很复杂,因为它同时针对Windows 8.1和Windows Phone 8.1.

为了我自己的理解,我编写了一些更简单的代码,仅针对Windows Phone.它可能有所帮助.

首先使用通过NuGet PM安装Lumia Imaging SDK的新C#Windows Phone 8.1(Store)应用程序.此示例使用x:Name="previewImage"in 绘制到图像元素,MainPage.xaml因此请确保添加该元素.您还需要制作MainPage.xaml.cs我认为的相关进口产品.

using Lumia.Imaging;
using System.Threading.Tasks;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Core;
using System.ComponentModel;
Run Code Online (Sandbox Code Playgroud)

然后,您只需在正确的位置添加以下内容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;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能想知道...我如何获取previewBuffer?你不需要!

_writeableBitmap对象始终拥有从相机中最新的框架,所以你可以做任何你用它喜欢.