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

	
				
		
原创粉丝点击