【问题标题】:Access preview frame from MediaCapture从 MediaCapture 访问预览帧
【发布时间】:2015-04-29 14:49:37
【问题描述】:

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

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

非常感谢任何有关如何解决此问题的建议。

【问题讨论】:

    标签: c# xaml windows-store-apps windows-phone-8.1


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 非常有趣!我最终使用了 Lumia Imaging SDK msdn.microsoft.com/en-us/library/dn859593.aspx,因为我需要支持当前的 Wp 8.1 设备。每当有可用的预览帧时,sdk 就会启动一个事件。来到 Wp 10,我一定会对此进行更多研究。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多