将VideoFrame转换为字节数组

时间:2015-07-02 15:16:06

标签: c# windows windows-runtime windows-10

我一直在尝试将捕获的VideoFrame对象转换为字节数组,但收效甚微。从文档中可以清楚地看出,每个帧都可以保存到SoftwareBitmap对象,例如

SoftwareBitmap bitmap = frame.SoftwareBitmap;

我已经能够将这个位图保存为图像,但我想获取它的数据并将其存储在一个字节数组中。许多SO问题已经解决了这个但是 SoftwareBitmap属于Windows.Graphics.Imaging命名空间(不是更典型的Xaml.Controls.Image,其他SO帖子解决了such as this one)所以像image.Save()这样的传统方法不可用。

似乎每个SoftwareBitmap都有一个CopyToBuffer()方法,但关于如何实际使用它的文档非常简洁。而且我也不确定这是否正确?

修改

使用艾伦的建议,我已成功实现了这一目标。我不确定它是否有用但是如果有其他人遇到这个代码,我会使用这些代码:

private void convertFrameToByteArray(SoftwareBitmap bitmap)
    {
        byte[] bytes;
        WriteableBitmap newBitmap = new WriteableBitmap(bitmap.PixelWidth, bitmap.PixelHeight);
        bitmap.CopyToBuffer(newBitmap.PixelBuffer);
        using (Stream stream = newBitmap.PixelBuffer.AsStream())
        using (MemoryStream memoryStream = new MemoryStream())
        {
            stream.CopyTo(memoryStream);
            bytes = memoryStream.ToArray();
        }

        // do what you want with the acquired bytes
        this.videoFramesAsBytes.Add(bytes);
    }

2 个答案:

答案 0 :(得分:2)

通过使用CopyToBuffer()方法,您可以将像素数据复制到WriteableBitmap的PixelBuffer。

然后我认为您可以参考the answer in this question将其转换为字节数组。

答案 1 :(得分:0)

对于希望从byte[](例如jpeg)访问 编码 SoftwareBitmap数组的任何人:

private async void PlayWithData(SoftwareBitmap softwareBitmap)
{
    var data = await EncodedBytes(softwareBitmap, BitmapEncoder.JpegEncoderId);

    // todo: save the bytes to a DB, etc
}

private async Task<byte[]> EncodedBytes(SoftwareBitmap soft, Guid encoderId)
{
    byte[] array = null;

    // First: Use an encoder to copy from SoftwareBitmap to an in-mem stream (FlushAsync)
    // Next:  Use ReadAsync on the in-mem stream to get byte[] array

    using (var ms = new InMemoryRandomAccessStream())
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, ms);
        encoder.SetSoftwareBitmap(soft);

        try
        {
            await encoder.FlushAsync();
        }
        catch ( Exception ex ){ return new byte[0]; }

        array = new byte[ms.Size];
        await ms.ReadAsync(array.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
    }
    return array;
}