Yuv422、Nv12转C#Bitmap

1.1、Nv12转Bitmap

int w = 1920;

int h = 1080;

int iImageSize = w * h * 3;

byte[] bRgbData = new byte[iImageSize];

int iYuvSize = iImageSize / 2;

byte[] bYuvData = new byte[iYuvSize];

nv12ToRgb(bRgbData, bYuvData, w, h);

Bitmap ShowBitmap = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

BitmapData bmpData = ShowBitmap.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

System.Runtime.InteropServices.Marshal.Copy(bRgbData, 0, bmpData.Scan0, iImageSize);

ShowBitmap.UnlockBits(bmpData); // 解锁内存区域

1.2、Nv12转Bitmap函数

private void nv12ToRgb(byte[] bRgbData, byte[] bYuvData, int w, int h)

{

int iPosUV = 0;

int iStepY = w;

int iStepUV = w;

int iStepRGB = w * 3;

int iOffsetUV = w * h;

int iIndex1 = 0;

int iIndex2 = 0;

for (int i = 0; i < h; i += 2)

{

for (int j = 0; j < w; j += 2)

{

int y11 = Math.Max(0, (int)(bYuvData[i * iStepY + j + 0])) << 20;

int y12 = Math.Max(0, (int)(bYuvData[i * iStepY + j + 1])) << 20;

int y21 = Math.Max(0, (int)(bYuvData[(i + 1) * iStepY + j + 0])) << 20;

int y22 = Math.Max(0, (int)(bYuvData[(i + 1) * iStepY + j + 1])) << 20;

int u = (int)(bYuvData[iPosUV * iStepUV + iOffsetUV + j + 0]) - 128;

int v = (int)(bYuvData[iPosUV * iStepUV + iOffsetUV + j + 1]) - 128;

int ruv = 524288 + 2130771 * v;

int guv = 524288 - 413812 * v - 608826 * u;

int buv = 524288 + 1195254 * u;

//填第1行的RGB的两个像素

bRgbData[i * iStepRGB + iIndex1 + 0] = LimitValue((y11 + buv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 1] = LimitValue((y11 + guv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 2] = LimitValue((y11 + ruv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 3] = LimitValue((y12 + buv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 4] = LimitValue((y12 + guv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 5] = LimitValue((y12 + ruv) >> 20);

iIndex1 += 6;

//填第2行的RGB的两个像素

bRgbData[(i + 1) * iStepRGB + iIndex2 + 0] = LimitValue((y21 + buv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 1] = LimitValue((y21 + guv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 2] = LimitValue((y21 + ruv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 3] = LimitValue((y22 + buv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 4] = LimitValue((y22 + guv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 5] = LimitValue((y22 + ruv) >> 20);

iIndex2 += 6;

}

iPosUV++;

iIndex1 = 0;

iIndex2 = 0;

}

}

//转出来的Rgb值范围0 - 255

private byte LimitValue(int iValue)

{

if (iValue < 0) return 0;

if (iValue > 255) return 255;

else return (byte)iValue;

//return (byte)(iValue <= 255 ? iValue : iValue > 0 ? 255 : 0);

}

2.1、Yuv422转Bitmap

int w = 1920;

int h = 1080;

int iImageSize = w * h * 3;

byte[] bRgbData = new byte[iImageSize];

int iYuvSize = iImageSize * 2;

byte[] bYuvData = new byte[iYuvSize];

Yuv2Rgb(bRgbData, bYuvData, w, h);

Bitmap ShowBitmap = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

BitmapData bmpData = ShowBitmap.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

System.Runtime.InteropServices.Marshal.Copy(bRgbData, 0, bmpData.Scan0, iImageSize);

ShowBitmap.UnlockBits(bmpData); // 解锁内存区域

2.2、Yuv422转Bitmap函数

private void nv12ToRgb(byte[] bRgbData, byte[] bYuvData, int w, int h)

{

int iPosUV = 0;

int iStepY = w;

int iStepUV = w;

int iStepRGB = w * 3;

int iOffsetUV = w * h;

int iIndex1 = 0;

int iIndex2 = 0;

for (int i = 0; i < h; i += 2)

{

for (int j = 0; j < w; j += 2)

{

int y11 = Math.Max(0, (int)(bYuvData[i * iStepY + j + 0])) << 20;

int y12 = Math.Max(0, (int)(bYuvData[i * iStepY + j + 1])) << 20;

int y21 = Math.Max(0, (int)(bYuvData[(i + 1) * iStepY + j + 0])) << 20;

int y22 = Math.Max(0, (int)(bYuvData[(i + 1) * iStepY + j + 1])) << 20;

int u = (int)(bYuvData[iPosUV * iStepUV + iOffsetUV + j + 0]) - 128;

int v = (int)(bYuvData[iPosUV * iStepUV + iOffsetUV + j + 1]) - 128;

int ruv = 524288 + 2130771 * v;

int guv = 524288 - 413812 * v - 608826 * u;

int buv = 524288 + 1195254 * u;

//填第1行的RGB的两个像素

bRgbData[i * iStepRGB + iIndex1 + 0] = LimitValue((y11 + buv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 1] = LimitValue((y11 + guv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 2] = LimitValue((y11 + ruv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 3] = LimitValue((y12 + buv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 4] = LimitValue((y12 + guv) >> 20);

bRgbData[i * iStepRGB + iIndex1 + 5] = LimitValue((y12 + ruv) >> 20);

iIndex1 += 6;

//填第2行的RGB的两个像素

bRgbData[(i + 1) * iStepRGB + iIndex2 + 0] = LimitValue((y21 + buv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 1] = LimitValue((y21 + guv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 2] = LimitValue((y21 + ruv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 3] = LimitValue((y22 + buv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 4] = LimitValue((y22 + guv) >> 20);

bRgbData[(i + 1) * iStepRGB + iIndex2 + 5] = LimitValue((y22 + ruv) >> 20);

iIndex2 += 6;

}

iPosUV++;

iIndex1 = 0;

iIndex2 = 0;

}

}

//转出来的Rgb值范围0 - 255

private byte LimitValue(int iValue)

{

if (iValue < 0) return 0;

if (iValue > 255) return 255;

else return (byte)iValue;

//return (byte)(iValue <= 255 ? iValue : iValue > 0 ? 255 : 0);

}

Yuv422、Nv12转C#Bitmap_第1张图片

你可能感兴趣的:(C#编程,C#编程)