YUY2经常用于电视制式以及许多摄像头的输出格式.而我们在处理时经常需要将其转化为RGB进行处理,这里简单介绍下YUY2(YUV)与RGB之间相互转化的关系:
http://msdn2.microsoft.com/en-us/library/ms893078.aspx
YUY2(YUV) To RGB:
C = Y - 16
D = U - 128
E = V - 128
R = clip(( 298 * C + 409 * E + 128) >> 8)
G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
B = clip(( 298 * C + 516 * D + 128) >> 8)
其中 clip()为限制函数,将其取值限制在0-255之间.
RGB To YUY2(YUV):
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16
U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128
V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128
上述两个公式在代码中的
int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB);
int RGB2YUV(void* pRGB, void* pYUVX, int width, int height, bool alphaYUV, bool alphaRGB);
函数中转换。
在诸如摄像头的数据获取中,我们往往需要直接在YUY2(YUV)空间上进行一些图象处理,我们希望能够在YUY2
(YUV)进行一些RGB上可以做到的处理。这里已blending为例,将两张带有透明度的YUY2(YUV)图片进行叠加,
以达到在RGB空间进行图像合成的效果。
RGB空间进行图像叠加,通常背景(BG)是不透明的,而前景(FG)是带有透明度的。在RGB空间,可以简单表示为:
Rdest = Rfg*alpha + Rbg*(1-alpha);
Gdest = Gfg*alpha + Gbg*(1-alpha);
Bdest = Bfg*alpha + Bbg*(1-alpha);
// Rdest、Gdest、Bdest 为最终合成后的像素值
考虑到
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16
U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128
V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128
我们可以推导出
(Ydest-16)<<8 = ((Yfg-16)<<8)*alpha + ((Ybg-16)<<8)*(1-alpha);
(Udest-128)<<8 = ((Ufg-128)<<8)*alpha + ((Ubg-128)<<8)*(1-alpha);
(Vdest-128)<<8 = ((Vfg-128)<<8)*alpha + ((Vbg-128)<<8)*(1-alpha);
从而可以得到
Ydest = (Yfg-16)*alpha + (Ybg-16)*(1-alpha) + 16;
Udest = (Ufg-128)*alpha + (Ubg-128)*(1-alpha) + 128;
Vdest = (Vfg-128)*alpha + (Vbg-128)*(1-alpha) + 128;
这个叠加过程在函数
int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG)
中实现。
由于本文针对摄像头采集所得的数据进行处理,因此数据为YUY2格式,即4个字节来表示两个像素点的YUV信息,
排列为Y1 U1 Y2 V2, 对于像素点1为(Y1, U1, V1),像素点2为(Y2, U1, V1)。即两个像素点共用U、V信息。
这里假设带有alpha透明度的YUV格式用6个字节来表示两个像素点的YUV以及alpha信息,排列为 Y1 U1 Y2 V1 alpha1 alpha2
其中像素点1为(Y1, U1, V1, alpha1),像素点2为(Y2, U1, V1, alpha2)。其中alpha为对应点的透明度信息。
而带有alpha透明度RGB格式的图片,假设为32bits的BMP图片,每个像素点用4bytes来表示,分别为B G R alpha信息。
上述函数的具体实现为:
- //
- //YUV2RGB
- //pYUVpointtotheYUVdata
- //pRGBpointtotheRGBdata
- //widthwidthofthepicture
- //heightheightofthepicture
- //alphaYUVisthereanalphachannelinYUV
- //alphaRGBisthereanalphachannelinRGB
- //
- intYUV2RGB(void*pYUV,void*pRGB,intwidth,intheight,boolalphaYUV,boolalphaRGB)
- {
- if(NULL==pYUV)
- {
- return-1;
- }
- unsignedchar*pYUVData=(unsignedchar*)pYUV;
- unsignedchar*pRGBData=(unsignedchar*)pRGB;
- if(NULL==pRGBData)
- {
- if(alphaRGB)
- {
- pRGBData=newunsignedchar[width*height*4];
- }
- else
- pRGBData=newunsignedchar[width*height*3];
- }
- intY1,U1,V1,Y2,alpha1,alpha2,R1,G1,B1,R2,G2,B2;
- intC1,D1,E1,C2;
- if(alphaRGB)
- {
- if(alphaYUV)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*3+j*6);
- U1=*(pYUVData+i*width*3+j*6+1);
- Y2=*(pYUVData+i*width*3+j*6+2);
- V1=*(pYUVData+i*width*3+j*6+3);
- alpha1=*(pYUVData+i*width*3+j*6+4);
- alpha2=*(pYUVData+i*width*3+j*6+5);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*4+j*8+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*4+j*8+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*4+j*8)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*4+j*8+3)=alpha1;
- *(pRGBData+(height-i-1)*width*4+j*8+6)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*4+j*8+5)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*4+j*8+4)=B2<0?0:B2;
- *(pRGBData+(height-i-1)*width*4+j*8+7)=alpha2;
- }
- }
- }
- else
- {
- intalpha=255;
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*2+j*4);
- U1=*(pYUVData+i*width*2+j*4+1);
- Y2=*(pYUVData+i*width*2+j*4+2);
- V1=*(pYUVData+i*width*2+j*4+3);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*4+j*8+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*4+j*8+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*4+j*8)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*4+j*8+3)=alpha;
- *(pRGBData+(height-i-1)*width*4+j*8+6)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*4+j*8+5)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*4+j*8+4)=B2<0?0:B2;
- *(pRGBData+(height-i-1)*width*4+j*8+7)=alpha;
- }
- }
- }
- }
- else
- {
- if(alphaYUV)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*3+j*4);
- U1=*(pYUVData+i*width*3+j*4+1);
- Y2=*(pYUVData+i*width*3+j*4+2);
- V1=*(pYUVData+i*width*3+j*4+3);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*3+j*6+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*3+j*6+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*3+j*6)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*3+j*6+5)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*3+j*6+4)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*3+j*6+3)=B2<0?0:B2;
- }
- }
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*2+j*4);
- U1=*(pYUVData+i*width*2+j*4+1);
- Y2=*(pYUVData+i*width*2+j*4+2);
- V1=*(pYUVData+i*width*2+j*4+3);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*3+j*6+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*3+j*6+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*3+j*6)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*3+j*6+5)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*3+j*6+4)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*3+j*6+3)=B2<0?0:B2;
- }
- }
- }
- }
- return0;
- }
- //
- //RGB2YUV
- //pRGBpointtotheRGBdata
- //pYUVpointtotheYUVdata
- //widthwidthofthepicture
- //heightheightofthepicture
- //alphaYUVisthereanalphachannelinYUV
- //alphaRGBisthereanalphachannelinRGB
- //
- intRGB2YUV(void*pRGB,void*pYUV,intwidth,intheight,boolalphaYUV,boolalphaRGB)
- {
- if(NULL==pRGB)
- {
- return-1;
- }
- unsignedchar*pRGBData=(unsignedchar*)pRGB;
- unsignedchar*pYUVData=(unsignedchar*)pYUV;
- if(NULL==pYUVData)
- {
- if(alphaYUV)
- {
- pYUVData=newunsignedchar[width*height*3];
- }
- else
- pYUVData=newunsignedchar[width*height*2];
- }
- intR1,G1,B1,R2,G2,B2,Y1,U1,Y2,V1;
- intalpha1,alpha2;
- if(alphaYUV)
- {
- if(alphaRGB)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*4+j*8);
- G1=*(pRGBData+(height-i-1)*width*4+j*8+1);
- R1=*(pRGBData+(height-i-1)*width*4+j*8+2);
- alpha1=*(pRGBData+(height-i-1)*width*4+j*8+3);
- B2=*(pRGBData+(height-i-1)*width*4+j*8+4);
- G2=*(pRGBData+(height-i-1)*width*4+j*8+5);
- R2=*(pRGBData+(height-i-1)*width*4+j*8+6);
- alpha2=*(pRGBData+(height-i-1)*width*4+j*8+7);
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*3+j*6)=Y1;
- *(pYUVData+i*width*3+j*6+1)=U1;
- *(pYUVData+i*width*3+j*6+2)=Y2;
- *(pYUVData+i*width*3+j*6+3)=V1;
- *(pYUVData+i*width*3+j*6+4)=alpha1;
- *(pYUVData+i*width*3+j*6+5)=alpha2;
- }
- }
- }
- else
- {
- unsignedcharalpha=255;
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*3+j*6);
- G1=*(pRGBData+(height-i-1)*width*3+j*6+1);
- R1=*(pRGBData+(height-i-1)*width*3+j*6+2);
- B2=*(pRGBData+(height-i-1)*width*3+j*6+3);
- G2=*(pRGBData+(height-i-1)*width*3+j*6+4);
- R2=*(pRGBData+(height-i-1)*width*3+j*6+5);
- Y1=((66*R1+129*G1+25*B1+128)>>8)+16;
- U1=((-38*R1-74*G1+112*B1+128)>>8+(-38*R2-74*G2+112*B2+128)>>8)/2+128;
- Y2=((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((112*R1-94*G1-18*B1+128)>>8+(112*R2-94*G2-18*B2+128)>>8)/2+128;
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*3+j*6)=Y1;
- *(pYUVData+i*width*3+j*6+1)=U1;
- *(pYUVData+i*width*3+j*6+2)=Y2;
- *(pYUVData+i*width*3+j*6+3)=V1;
- *(pYUVData+i*width*3+j*6+4)=alpha;
- *(pYUVData+i*width*3+j*6+5)=alpha;
- }
- }
- }
- }
- else
- {
- if(alphaRGB)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*4+j*8);
- G1=*(pRGBData+(height-i-1)*width*4+j*8+1);
- R1=*(pRGBData+(height-i-1)*width*4+j*8+2);
- B2=*(pRGBData+(height-i-1)*width*4+j*8+4);
- G2=*(pRGBData+(height-i-1)*width*4+j*8+5);
- R2=*(pRGBData+(height-i-1)*width*4+j*8+6);
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*2+j*4)=Y1;
- *(pYUVData+i*width*2+j*4+1)=U1;
- *(pYUVData+i*width*2+j*4+2)=Y2;
- *(pYUVData+i*width*2+j*4+3)=V1;
- }
- }
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*3+j*6);
- G1=*(pRGBData+(height-i-1)*width*3+j*6+1);
- R1=*(pRGBData+(height-i-1)*width*3+j*6+2);
- B2=*(pRGBData+(height-i-1)*width*3+j*6+3);
- G2=*(pRGBData+(height-i-1)*width*3+j*6+4);
- R2=*(pRGBData+(height-i-1)*width*3+j*6+5);
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*2+j*4)=Y1;
- *(pYUVData+i*width*2+j*4+1)=U1;
- *(pYUVData+i*width*2+j*4+2)=Y2;
- *(pYUVData+i*width*2+j*4+3)=V1;
- }
- }
- }
- }
- return0;
- }
- //
- //pGBYUVpointtothebackgroundYUVdata
- //pFGYUVpointtotheforegroundYUVdata
- //widthwidthofthepicture
- //heightheightofthepicture
- //alphaBGisthereanalphachannelinbackgroundYUVdata
- //alphaFGisthereanalphachannelinfourgroundYUVdata
- //
- intYUVBlending(void*pBGYUV,void*pFGYUV,intwidth,intheight,boolalphaBG,boolalphaFG)
- {
- if(NULL==pBGYUV||NULL==pFGYUV)
- {
- return-1;
- }
- unsignedchar*pBGData=(unsignedchar*)pBGYUV;
- unsignedchar*pFGData=(unsignedchar*)pFGYUV;
- if(!alphaFG)
- {
- if(!alphaBG)
- {
- memcpy(pBGData,pFGData,width*height*2);
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- *(pBGData+i*width*2+j*4)=*(pFGData+i*width*2+j*4);
- *(pBGData+i*width*2+j*4+1)=*(pFGData+i*width*2+j*4+1);
- *(pBGData+i*width*2+j*4+2)=*(pFGData+i*width*2+j*4+2);
- *(pBGData+i*width*2+j*4+3)=*(pFGData+i*width*2+j*4+3);
- }
- }
- }
- }
- intY11,U11,V11,Y12,Y21,U21,V21,Y22;
- intalpha1,alpha2;
- if(!alphaBG)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y11=*(pBGData+i*width*2+j*4);
- U11=*(pBGData+i*width*2+j*4+1);
- Y12=*(pBGData+i*width*2+j*4+2);
- V11=*(pBGData+i*width*2+j*4+3);
- Y21=*(pFGData+i*width*3+j*6);
- U21=*(pFGData+i*width*3+j*6+1);
- Y22=*(pFGData+i*width*3+j*6+2);
- V21=*(pFGData+i*width*3+j*6+3);
- alpha1=*(pFGData+i*width*3+j*6+4);
- alpha2=*(pFGData+i*width*3+j*6+5);
- *(pBGData+i*width*2+j*4)=(Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
- *(pBGData+i*width*2+j*4+1)=((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255+(U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*2+j*4+3)=((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255+(V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*2+j*4+2)=(Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
- }
- }
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y11=*(pBGData+i*width*3+j*6);
- U11=*(pBGData+i*width*3+j*6+1);
- Y12=*(pBGData+i*width*3+j*6+2);
- V11=*(pBGData+i*width*3+j*6+3);
- Y21=*(pFGData+i*width*3+j*6);
- U21=*(pFGData+i*width*3+j*6+1);
- Y22=*(pFGData+i*width*3+j*6+2);
- V21=*(pFGData+i*width*3+j*6+3);
- alpha1=*(pFGData+i*width*3+j*6+4);
- alpha2=*(pFGData+i*width*3+j*6+5);
- *(pBGData+i*width*3+j*6)=(Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
- *(pBGData+i*width*3+j*6+1)=((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255+(U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*3+j*6+3)=((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255+(V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*3+j*6+2)=(Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
- }
- }
- }
- return0;
- }
- //
- //YUV2RGB
- //pYUVpointtotheYUVdata
- //pRGBpointtotheRGBdata
- //widthwidthofthepicture
- //heightheightofthepicture
- //alphaYUVisthereanalphachannelinYUV
- //alphaRGBisthereanalphachannelinRGB
- //
- intYUV2RGB(void*pYUV,void*pRGB,intwidth,intheight,boolalphaYUV,boolalphaRGB)
- {
- if(NULL==pYUV)
- {
- return-1;
- }
- unsignedchar*pYUVData=(unsignedchar*)pYUV;
- unsignedchar*pRGBData=(unsignedchar*)pRGB;
- if(NULL==pRGBData)
- {
- if(alphaRGB)
- {
- pRGBData=newunsignedchar[width*height*4];
- }
- else
- pRGBData=newunsignedchar[width*height*3];
- }
- intY1,U1,V1,Y2,alpha1,alpha2,R1,G1,B1,R2,G2,B2;
- intC1,D1,E1,C2;
- if(alphaRGB)
- {
- if(alphaYUV)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*3+j*6);
- U1=*(pYUVData+i*width*3+j*6+1);
- Y2=*(pYUVData+i*width*3+j*6+2);
- V1=*(pYUVData+i*width*3+j*6+3);
- alpha1=*(pYUVData+i*width*3+j*6+4);
- alpha2=*(pYUVData+i*width*3+j*6+5);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*4+j*8+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*4+j*8+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*4+j*8)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*4+j*8+3)=alpha1;
- *(pRGBData+(height-i-1)*width*4+j*8+6)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*4+j*8+5)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*4+j*8+4)=B2<0?0:B2;
- *(pRGBData+(height-i-1)*width*4+j*8+7)=alpha2;
- }
- }
- }
- else
- {
- intalpha=255;
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*2+j*4);
- U1=*(pYUVData+i*width*2+j*4+1);
- Y2=*(pYUVData+i*width*2+j*4+2);
- V1=*(pYUVData+i*width*2+j*4+3);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*4+j*8+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*4+j*8+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*4+j*8)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*4+j*8+3)=alpha;
- *(pRGBData+(height-i-1)*width*4+j*8+6)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*4+j*8+5)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*4+j*8+4)=B2<0?0:B2;
- *(pRGBData+(height-i-1)*width*4+j*8+7)=alpha;
- }
- }
- }
- }
- else
- {
- if(alphaYUV)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*3+j*4);
- U1=*(pYUVData+i*width*3+j*4+1);
- Y2=*(pYUVData+i*width*3+j*4+2);
- V1=*(pYUVData+i*width*3+j*4+3);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*3+j*6+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*3+j*6+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*3+j*6)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*3+j*6+5)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*3+j*6+4)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*3+j*6+3)=B2<0?0:B2;
- }
- }
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y1=*(pYUVData+i*width*2+j*4);
- U1=*(pYUVData+i*width*2+j*4+1);
- Y2=*(pYUVData+i*width*2+j*4+2);
- V1=*(pYUVData+i*width*2+j*4+3);
- C1=Y1-16;
- C2=Y2-16;
- D1=U1-128;
- E1=V1-128;
- R1=((298*C1+409*E1+128)>>8>255?255:(298*C1+409*E1+128)>>8);
- G1=((298*C1-100*D1-208*E1+128)>>8>255?255:(298*C1-100*D1-208*E1+128)>>8);
- B1=((298*C1+516*D1+128)>>8>255?255:(298*C1+516*D1+128)>>8);
- R2=((298*C2+409*E1+128)>>8>255?255:(298*C2+409*E1+128)>>8);
- G2=((298*C2-100*D1-208*E1+128)>>8>255?255:(298*C2-100*D1-208*E1+128)>>8);
- B2=((298*C2+516*D1+128)>>8>255?255:(298*C2+516*D1+128)>>8);
- *(pRGBData+(height-i-1)*width*3+j*6+2)=R1<0?0:R1;
- *(pRGBData+(height-i-1)*width*3+j*6+1)=G1<0?0:G1;
- *(pRGBData+(height-i-1)*width*3+j*6)=B1<0?0:B1;
- *(pRGBData+(height-i-1)*width*3+j*6+5)=R2<0?0:R2;
- *(pRGBData+(height-i-1)*width*3+j*6+4)=G2<0?0:G2;
- *(pRGBData+(height-i-1)*width*3+j*6+3)=B2<0?0:B2;
- }
- }
- }
- }
- return0;
- }
- //
- //RGB2YUV
- //pRGBpointtotheRGBdata
- //pYUVpointtotheYUVdata
- //widthwidthofthepicture
- //heightheightofthepicture
- //alphaYUVisthereanalphachannelinYUV
- //alphaRGBisthereanalphachannelinRGB
- //
- intRGB2YUV(void*pRGB,void*pYUV,intwidth,intheight,boolalphaYUV,boolalphaRGB)
- {
- if(NULL==pRGB)
- {
- return-1;
- }
- unsignedchar*pRGBData=(unsignedchar*)pRGB;
- unsignedchar*pYUVData=(unsignedchar*)pYUV;
- if(NULL==pYUVData)
- {
- if(alphaYUV)
- {
- pYUVData=newunsignedchar[width*height*3];
- }
- else
- pYUVData=newunsignedchar[width*height*2];
- }
- intR1,G1,B1,R2,G2,B2,Y1,U1,Y2,V1;
- intalpha1,alpha2;
- if(alphaYUV)
- {
- if(alphaRGB)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*4+j*8);
- G1=*(pRGBData+(height-i-1)*width*4+j*8+1);
- R1=*(pRGBData+(height-i-1)*width*4+j*8+2);
- alpha1=*(pRGBData+(height-i-1)*width*4+j*8+3);
- B2=*(pRGBData+(height-i-1)*width*4+j*8+4);
- G2=*(pRGBData+(height-i-1)*width*4+j*8+5);
- R2=*(pRGBData+(height-i-1)*width*4+j*8+6);
- alpha2=*(pRGBData+(height-i-1)*width*4+j*8+7);
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*3+j*6)=Y1;
- *(pYUVData+i*width*3+j*6+1)=U1;
- *(pYUVData+i*width*3+j*6+2)=Y2;
- *(pYUVData+i*width*3+j*6+3)=V1;
- *(pYUVData+i*width*3+j*6+4)=alpha1;
- *(pYUVData+i*width*3+j*6+5)=alpha2;
- }
- }
- }
- else
- {
- unsignedcharalpha=255;
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*3+j*6);
- G1=*(pRGBData+(height-i-1)*width*3+j*6+1);
- R1=*(pRGBData+(height-i-1)*width*3+j*6+2);
- B2=*(pRGBData+(height-i-1)*width*3+j*6+3);
- G2=*(pRGBData+(height-i-1)*width*3+j*6+4);
- R2=*(pRGBData+(height-i-1)*width*3+j*6+5);
- Y1=((66*R1+129*G1+25*B1+128)>>8)+16;
- U1=((-38*R1-74*G1+112*B1+128)>>8+(-38*R2-74*G2+112*B2+128)>>8)/2+128;
- Y2=((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((112*R1-94*G1-18*B1+128)>>8+(112*R2-94*G2-18*B2+128)>>8)/2+128;
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*3+j*6)=Y1;
- *(pYUVData+i*width*3+j*6+1)=U1;
- *(pYUVData+i*width*3+j*6+2)=Y2;
- *(pYUVData+i*width*3+j*6+3)=V1;
- *(pYUVData+i*width*3+j*6+4)=alpha;
- *(pYUVData+i*width*3+j*6+5)=alpha;
- }
- }
- }
- }
- else
- {
- if(alphaRGB)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*4+j*8);
- G1=*(pRGBData+(height-i-1)*width*4+j*8+1);
- R1=*(pRGBData+(height-i-1)*width*4+j*8+2);
- B2=*(pRGBData+(height-i-1)*width*4+j*8+4);
- G2=*(pRGBData+(height-i-1)*width*4+j*8+5);
- R2=*(pRGBData+(height-i-1)*width*4+j*8+6);
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*2+j*4)=Y1;
- *(pYUVData+i*width*2+j*4+1)=U1;
- *(pYUVData+i*width*2+j*4+2)=Y2;
- *(pYUVData+i*width*2+j*4+3)=V1;
- }
- }
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- B1=*(pRGBData+(height-i-1)*width*3+j*6);
- G1=*(pRGBData+(height-i-1)*width*3+j*6+1);
- R1=*(pRGBData+(height-i-1)*width*3+j*6+2);
- B2=*(pRGBData+(height-i-1)*width*3+j*6+3);
- G2=*(pRGBData+(height-i-1)*width*3+j*6+4);
- R2=*(pRGBData+(height-i-1)*width*3+j*6+5);
- Y1=(((66*R1+129*G1+25*B1+128)>>8)+16)>255?255:(((66*R1+129*G1+25*B1+128)>>8)+16);
- U1=((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128)>255?255:((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2+128);
- Y2=(((66*R2+129*G2+25*B2+128)>>8)+16)>255?255:((66*R2+129*G2+25*B2+128)>>8)+16;
- V1=((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128)>255?255:((((112*R1-94*G1-18*B1+128)>>8)+((112*R2-94*G2-18*B2+128)>>8))/2+128);
- *(pYUVData+i*width*2+j*4)=Y1;
- *(pYUVData+i*width*2+j*4+1)=U1;
- *(pYUVData+i*width*2+j*4+2)=Y2;
- *(pYUVData+i*width*2+j*4+3)=V1;
- }
- }
- }
- }
- return0;
- }
- //
- //pGBYUVpointtothebackgroundYUVdata
- //pFGYUVpointtotheforegroundYUVdata
- //widthwidthofthepicture
- //heightheightofthepicture
- //alphaBGisthereanalphachannelinbackgroundYUVdata
- //alphaFGisthereanalphachannelinfourgroundYUVdata
- //
- intYUVBlending(void*pBGYUV,void*pFGYUV,intwidth,intheight,boolalphaBG,boolalphaFG)
- {
- if(NULL==pBGYUV||NULL==pFGYUV)
- {
- return-1;
- }
- unsignedchar*pBGData=(unsignedchar*)pBGYUV;
- unsignedchar*pFGData=(unsignedchar*)pFGYUV;
- if(!alphaFG)
- {
- if(!alphaBG)
- {
- memcpy(pBGData,pFGData,width*height*2);
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- *(pBGData+i*width*2+j*4)=*(pFGData+i*width*2+j*4);
- *(pBGData+i*width*2+j*4+1)=*(pFGData+i*width*2+j*4+1);
- *(pBGData+i*width*2+j*4+2)=*(pFGData+i*width*2+j*4+2);
- *(pBGData+i*width*2+j*4+3)=*(pFGData+i*width*2+j*4+3);
- }
- }
- }
- }
- intY11,U11,V11,Y12,Y21,U21,V21,Y22;
- intalpha1,alpha2;
- if(!alphaBG)
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y11=*(pBGData+i*width*2+j*4);
- U11=*(pBGData+i*width*2+j*4+1);
- Y12=*(pBGData+i*width*2+j*4+2);
- V11=*(pBGData+i*width*2+j*4+3);
- Y21=*(pFGData+i*width*3+j*6);
- U21=*(pFGData+i*width*3+j*6+1);
- Y22=*(pFGData+i*width*3+j*6+2);
- V21=*(pFGData+i*width*3+j*6+3);
- alpha1=*(pFGData+i*width*3+j*6+4);
- alpha2=*(pFGData+i*width*3+j*6+5);
- *(pBGData+i*width*2+j*4)=(Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
- *(pBGData+i*width*2+j*4+1)=((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255+(U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*2+j*4+3)=((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255+(V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*2+j*4+2)=(Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
- }
- }
- }
- else
- {
- for(inti=0;i<height;++i)
- {
- for(intj=0;j<width/2;++j)
- {
- Y11=*(pBGData+i*width*3+j*6);
- U11=*(pBGData+i*width*3+j*6+1);
- Y12=*(pBGData+i*width*3+j*6+2);
- V11=*(pBGData+i*width*3+j*6+3);
- Y21=*(pFGData+i*width*3+j*6);
- U21=*(pFGData+i*width*3+j*6+1);
- Y22=*(pFGData+i*width*3+j*6+2);
- V21=*(pFGData+i*width*3+j*6+3);
- alpha1=*(pFGData+i*width*3+j*6+4);
- alpha2=*(pFGData+i*width*3+j*6+5);
- *(pBGData+i*width*3+j*6)=(Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
- *(pBGData+i*width*3+j*6+1)=((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255+(U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*3+j*6+3)=((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255+(V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
- *(pBGData+i*width*3+j*6+2)=(Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
- }
- }
- }
- return0;
- }