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