Bitmapimage C中的NV12格式支持#

时间:2013-07-16 14:02:51

标签: c# bitmapimage yuv writeablebitmap

BitmapImageWriteableBitmapImage是否支持NV12格式。或者我们可以从以NV12格式排列的字节数组创建BitmapImageWriteableBitmapImage吗?

由于

2 个答案:

答案 0 :(得分:0)

不。 NV12不在受支持的PixelFormats中。

您必须首先将字节数组转换为受支持的像素格式。 This的答案显示了如何针对YUV进行此操作,并且可能会帮助您编写类似的方法来从NV12进行转换。

编辑:

Here是C ++代码,用于将NV21(!)转换为RGB。与NV12的唯一区别是UV值的顺序,因此很容易适应。

答案 1 :(得分:0)

带着这个答案从未来滑入。

此方法将 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 示例存储库,here

相关问题