将SoftwareBitmap转换为WriteableBitmap

5
每次我想把我的SoftwareBitmap 转换成 WriteableBitmap时,都会出现以下异常:System.Runtime.InteropServices.COMException
以下是我转换的代码片段:
 private async void Start(object sender, RoutedEventArgs e)
        {

            _MediaCapture = new MediaCapture();
            await _MediaCapture.InitializeAsync();

            mediaElement.Source = _MediaCapture;
            await _MediaCapture.StartPreviewAsync();
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 0, 1);
            timer.Tick += HandleTimerTick;
            timer.Start();
        }

        private async void HandleTimerTick(object Sender, object E)
        {


            var frame = await _MediaCapture.GetPreviewFrameAsync();
            SoftwareBitmap frameBitmap = frame.SoftwareBitmap;
            WriteableBitmap bitmap = new WriteableBitmap(frameBitmap.PixelWidth, frameBitmap.PixelHeight);
            try
            {
                frameBitmap.CopyToBuffer(bitmap.PixelBuffer);
            }
            catch (Exception)
            {
                Debug.WriteLine("Exception ");
            }
        }

这行

frameBitmap.CopyToBuffer(bitmap.PixelBuffer); 

抛出异常。

我正在一个x64远程设备上进行调试。


抛出了什么异常? - Dmitry Bychenko
@Dmitry Bychenko 看上面: System.Runtime.InteropServices.COMException - TheTanic
旁注:吞噬异常,例如catch (Exception) { Debug.WriteLine("Exception "); }是一种非常糟糕的做法。 - Dmitry Bychenko
我知道那个问题。只是为了澄清一下而已。不过感谢你的提醒。 - TheTanic
1
未来参考,请查看SDK示例:https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraGetPreviewFrame - Mike
1个回答

6

我可以使用你的代码重现这个问题。它是由frame.SoftwareBitmap始终返回null造成的。

您可以通过以下代码来解决此问题:

    private async void button_Click(object sender, RoutedEventArgs e)
    {
        _mediaCapture = new MediaCapture();

        await _mediaCapture.InitializeAsync();

        mediaElement.Source = _mediaCapture;

        await _mediaCapture.StartPreviewAsync();

        DispatcherTimer timer = new DispatcherTimer();
        timer.Interval = new TimeSpan(0, 0, 0, 1);
        timer.Tick += Timer_Tick;
        timer.Start();
    }

    private async void Timer_Tick(object sender, object e)
    {
        var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

        var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);

        var frame = await _mediaCapture.GetPreviewFrameAsync(videoFrame);

        SoftwareBitmap frameBitmap = frame.SoftwareBitmap;

        WriteableBitmap bitmap = new WriteableBitmap(frameBitmap.PixelWidth, frameBitmap.PixelHeight);

        frameBitmap.CopyToBuffer(bitmap.PixelBuffer);

        Debug.WriteLine("done");
    }

运行正常。谢谢。 - TheTanic
@Jeffrey,我不明白这有什么帮助...看起来唯一的区别就是使用GetPreviewFrameAsync的返回值。这没有意义!如果函数使用传递的VideoFrame进行填充,那么它应该以不同的方式记录。您能否告诉我在InitializeAsync中指定不同的位图像素格式与VideoFrame中是否会有性能损失? - Arian Kulp
@Jeffrey 为了明确...它确实有效!我只是困惑为什么。 - Arian Kulp
请查看文档的“重要”部分,位于此页面底部:https://msdn.microsoft.com/zh-cn/library/windows/apps/mt280228.aspx - Mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接