YV12转换到RGB32[]
来源:互联网 发布:java获取字符串编码 编辑:程序博客网 时间:2024/05/21 15:51
在做视频回调解码时,需要用到数据转换,找了很多,后来公司同事写了一个,基本上可以通用,发出来给大家分享下。
/// <summary> /// 将YV12转换成RGB32 /// </summary> /// <param name="pYU12">yv12数据</param> /// <param name="lPicHeight">图片高度</param> /// <param name="lPicWidth">图片宽度</param> /// <returns></returns> public static byte[] GetRgb32_From_Yv12(IntPtr pYV12, Int32 lPicHeight, Int32 lPicWidth) { // YUV平面 byte[] pYPlaneByte = new byte[lPicHeight * lPicWidth]; byte[] pUPlaneByte = new byte[(lPicHeight / 2) * (lPicWidth / 2)]; byte[] pVPlaneByte = new byte[(lPicHeight / 2) * (lPicWidth / 2)]; // 根据解码数据首地址及分量长度,进行地址偏移,获取各YUV分量的内存地址 IntPtr pYPlaneAddr = (IntPtr)(pYV12.ToInt32() + 0); IntPtr pUPlaneAddr = (IntPtr)(pYV12.ToInt32() + lPicHeight * lPicWidth); IntPtr pVPlaneAddr = (IntPtr)(pYV12.ToInt32() + lPicHeight * lPicWidth + (lPicHeight / 2) * (lPicWidth / 2)); // 将YUV数据从非托管内存指针复制到托管 8 位无符号整数数组。 Marshal.Copy(pYPlaneAddr, pYPlaneByte, 0, lPicHeight * lPicWidth); Marshal.Copy(pUPlaneAddr, pUPlaneByte, 0, (lPicHeight / 2) * (lPicWidth / 2)); Marshal.Copy(pVPlaneAddr, pVPlaneByte, 0, (lPicHeight / 2) * (lPicWidth / 2)); //YV12转换到RGB32 byte[] Rgba32 = GetRgb32_From_Yv12(pYPlaneByte, pUPlaneByte, pVPlaneByte, lPicHeight, lPicWidth); return Rgba32; } /// <summary> /// YUV12转RGB32 /// </summary> /// <param name="pYPlaneByte"></param> /// <param name="pUPlaneByte"></param> /// <param name="pVPlaneByte"></param> /// <param name="lPicHeight"></param> /// <param name="lPicWidth"></param> /// <returns></returns> public static byte[] GetRgb32_From_Yv12(byte[] pYPlaneByte, byte[] pUPlaneByte, byte[] pVPlaneByte, Int32 lPicHeight, Int32 lPicWidth) { int picSize = lPicWidth * lPicHeight; byte[] pRrgaByte = new byte[picSize * 4]; int A = 0; for (int iRow = 0; iRow < lPicHeight; iRow++) { for (int jCol = 0; jCol < lPicWidth; jCol++) { int Y = pYPlaneByte[iRow * lPicWidth + jCol]; int U = pUPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)]; int V = pVPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)]; int R = Y + (U - 128) + (((U - 128) * 103) >> 8); int G = Y - (((V - 128) * 88) >> 8) - (((U - 128) * 183) >> 8); int B = Y + (V - 128) + (((V - 128) * 198) >> 8); R = Math.Max(0, Math.Min(255, R)); G = Math.Max(0, Math.Min(255, G)); B = Math.Max(0, Math.Min(255, B)); pRrgaByte[4 * (iRow * lPicWidth + jCol) + 0] = Convert.ToByte(B); pRrgaByte[4 * (iRow * lPicWidth + jCol) + 1] = Convert.ToByte(G); pRrgaByte[4 * (iRow * lPicWidth + jCol) + 2] = Convert.ToByte(R); pRrgaByte[4 * (iRow * lPicWidth + jCol) + 3] = Convert.ToByte(A); //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 0] = Convert.ToByte(R); //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 1] = Convert.ToByte(G); //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 2] = Convert.ToByte(B); //pRrgaByte[4 * (iRow * lPicWidth + jCol) + 3] = Convert.ToByte(A); } } return pRrgaByte; }