是否BitmapImage
或WriteableBitmapImage
支持NV12
格式。或者我们可以创建一个BitmapImage
或WriteableBitmapImage
从一个以 NV12 格式排列的字节数组吗?
谢谢
是否BitmapImage
或WriteableBitmapImage
支持NV12
格式。或者我们可以创建一个BitmapImage
或WriteableBitmapImage
从一个以 NV12 格式排列的字节数组吗?
谢谢
不NV12
支持PixelFormats
。
您必须先将字节数组转换为受支持的像素格式。这个答案显示了如何做到这一点,YUV
并可能帮助您编写一个类似的方法来从NV12
.
编辑:
这是将NV21
(!) 转换为RGB
. 唯一的区别NV12
是U
和V
值的顺序,因此很容易适应。
带着这个答案从未来滑入。
此方法将 NV12 数据的 byte[] 数组转换为 BMP 图像。
public static Bitmap TransformNv12ToBmpFaster(byte[] data, int width, int height, IGraphLogger logger)
{
Stopwatch watch = new Stopwatch();
watch.Start();
var bmp = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
var bmpData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format32bppRgb);
var uvStart = width * height;
for (var y = 0; y < height; y++)
{
var pos = y * width;
var posInBmp = y * bmpData.Stride;
for (var x = 0; x < width; x++)
{
var vIndex = uvStart + ((y >> 1) * width) + (x & ~1);
//// https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx
//// https://en.wikipedia.org/wiki/YUV
var c = data[pos] - 16;
var d = data[vIndex] - 128;
var e = data[vIndex + 1] - 128;
c = c < 0 ? 0 : c;
var r = ((298 * c) + (409 * e) + 128) >> 8;
var g = ((298 * c) - (100 * d) - (208 * e) + 128) >> 8;
var b = ((298 * c) + (516 * d) + 128) >> 8;
r = r.Clamp(0, 255);
g = g.Clamp(0, 255);
b = b.Clamp(0, 255);
Marshal.WriteInt32(bmpData.Scan0, posInBmp + (x << 2), (b << 0) | (g << 8) | (r << 16) | (0xFF << 24));
pos++;
}
}
bmp.UnlockBits(bmpData);
watch.Stop();
logger.Info($"Took {watch.ElapsedMilliseconds} ms to lock and unlock");
return bmp;
}
我在这里得到了 Microsoft Graph Samples 存储库。