将 VideoFrame 转换为字节数组

Converting a VideoFrame to a byte array

我一直在尝试转换捕获的 VideoFrame object to a byte array with little success. It is clear from the documentation that each frame can be saved to a SoftwareBitmap 对象,例如

SoftwareBitmap bitmap = frame.SoftwareBitmap;

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

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

编辑:

根据下面 Alan 的建议,我成功地完成了这项工作。我不确定它是否有用,但这是我在其他人遇到此问题时使用的代码:

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

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

那我觉得你可以参考the answer in this question把它转成字节数组

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

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