YUV420-RGB 以点的方式进行转换 原创by: GanYJ

YUV420-RGB 以点的方式进行转换 原创by: GanYJ

C++代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//YUV420-RGB 以点的方式进行转换  原创by: GanYJ
//可能的问题:在不同的计算机上,显示的色彩有问题,我试了几种算法,还是无法还原
  
struct mRGB
{ unsigned char R;
   unsigned char G;
   unsigned char B;
};
  
mRGB tempRGB[4];
  
void ConvertPointYUV2RGB(unsigned char *pFramBeg, int x, int y, int width, int height)
{
    unsigned char YUV_Y;
    unsigned char YUV_U;
    unsigned char YUV_V;
    unsigned char *pTemp[4]; //一次计算4个像素
  
     //4个像素共用一个UV值,只取一次值
      pTemp[0]=pFramBeg+height*width+(y/2)*(width)/2+(x/2); // =INT(y/2)*width+INT(x/2)*2  //计算U地址
      YUV_V=*pTemp[0];    //取U
      pTemp[0]=pTemp[0]+(height*width)/4; //加上前半部UV分量的长度,即是后部指针
      YUV_U=*(pTemp[0]);
  
  
      if (YUV_U>=128)  
          YUV_U=YUV_U-128;
      else
          YUV_U=128-YUV_U;
  
      if (YUV_V>=128)  
          YUV_V=YUV_V-128;
      else
          YUV_V=128-YUV_V;
  
     //取4个点的Y值
      pTemp[0]=pFramBeg+y*width+x; //指针计算
      pTemp[1]=pFramBeg+y*width+x+1; //指针计算
      pTemp[2]=pFramBeg+(y+1)*width+x; //指针计算
      pTemp[3]=pFramBeg+(y+1)*width+x+1; //指针计算
       
      //计算4次
     for ( int i=0;i<4;i++)
         {     YUV_Y=*pTemp[i];             //取Y值
  
                  if (YUV_Y>=16)  
                      YUV_Y=YUV_Y-16;
                  else
                      YUV_Y=16-YUV_Y;
                  //计算并保存结果
                  tempRGB[i].R=(( int )1000*(YUV_Y)+( int )1402*(YUV_V))/( int )1000;
                  tempRGB[i].G=(( int )1000*(YUV_Y)-( int )344*(YUV_U)-( int )714*(YUV_V))/( int )1000;
                  tempRGB[i].B=(( int )1000*(YUV_Y)+( int )1772*(YUV_U))/( int )1000;
  
             }
}
  
  
  
  unsigned char * YUV_2_RGB(unsigned char *YUV, int width, int height, bool snapbmp)
{
     int i,j;
     unsigned char *yAddress;
     unsigned char *pUV_Address_ahead_half;
     unsigned char *pUV_Address_behend_half;
     unsigned char * outBuffer=(unsigned char *) malloc (width*height*3);
     unsigned char * g_pBits = (unsigned char *) malloc (width*height*3); 
     yAddress=YUV; //指向数据帧的头,即Y分量
     pUV_Address_ahead_half=YUV+width*height;   //UV分量的指向前半部。
     pUV_Address_behend_half=pUV_Address_ahead_half+width*height/4;   //UV分量的指向后前半部。
      
     //ConvertYUV2RGB( yAddress,pUV_Address_ahead_half,pUV_Address_behend_half,outBuffer,width,height);//转换
     unsigned char *pTemp=outBuffer;
     //X Y均以2的倍数进行处理,以点的方式转RGB
     for (j = 0; j < height; j=j+2) 
     {    pTemp=outBuffer+3*j*width;
         for (i = 0; i < width; i=i+2) 
         {
             ConvertPointYUV2RGB(yAddress,i,j,width,height);  //i,j即点的X,Y坐标
  
            *(pTemp+3*i)=tempRGB[0].R;   //4个点的结果,存入内存中
            *(pTemp+3*i+1)=tempRGB[0].G;
            *(pTemp+3*i+2)=tempRGB[0].B;
             
            *(pTemp+3*i+3)=tempRGB[1].R;
            *(pTemp+3*i+4)=tempRGB[1].G;
            *(pTemp+3*i+5)=tempRGB[1].B;
             
            *(pTemp+3*width+3*i)=tempRGB[2].R;   //4个点的结果,存入内存中
            *(pTemp+3*width+3*i+1)=tempRGB[2].G;
            *(pTemp+3*width+3*i+2)=tempRGB[2].B;
  
            *(pTemp+3*width+3*i+3)=tempRGB[3].R;
            *(pTemp+3*width+3*i+4)=tempRGB[3].G;
            *(pTemp+3*width+3*i+5)=tempRGB[3].B;
         }
     }
      
  
     pTemp=outBuffer;
  
     for (i=height-1,j=0; i>=0; i--,j++)        
         {
           memcpy (g_pBits+j*width*3,pTemp+i*width*3,width*3);  //将图像进行水平镜像 否则图像是颠倒的
         }
     free (outBuffer);
     return g_pBits;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值