public void Test()
{
var nv12Binary = File.ReadAllBytes(@"C:\NV12.dat");
var height = 256; //BitmapInfoHeaderより
var width = 320; //BitmapInfoHeaderより
var uvStartIndex = height * width; //UVの開始位置を取得
var rgbBuffer = new byte[height * width * 3];
for (var h = 0; h < height; h++)
{
for (var w = 0; w < width; w += 2)
{
var u = nv12Binary[uvStartIndex + w + 0];
var v = nv12Binary[uvStartIndex + w + 1];
for (int cnt = 0; cnt < 2; cnt++)
{
var y = nv12Binary[h * width + h + cnt];
//var r = ((298 * (y - 16) + 409 * (v - 128) + 128) >> 8);
//var g = ((298 * (y - 16) - 100 * (u - 128) - 208 * (v - 128) + 128) >> 8);
//var b = ((298 * (y - 16) + 516 * (u - 128) + 128) >> 8);
var r = y + (1.370705 * (v - 128));
var g = y - (0.698001 * (v - 128)) - (0.337633 * (u - 128));
var b = y + (1.732446 * (u - 128));
rgbBuffer[(h * width + w + cnt) * 3 + 0] = ConvertByte(b);
rgbBuffer[(h * width + w + cnt) * 3 + 1] = ConvertByte(g);
rgbBuffer[(h * width + w + cnt) * 3 + 2] = ConvertByte(r);
}
}
uvStartIndex += width * (h % 2);//UV位置を移動
}
using (var img = new Bitmap(width, height, PixelFormat.Format24bppRgb))
{
var bitmapData = img.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
Marshal.Copy(rgbBuffer, 0, bitmapData.Scan0, rgbBuffer.Length);
img.UnlockBits(bitmapData);
img.Save(@"C:\Image.bmp",ImageFormat.Bmp);
}
}
private static byte ConvertByte(double value)
=> value > byte.MaxValue ? byte.MaxValue : (value < byte.MinValue ? byte.MinValue : (byte)value);