C# 将视频帧转换为字节数组

C# 将视频帧转换为字节数组,c#,windows,windows-runtime,windows-10,C#,Windows,Windows Runtime,Windows 10,我一直在尝试将捕获的对象转换为字节数组,但收效甚微。从文档中可以清楚地看出,每个帧都可以保存到一个对象中,例如 SoftwareBitmap bitmap = frame.SoftwareBitmap; 我已经能够将此位图保存为图像,但我想获取它的数据并将其存储在字节数组中。很多问题已经解决了这个问题,但是软件位图属于Windows.Graphics.Imaging名称空间(不是其他SO发布地址的更典型的Xaml.Controls.Image),所以像Image.Save()这样的传统方法不可

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

SoftwareBitmap bitmap = frame.SoftwareBitmap;
我已经能够将此位图保存为图像,但我想获取它的数据并将其存储在字节数组中。很多问题已经解决了这个问题,但是软件位图属于Windows.Graphics.Imaging名称空间(不是其他SO发布地址的更典型的Xaml.Controls.Image),所以像
Image.Save()
这样的传统方法不可用

似乎每个软件位图都有一个
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);
    }

通过使用
CopyToBuffer()
方法,可以将像素数据复制到可写位图的像素缓冲区


然后我想您可以参考将其转换为字节数组。

对于希望从
软件位图(例如jpeg)访问编码的
字节[]
数组的任何人:

private async void PlayWithData(软件位图软件位图)
{
var data=await EncodedBytes(软件位图、位图编码器.JpegEncoderId);
//todo:将字节保存到数据库中,等等
}
专用异步任务EncodedBytes(软件位图软件,Guid encoderId)
{
字节[]数组=null;
//第一:使用编码器将软件位图复制到内存中的流(FlushAsync)
//下一步:在内存流中使用ReadAsync获取字节[]数组
使用(var ms=new InMemoryRandomAccessStream())
{
BitmapEncoder编码器=等待BitmapEncoder.CreateAsync(encoderId,ms);
编码器。设置软件EBITMAP(软);
尝试
{
等待编码器。FlushAsync();
}
catch(异常ex){返回新字节[0];}
数组=新字节[ms.Size];
等待ms.ReadAsync(array.AsBuffer(),(uint)ms.Size,InputStreamOptions.None);
}
返回数组;
}
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;
}