从MediaCapture访问预览框 [英] Access preview frame from MediaCapture

查看:595
本文介绍了从MediaCapture访问预览框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想抓住这显示我的 CaptureElement XAML元素内的预览画面。在我的 CaptureElement 设置为 MediaCapture 对象我用的是 StartPreview()方法来启动显示摄像机。我想访问正在显示的帧无将它们保存到一个img或视频文件。我们的目标是捕获从预览10帧,每帧发送到接受字节[] 另一个类。

I would like to grab the preview frames that are displayed inside my CaptureElement xaml element. The source of my CaptureElement is set to a MediaCapture object and I use the StartPreview() method to start displaying the camera. I would like to access the frames that are being shown without saving them to an img or video file. The goal is to capture 10 fps from the preview and send each frame to another class that accepts byte[].

我尝试使用 CapturePhotoToStorageFileAsync 办法然而,这是不是因为我不希望采取10实际的一个可行的选择张/秒。我也不想用抓屏,因为它存储了什么被捕获到的视频文件。理想情况下,我不希望暂时存储在手机上的媒体文件。在 MSDN 寻找<$ C后$ C> MediaCapture ,我注意到有一个名为 GetPreviewFrameAsync()然而,这种方法并不Windows Phone的8.1里面存在的方法。我还无意中发现了这个 的例子不能完全理解它是如何工作的。

I tried using the CapturePhotoToStorageFileAsync method however this is not a feasible option as I do not want to take 10 actual images / second. I also do not want to use ScreenCapture as it stores what is captured into a video file. Ideally I do not want to store any media files temporarily on the phone. After looking at the msdn for MediaCapture, I noticed there's a method called GetPreviewFrameAsync() however this method does not exist inside Windows Phone 8.1. I also stumbled on this example however I do not completely understand how it works.

推荐答案

有是微软GitHub的页面相关的样本,虽然他们面向Windows 10.您可能感兴趣的迁移项目中得到这个功能。

There is a sample on the Microsoft github page that is relevant, although they target Windows 10. You may be interested in migrating your project to get this functionality.

GetPreviewFrame :此示例将捕获预览画面,而不是全面的照片。一旦它有一个预览框,它可以在其上编辑像素

GetPreviewFrame: This sample will capture preview frames as opposed to full-blown photos. Once it has a preview frame, it can edit the pixels on it.

下面是相关的部分:

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);
}



当然,你的项目将允许不安全的代码,这一切工作。

And of course, your project will have to allow unsafe code for all of this to work.

有在样品仔细看看,看看如何让所有的细节。或者说,有一个演练中,您可以观看从相机会近期//构建/会议,其中包括通过一些相机样本演练一点点。

Have a closer look at the sample to see how to get all the details. Or, to have a walkthrough, you can watch the camera session from the recent //build/ conference, which includes a little bit of a walkthrough through some camera samples.

这篇关于从MediaCapture访问预览框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆