Yuv422、Nv12转C#Bitmap

这段代码展示了如何将Nv12和Yuv422格式的图像数据转换成Bitmap。通过定义的nv12ToRgb和Yuv2Rgb函数,将YUV数据转换为RGB并填充到Bitmap中,最后用系统库创建并显示Bitmap。
摘要由CSDN通过智能技术生成

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);

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mark-puls

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值