Advertisement

YUV转RGB汇总

阅读量:
复制代码
 #region ******************彩色图像记录的格式,YUV 转 RGB******************

    
  
    
     /* YUV, http://zh.wikipedia.org/wiki/YUV#.E5.B8.B8.E7.94.A8.E7.9A.84YUV.E6.A0.BC.E5.BC.8F
    
      *  作为视频媒体类型的辅助说明类型(Subtype),它们对应的GUID如下:
    
      *  在DirectShow中,常见的RGB和YUV格式
    
         GUID                                格式描述
    
         MEDIASUBTYPE_RGB1                       2色,每个像素用1位表示,需要调色板
    
         MEDIASUBTYPE_RGB4                       16色,每个像素用4位表示,需要调色板
    
         MEDIASUBTYPE_RGB8                       256色,每个像素用8位表示,需要调色板
    
         MEDIASUBTYPE_RGB565                     每个像素用16位表示,RGB分量分别使用5位、6位、5位
    
         MEDIASUBTYPE_RGB555                     每个像素用16位表示,RGB分量都使用5位(剩下的1位不用)
    
         MEDIASUBTYPE_RGB24                      每个像素用24位表示,RGB分量各使用8位
    
         MEDIASUBTYPE_RGB32                      每个像素用32位表示,RGB分量各使用8位(剩下的8位不用)
    
         MEDIASUBTYPE_ARGB32                     每个像素用32位表示,RGB分量各使用8位(剩下的8位用于表示Alpha通道值)

         MEDIASUBTYPE_YUY2                    YUY2格式,以4:2:2方式打包
    
         MEDIASUBTYPE_YUYV                    YUYV格式(实际格式与YUY2相同)
    
         MEDIASUBTYPE_YVYU                    YVYU格式,以4:2:2方式打包
    
         MEDIASUBTYPE_UYVY                    UYVY格式,以4:2:2方式打包
    
         MEDIASUBTYPE_AYUV                    带Alpha通道的4:4:4 YUV格式
    
         MEDIASUBTYPE_Y41P                    Y41P格式,以4:1:1方式打包
    
         MEDIASUBTYPE_Y411                    Y411格式(实际格式与Y41P相同)
    
         MEDIASUBTYPE_Y211                    Y211格式
    
         MEDIASUBTYPE_IF09                    IF09格式
    
         MEDIASUBTYPE_IYUV                    IYUV格式
    
         MEDIASUBTYPE_YV12                    YV12格式
    
         MEDIASUBTYPE_YVU9                    YVU9格式
    
      */
    
  
    
  
    
     #region RGB TO RGB32
    
  
    
     /* RGB32 */
    
     /// <summary>
    
     /// 根据指针地址及内存块长度,获取RGB32数组
    
     /// @20140516
    
     /// </summary>
    
     /// <param name="pBuffer"></param>
    
     /// <param name="lBufferSize"></param>
    
     /// <param name="lPicWidth"></param>
    
     /// <param name="lPicHeight"></param>
    
     /// <returns></returns>
    
     public static byte[] GetRgb32_FromIntptr(IntPtr pBuffer, Int32 lBufferSize, Int32 lPicWidth, Int32 lPicHeight)
    
     {
    
         // 设置数组大小
    
         byte[] rgba32 = new byte[lPicHeight * lPicWidth * 4];
    
         Marshal.Copy(pBuffer, rgba32, 0, lBufferSize);
    
  
    
         return rgba32;
    
     }
    
  
    
     #endregion
    
  
    
  
    
     #region YUV TO RGB32
    
  
    
     /// <summary>
    
     /// YUV 转 RGB32
    
     /// </summary>
    
     /// <param name="pYPlaneByte"></param>
    
     /// <param name="pVPlaneByte"></param>
    
     /// <param name="pUPlaneByte"></param>
    
     /// <param name="lPicHeight"></param>
    
     /// <param name="lPicWidth"></param>
    
     /// <param name="bError">是否存在错误</param>
    
     /// <param name="strErrorDesc">错误消息</param>
    
     /// <returns></returns>
    
     public static byte[] GetRgb32_From_Yuv(byte[] pYPlaneByte, byte[] pUPlaneByte, byte[] pVPlaneByte, Int32 lPicHeight, Int32 lPicWidth, ref bool bError, ref string strErrorDesc)
    
     {
    
         bError = true;
    
         strErrorDesc = "无错误";
    
         int picSize = lPicWidth * lPicHeight;
    
  
    
         byte[] pRrgaByte = new byte[picSize * 4];
    
         int A = 0;
    
  
    
         try
    
         {
    
             for (int iRow = 0; iRow < lPicHeight; iRow++)
    
             {
    
                 for (int jCol = 0; jCol < lPicWidth; jCol++)
    
                 {
    
                     //int Y = pYPlane[i * dwWidth + j];
    
                     //int U = pUPlane[(i / 2) * (dwWidth / 2) + (j / 2)];
    
                     //int V = pVPlane[(i / 2) * (dwWidth / 2) + (j / 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 = max(0, min(255, R));
    
                     //G = max(0, min(255, G));
    
                     //B = max(0, min(255, B));
    
  
    
                     int Y = pYPlaneByte[iRow * lPicWidth + jCol];
    
                     int U = pUPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];
    
                     int V = pVPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];
    
  
    
                     /* 存在颜色转换错误问题。现象:公交车编号的LED灯显示颜色,与实际不符。如K30,图片上的30颜色为蓝色,但实际上30是红色 */
    
                     /* 1、宣传横幅,红色变成蓝色 */
    
                     /* 2、公交编号LED,红色变成蓝色 */
    
                     /* 3、信号灯LED,红色变成蓝色 */
    
                     //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);
    
  
    
                     // http://zh.wikipedia.org/wiki/YUV#YV12
    
                     //Int32 R = Y + 1.13983 * (V - 128);
    
                     //Int32 G = Y - 0.39456 * (U - 128) - 0.58060 * (V - 128);
    
                     //Int32 B = Y + 2.03211 * (U - 128);
    
  
    
                     /* 2012.12.24,纠正颜色错位问题R与B */
    
                     int R = Y + (V - 128) + (((V - 128) * 103) >> 8);
    
                     int G = Y - (((U - 128) * 88) >> 8) - (((V - 128) * 183) >> 8);
    
                     int B = Y + (U - 128) + (((U - 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;
    
         }
    
         catch (Exception exp)
    
         {
    
             pRrgaByte = null;
    
  
    
             bError = false;
    
             strErrorDesc = exp.ToString();
    
             //throw;
    
         }
    
  
    
         return null;
    
     }
    
  
    
     /* YUV420 / I420 
    
      * 存储格式:yuv yuv yuv
    
      */
    
  
    
     /* YUV420P: 
    
      * 存储格式:yyyyyyyy uuuuuuuu vvvvv
    
      * yuv420p 和 YUV420的区别 在存储格式上有区别
    
         yuv420p:yyyyyyyy uuuuuuuu vvvvv
    
         yuv420: yuv yuv yuv
    
      */
    
  
    
     /// <summary>
    
     /// GetRgb32_From_Yuv420
    
     /// @20140521,内存排列顺序有疑问
    
     /// </summary>
    
     /// <param name="pYuvPackedByte"></param>
    
     /// <param name="lBuffSize"></param>
    
     /// <param name="lPicHeight"></param>
    
     /// <param name="lPicWidth"></param>
    
     /// <param name="bError"></param>
    
     /// <param name="strErrorDesc"></param>
    
     /// <returns></returns>
    
     public static byte[] GetRgb32_From_Yuv420(byte[] pYuvPackedByte, Int32 lBuffSize, Int32 lPicHeight, Int32 lPicWidth, ref bool bError, ref string strErrorDesc)
    
     {
    
         bError = true;
    
         int picSize = lPicWidth * lPicHeight;
    
         strErrorDesc = string.Format("无错误.picSize4 = '{0}', lBuffSize1.5 = '{1}'", picSize * 4, lBuffSize * 3 / 2);
    
  
    
         byte[] pRrgaByte = new byte[picSize * 4];
    
         int A = 0;
    
  
    
         try
    
         {
    
             for (int iRow = 0; iRow < lPicHeight; iRow++)
    
             {
    
                 for (int jCol = 0; jCol < lPicWidth; jCol++)
    
                 {
    
                     int Y = pYuvPackedByte[iRow * lPicWidth + jCol + 0];
    
                     int U = pYuvPackedByte[iRow * lPicWidth + jCol + 1];
    
                     int V = pYuvPackedByte[iRow * lPicWidth + jCol + 2];
    
  
    
                     // http://zh.wikipedia.org/wiki/YUV#YV12
    
                     //Int32 R = Y + 1.13983 * (V - 128);
    
                     //Int32 G = Y - 0.39456 * (U - 128) - 0.58060 * (V - 128);
    
                     //Int32 B = Y + 2.03211 * (U - 128);
    
  
    
                     /* 2012.12.24,纠正颜色错位问题R与B */
    
                     int R = Y + (V - 128) + (((V - 128) * 103) >> 8);
    
                     int G = Y - (((U - 128) * 88) >> 8) - (((V - 128) * 183) >> 8);
    
                     int B = Y + (U - 128) + (((U - 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;
    
         }
    
         catch (Exception exp)
    
         {
    
             pRrgaByte = null;
    
  
    
             bError = false;
    
             strErrorDesc = exp.ToString();
    
             //throw;
    
         }
    
  
    
         return null;
    
     }
    
  
    
     /* UYVY / YVYU */
    
  
    
     /// <summary>
    
     /// 
    
     /// </summary>
    
     /// <param name="pYuvPackedByte"></param>
    
     /// <param name="lBuffSize"></param>
    
     /// <param name="lPicHeight"></param>
    
     /// <param name="lPicWidth"></param>
    
     /// <param name="bError"></param>
    
     /// <param name="strErrorDesc"></param>
    
     /// <returns></returns>
    
     public static byte[] GetRgb32_From_Uyvy(byte[] pYuvPackedByte, Int32 lBuffSize, Int32 lPicHeight, Int32 lPicWidth, ref bool bError, ref string strErrorDesc)
    
     {
    
         bError = true;
    
         int picSize = lPicWidth * lPicHeight;
    
         strErrorDesc = string.Format("无错误.picSize4 = '{0}', lBuffSize2 = '{1}'", picSize * 4, lBuffSize * 2);
    
  
    
         byte[] pRrgaByte = new byte[picSize * 4];
    
         //int A = 0;
    
  
    
         byte[] pYPlaneByte;
    
         byte[] pUPlaneByte;
    
         byte[] pVPlaneByte;
    
  
    
         try
    
         {
    
             // 使用每行跨距
    
             pYPlaneByte = new byte[lPicHeight * lPicWidth];
    
             pUPlaneByte = new byte[(lPicHeight) * (lPicWidth / 2)];
    
             pVPlaneByte = new byte[(lPicHeight) * (lPicWidth / 2)];
    
  
    
             for (int idxSrc = 0, idxDest = 0; idxSrc < lBuffSize; )
    
             {
    
                 pUPlaneByte[idxDest * 2] = pYuvPackedByte[idxSrc + 0];
    
                 pYPlaneByte[idxDest] = pYuvPackedByte[idxSrc + 1];
    
  
    
                 pVPlaneByte[idxDest * 2 + 1] = pYuvPackedByte[idxSrc + 2];
    
                 pYPlaneByte[idxDest] = pYuvPackedByte[idxSrc + 3];
    
  
    
                 idxSrc = idxSrc + 4;
    
                 idxDest++;
    
             }
    
  
    
             pRrgaByte = GetRgb32_From_Yuv(pYPlaneByte, pUPlaneByte, pVPlaneByte, lPicHeight, lPicWidth, ref bError, ref strErrorDesc);
    
  
    
             pYPlaneByte = null;
    
             pUPlaneByte = null;
    
             pVPlaneByte = null;
    
  
    
             return pRrgaByte;
    
         }
    
         catch (Exception exp)
    
         {
    
             pYPlaneByte = null;
    
             pUPlaneByte = null;
    
             pVPlaneByte = null;
    
  
    
             pRrgaByte = null;
    
  
    
             bError = false;
    
             strErrorDesc = exp.ToString();
    
             //throw;
    
         }
    
  
    
         return null;
    
     }
    
  
    
     /* YV12 / I420 
    
      * * YV12格式与IYUV类似,每个像素都提取Y,在UV提取时,将图像2 x 2的矩阵,每个矩阵提取一个U和一个V。
    
      * * YV12格式和I420格式的不同处在V平面和U平面的位置不同。在YV12格式中,V平面紧跟在Y平面之后,然后才是U平面(即:YVU);但I420则是相反(即:YUV)。
    
      * * NV12与YV12类似,效果一样,YV12中U和V是连续排列的,而在NV12中,U和V就交错排列的。
    
      */
    
  
    
     /// <summary>
    
     /// YV12 转 RGB32
    
     /// @在YV12格式中,V平面紧跟在Y平面之后,然后才是U平面(即:YVU);但I420则是相反(即:YUV)
    
     /// </summary>
    
     /// <param name="pYPlaneByte"></param>
    
     /// <param name="pVPlaneByte"></param>
    
     /// <param name="pUPlaneByte"></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;
    
  
    
         try
    
         {
    
             for (int iRow = 0; iRow < lPicHeight; iRow++)
    
             {
    
                 for (int jCol = 0; jCol < lPicWidth; jCol++)
    
                 {
    
                     //int Y = pYPlane[i * dwWidth + j];
    
                     //int U = pUPlane[(i / 2) * (dwWidth / 2) + (j / 2)];
    
                     //int V = pVPlane[(i / 2) * (dwWidth / 2) + (j / 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 = max(0, min(255, R));
    
                     //G = max(0, min(255, G));
    
                     //B = max(0, min(255, B));
    
  
    
                     int Y = pYPlaneByte[iRow * lPicWidth + jCol];
    
                     int U = pUPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];
    
                     int V = pVPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];
    
  
    
                     /* 存在颜色转换错误问题。现象:公交车编号的LED灯显示颜色,与实际不符。如K30,图片上的30颜色为蓝色,但实际上30是红色 */
    
                     /* 1、宣传横幅,红色变成蓝色 */
    
                     /* 2、公交编号LED,红色变成蓝色 */
    
                     /* 3、信号灯LED,红色变成蓝色 */
    
                     //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);
    
  
    
                     /* 2012.12.24,纠正颜色错位问题R与B */
    
                     int R = Y + (V - 128) + (((V - 128) * 103) >> 8);
    
                     int G = Y - (((U - 128) * 88) >> 8) - (((V - 128) * 183) >> 8);
    
                     int B = Y + (U - 128) + (((U - 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;
    
         }
    
         catch (Exception exp)
    
         {
    
             pRrgaByte = null;
    
             //throw;
    
         }
    
  
    
         return null;
    
     }
    
  
    
     / <summary>
    
     / YV12 转 RGB32(GetRgb32_From_Yv12_20130417,纠正R与B的转换错误)
    
     / </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_20130417(byte[] pYPlaneByte, byte[] pUPlaneByte, byte[] pVPlaneByte, Int32 lPicHeight, Int32 lPicWidth)
    
     //{
    
     //    try
    
     //    {
    
     //        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 = pYPlane[i * dwWidth + j];
    
     //                //int U = pUPlane[(i / 2) * (dwWidth / 2) + (j / 2)];
    
     //                //int V = pVPlane[(i / 2) * (dwWidth / 2) + (j / 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 = max(0, min(255, R));
    
     //                //G = max(0, min(255, G));
    
     //                //B = max(0, min(255, B));
    
  
    
     //                int Y = pYPlaneByte[iRow * lPicWidth + jCol];
    
     //                int U = pUPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];
    
     //                int V = pVPlaneByte[(iRow / 2) * (lPicWidth / 2) + (jCol / 2)];
    
  
    
     //                /* 存在颜色转换错误问题。现象:公交车编号的LED灯显示颜色,与实际不符。如K30,图片上的30颜色为蓝色,但实际上30是红色 */
    
     //                //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);
    
  
    
     //                /* 2012.12.24,纠正颜色错位问题R与B */
    
     //                int R = Y + (V - 128) + (((V - 128) * 103) >> 8);
    
     //                int G = Y - (((U - 128) * 88) >> 8) - (((V - 128) * 183) >> 8);
    
     //                int B = Y + (U - 128) + (((U - 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;
    
     //    }
    
     //    catch (Exception exp)
    
     //    {
    
     //        //throw;
    
     //    }
    
  
    
     //    return null;
    
     //}
    
  
    
  
    
     static double[,] YUV2RGB_CONVERT_MATRIX = new double[3, 3] { { 1, 0, 1.4022 }, { 1, -0.3456, -0.7145 }, { 1, 1.771, 0 } };
    
  
    
     /// <summary>
    
     /// YUV420 转 RGB 参考地址http://www.haogongju.net/art/953565
    
     /// </summary>
    
     /// <param name="yuvFrame">yuv数据</param>
    
     /// <param name="width">图片宽</param>
    
     /// <param name="height">图片高</param>
    
     /// <returns></returns>
    
     public static byte[] ConvertYUV420RGB(byte[] yuvFrame, int width, int height)
    
     {
    
  
    
         int gIndex = width * height;
    
         int uIndex = width * height;
    
         int vIndex = uIndex + ((width * height) >> 2);
    
  
    
         byte[] rgbFrame = new byte[gIndex * 3];
    
  
    
         int bIndex = gIndex * 2;
    
  
    
         int temp = 0;
    
  
    
         for (int y = 0; y < height; y++)
    
         {
    
             for (int x = 0; x < width; x++)
    
             {
    
  
    
                 // R分量       
    
                 temp = (int)(yuvFrame[y * width + x] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[0, 2]);
    
                 rgbFrame[y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
    
  
    
                 // G分量      
    
                 temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 1] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 2]);
    
                 rgbFrame[gIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
    
  
    
                 // B分量            
    
                 temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[2, 1]);
    
                 rgbFrame[bIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
    
                 //rgbFrame[bIndex + y * width + x] = Math.Max(0, Math.Min(255, temp));
    
  
    
             }
    
         }
    
         return rgbFrame;
    
  
    
     }
    
  
    
     public static byte[] ConvertYUV420RGB(byte[] pYPlaneByte, byte[] pUPlaneByte, byte[] pVPlaneByte, Int32 lPicHeight, Int32 lPicWidth)
    
     {
    
  
    
         return null;
    
     }
    
  
    
     #endregion
    
  
    
     #endregion
    
    
    
    
    代码解释

全部评论 (0)

还没有任何评论哟~