将 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;
}
我一直在尝试转换捕获的 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;
}