网站建设培训学校,泰兴网页定制,wordpress系统选择,东阳做网站的公司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((…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信息。上述函数的具体实现为
view plaincopy to clipboardprint?// // YUV2RGB // pYUV point to the YUV data // pRGB point to the RGB data // width width of the picture // height height of the picture // alphaYUV is there an alpha channel in YUV // alphaRGB is there an alpha channel in RGB // int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB) { if (NULL pYUV) { return -1; } unsigned char* pYUVData (unsigned char *)pYUV; unsigned char* pRGBData (unsigned char *)pRGB; if (NULL pRGBData) { if (alphaRGB) { pRGBData new unsigned char[width*height*4]; } else pRGBData new unsigned char[width*height*3]; } int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2; int C1, D1, E1, C2; if (alphaRGB) { if (alphaYUV) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*3j*6); U1 *(pYUVDatai*width*3j*61); Y2 *(pYUVDatai*width*3j*62); V1 *(pYUVDatai*width*3j*63); alpha1 *(pYUVDatai*width*3j*64); alpha2 *(pYUVDatai*width*3j*65); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*4j*82) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*4j*81) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*4j*8) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*4j*83) alpha1; *(pRGBData(height-i-1)*width*4j*86) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*4j*85) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*4j*84) B20 ? 0 : B2; *(pRGBData(height-i-1)*width*4j*87) alpha2; } } } else { int alpha 255; for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*2j*4); U1 *(pYUVDatai*width*2j*41); Y2 *(pYUVDatai*width*2j*42); V1 *(pYUVDatai*width*2j*43); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*4j*82) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*4j*81) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*4j*8) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*4j*83) alpha; *(pRGBData(height-i-1)*width*4j*86) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*4j*85) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*4j*84) B20 ? 0 : B2; *(pRGBData(height-i-1)*width*4j*87) alpha; } } } } else { if (alphaYUV) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*3j*4); U1 *(pYUVDatai*width*3j*41); Y2 *(pYUVDatai*width*3j*42); V1 *(pYUVDatai*width*3j*43); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*3j*62) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*3j*61) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*3j*6) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*3j*65) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*3j*64) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*3j*63) B20 ? 0 : B2; } } } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*2j*4); U1 *(pYUVDatai*width*2j*41); Y2 *(pYUVDatai*width*2j*42); V1 *(pYUVDatai*width*2j*43); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*3j*62) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*3j*61) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*3j*6) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*3j*65) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*3j*64) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*3j*63) B20 ? 0 : B2; } } } } return 0; } // // RGB2YUV // pRGB point to the RGB data // pYUV point to the YUV data // width width of the picture // height height of the picture // alphaYUV is there an alpha channel in YUV // alphaRGB is there an alpha channel in RGB // int RGB2YUV(void* pRGB, void* pYUV, int width, int height, bool alphaYUV, bool alphaRGB) { if (NULL pRGB) { return -1; } unsigned char* pRGBData (unsigned char *)pRGB; unsigned char* pYUVData (unsigned char *)pYUV; if (NULL pYUVData) { if (alphaYUV) { pYUVData new unsigned char[width*height*3]; } else pYUVData new unsigned char[width*height*2]; } int R1, G1, B1, R2, G2, B2, Y1, U1, Y2, V1; int alpha1, alpha2; if (alphaYUV) { if (alphaRGB) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*4j*8); G1 *(pRGBData(height-i-1)*width*4j*81); R1 *(pRGBData(height-i-1)*width*4j*82); alpha1 *(pRGBData(height-i-1)*width*4j*83); B2 *(pRGBData(height-i-1)*width*4j*84); G2 *(pRGBData(height-i-1)*width*4j*85); R2 *(pRGBData(height-i-1)*width*4j*86); alpha2 *(pRGBData(height-i-1)*width*4j*87); Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*3j*6) Y1; *(pYUVDatai*width*3j*61) U1; *(pYUVDatai*width*3j*62) Y2; *(pYUVDatai*width*3j*63) V1; *(pYUVDatai*width*3j*64) alpha1; *(pYUVDatai*width*3j*65) alpha2; } } } else { unsigned char alpha 255; for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*3j*6); G1 *(pRGBData(height-i-1)*width*3j*61); R1 *(pRGBData(height-i-1)*width*3j*62); B2 *(pRGBData(height-i-1)*width*3j*63); G2 *(pRGBData(height-i-1)*width*3j*64); R2 *(pRGBData(height-i-1)*width*3j*65); Y1 ((66*R1129*G125*B1128)8) 16; U1 ((-38*R1-74*G1112*B1128)8(-38*R2-74*G2112*B2128)8)/2 128; Y2 ((66*R2129*G225*B2128)8) 16; V1 ((112*R1-94*G1-18*B1128)8 (112*R2-94*G2-18*B2128)8)/2 128; Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*3j*6) Y1; *(pYUVDatai*width*3j*61) U1; *(pYUVDatai*width*3j*62) Y2; *(pYUVDatai*width*3j*63) V1; *(pYUVDatai*width*3j*64) alpha; *(pYUVDatai*width*3j*65) alpha; } } } } else { if (alphaRGB) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*4j*8); G1 *(pRGBData(height-i-1)*width*4j*81); R1 *(pRGBData(height-i-1)*width*4j*82); B2 *(pRGBData(height-i-1)*width*4j*84); G2 *(pRGBData(height-i-1)*width*4j*85); R2 *(pRGBData(height-i-1)*width*4j*86); Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*2j*4) Y1; *(pYUVDatai*width*2j*41) U1; *(pYUVDatai*width*2j*42) Y2; *(pYUVDatai*width*2j*43) V1; } } } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*3j*6); G1 *(pRGBData(height-i-1)*width*3j*61); R1 *(pRGBData(height-i-1)*width*3j*62); B2 *(pRGBData(height-i-1)*width*3j*63); G2 *(pRGBData(height-i-1)*width*3j*64); R2 *(pRGBData(height-i-1)*width*3j*65); Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*2j*4) Y1; *(pYUVDatai*width*2j*41) U1; *(pYUVDatai*width*2j*42) Y2; *(pYUVDatai*width*2j*43) V1; } } } } return 0; } // // pGBYUV point to the background YUV data // pFGYUV point to the foreground YUV data // width width of the picture // height height of the picture // alphaBG is there an alpha channel in background YUV data // alphaFG is there an alpha channel in fourground YUV data // int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG) { if (NULL pBGYUV || NULL pFGYUV) { return -1; } unsigned char* pBGData (unsigned char*)pBGYUV; unsigned char* pFGData (unsigned char*)pFGYUV; if (!alphaFG) { if (!alphaBG) { memcpy(pBGData, pFGData, width*height*2); } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { *(pBGDatai*width*2j*4) *(pFGDatai*width*2j*4); *(pBGDatai*width*2j*41) *(pFGDatai*width*2j*41); *(pBGDatai*width*2j*42) *(pFGDatai*width*2j*42); *(pBGDatai*width*2j*43) *(pFGDatai*width*2j*43); } } } } int Y11, U11, V11, Y12, Y21, U21, V21, Y22; int alpha1, alpha2; if (!alphaBG) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y11 *(pBGDatai*width*2j*4); U11 *(pBGDatai*width*2j*41); Y12 *(pBGDatai*width*2j*42); V11 *(pBGDatai*width*2j*43); Y21 *(pFGDatai*width*3j*6); U21 *(pFGDatai*width*3j*61); Y22 *(pFGDatai*width*3j*62); V21 *(pFGDatai*width*3j*63); alpha1 *(pFGDatai*width*3j*64); alpha2 *(pFGDatai*width*3j*65); *(pBGDatai*width*2j*4) (Y21-16)*alpha1/255(Y11-16)*(255-alpha1)/25516; *(pBGDatai*width*2j*41) ((U21-128)*alpha1/255(U11-128)*(255-alpha1)/255 (U21-128)*alpha2/255(U11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*2j*43) ((V21-128)*alpha1/255(V11-128)*(255-alpha1)/255 (V21-128)*alpha2/255(V11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*2j*42) (Y22-16)*alpha2/255(Y12-16)*(255-alpha2)/25516; } } } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y11 *(pBGDatai*width*3j*6); U11 *(pBGDatai*width*3j*61); Y12 *(pBGDatai*width*3j*62); V11 *(pBGDatai*width*3j*63); Y21 *(pFGDatai*width*3j*6); U21 *(pFGDatai*width*3j*61); Y22 *(pFGDatai*width*3j*62); V21 *(pFGDatai*width*3j*63); alpha1 *(pFGDatai*width*3j*64); alpha2 *(pFGDatai*width*3j*65); *(pBGDatai*width*3j*6) (Y21-16)*alpha1/255(Y11-16)*(255-alpha1)/25516; *(pBGDatai*width*3j*61) ((U21-128)*alpha1/255(U11-128)*(255-alpha1)/255 (U21-128)*alpha2/255(U11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*3j*63) ((V21-128)*alpha1/255(V11-128)*(255-alpha1)/255 (V21-128)*alpha2/255(V11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*3j*62) (Y22-16)*alpha2/255(Y12-16)*(255-alpha2)/25516; } } } return 0; } [c-sharp] view plaincopyprint?// // YUV2RGB // pYUV point to the YUV data // pRGB point to the RGB data // width width of the picture // height height of the picture // alphaYUV is there an alpha channel in YUV // alphaRGB is there an alpha channel in RGB // int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB) { if (NULL pYUV) { return -1; } unsigned char* pYUVData (unsigned char *)pYUV; unsigned char* pRGBData (unsigned char *)pRGB; if (NULL pRGBData) { if (alphaRGB) { pRGBData new unsigned char[width*height*4]; } else pRGBData new unsigned char[width*height*3]; } int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2; int C1, D1, E1, C2; if (alphaRGB) { if (alphaYUV) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*3j*6); U1 *(pYUVDatai*width*3j*61); Y2 *(pYUVDatai*width*3j*62); V1 *(pYUVDatai*width*3j*63); alpha1 *(pYUVDatai*width*3j*64); alpha2 *(pYUVDatai*width*3j*65); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*4j*82) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*4j*81) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*4j*8) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*4j*83) alpha1; *(pRGBData(height-i-1)*width*4j*86) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*4j*85) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*4j*84) B20 ? 0 : B2; *(pRGBData(height-i-1)*width*4j*87) alpha2; } } } else { int alpha 255; for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*2j*4); U1 *(pYUVDatai*width*2j*41); Y2 *(pYUVDatai*width*2j*42); V1 *(pYUVDatai*width*2j*43); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*4j*82) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*4j*81) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*4j*8) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*4j*83) alpha; *(pRGBData(height-i-1)*width*4j*86) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*4j*85) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*4j*84) B20 ? 0 : B2; *(pRGBData(height-i-1)*width*4j*87) alpha; } } } } else { if (alphaYUV) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*3j*4); U1 *(pYUVDatai*width*3j*41); Y2 *(pYUVDatai*width*3j*42); V1 *(pYUVDatai*width*3j*43); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*3j*62) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*3j*61) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*3j*6) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*3j*65) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*3j*64) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*3j*63) B20 ? 0 : B2; } } } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y1 *(pYUVDatai*width*2j*4); U1 *(pYUVDatai*width*2j*41); Y2 *(pYUVDatai*width*2j*42); V1 *(pYUVDatai*width*2j*43); C1 Y1-16; C2 Y2-16; D1 U1-128; E1 V1-128; R1 ((298*C1 409*E1 128)8255 ? 255 : (298*C1 409*E1 128)8); G1 ((298*C1 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C1 - 100*D1 - 208*E1 128)8); B1 ((298*C1516*D1 128)8255 ? 255 : (298*C1516*D1 128)8); R2 ((298*C2 409*E1 128)8255 ? 255 : (298*C2 409*E1 128)8); G2 ((298*C2 - 100*D1 - 208*E1 128)8255 ? 255 : (298*C2 - 100*D1 - 208*E1 128)8); B2 ((298*C2 516*D1 128)8255 ? 255 : (298*C2 516*D1 128)8); *(pRGBData(height-i-1)*width*3j*62) R10 ? 0 : R1; *(pRGBData(height-i-1)*width*3j*61) G10 ? 0 : G1; *(pRGBData(height-i-1)*width*3j*6) B10 ? 0 : B1; *(pRGBData(height-i-1)*width*3j*65) R20 ? 0 : R2; *(pRGBData(height-i-1)*width*3j*64) G20 ? 0 : G2; *(pRGBData(height-i-1)*width*3j*63) B20 ? 0 : B2; } } } } return 0; } // // RGB2YUV // pRGB point to the RGB data // pYUV point to the YUV data // width width of the picture // height height of the picture // alphaYUV is there an alpha channel in YUV // alphaRGB is there an alpha channel in RGB // int RGB2YUV(void* pRGB, void* pYUV, int width, int height, bool alphaYUV, bool alphaRGB) { if (NULL pRGB) { return -1; } unsigned char* pRGBData (unsigned char *)pRGB; unsigned char* pYUVData (unsigned char *)pYUV; if (NULL pYUVData) { if (alphaYUV) { pYUVData new unsigned char[width*height*3]; } else pYUVData new unsigned char[width*height*2]; } int R1, G1, B1, R2, G2, B2, Y1, U1, Y2, V1; int alpha1, alpha2; if (alphaYUV) { if (alphaRGB) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*4j*8); G1 *(pRGBData(height-i-1)*width*4j*81); R1 *(pRGBData(height-i-1)*width*4j*82); alpha1 *(pRGBData(height-i-1)*width*4j*83); B2 *(pRGBData(height-i-1)*width*4j*84); G2 *(pRGBData(height-i-1)*width*4j*85); R2 *(pRGBData(height-i-1)*width*4j*86); alpha2 *(pRGBData(height-i-1)*width*4j*87); Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*3j*6) Y1; *(pYUVDatai*width*3j*61) U1; *(pYUVDatai*width*3j*62) Y2; *(pYUVDatai*width*3j*63) V1; *(pYUVDatai*width*3j*64) alpha1; *(pYUVDatai*width*3j*65) alpha2; } } } else { unsigned char alpha 255; for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*3j*6); G1 *(pRGBData(height-i-1)*width*3j*61); R1 *(pRGBData(height-i-1)*width*3j*62); B2 *(pRGBData(height-i-1)*width*3j*63); G2 *(pRGBData(height-i-1)*width*3j*64); R2 *(pRGBData(height-i-1)*width*3j*65); Y1 ((66*R1129*G125*B1128)8) 16; U1 ((-38*R1-74*G1112*B1128)8(-38*R2-74*G2112*B2128)8)/2 128; Y2 ((66*R2129*G225*B2128)8) 16; V1 ((112*R1-94*G1-18*B1128)8 (112*R2-94*G2-18*B2128)8)/2 128; Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*3j*6) Y1; *(pYUVDatai*width*3j*61) U1; *(pYUVDatai*width*3j*62) Y2; *(pYUVDatai*width*3j*63) V1; *(pYUVDatai*width*3j*64) alpha; *(pYUVDatai*width*3j*65) alpha; } } } } else { if (alphaRGB) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*4j*8); G1 *(pRGBData(height-i-1)*width*4j*81); R1 *(pRGBData(height-i-1)*width*4j*82); B2 *(pRGBData(height-i-1)*width*4j*84); G2 *(pRGBData(height-i-1)*width*4j*85); R2 *(pRGBData(height-i-1)*width*4j*86); Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*2j*4) Y1; *(pYUVDatai*width*2j*41) U1; *(pYUVDatai*width*2j*42) Y2; *(pYUVDatai*width*2j*43) V1; } } } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { B1 *(pRGBData(height-i-1)*width*3j*6); G1 *(pRGBData(height-i-1)*width*3j*61); R1 *(pRGBData(height-i-1)*width*3j*62); B2 *(pRGBData(height-i-1)*width*3j*63); G2 *(pRGBData(height-i-1)*width*3j*64); R2 *(pRGBData(height-i-1)*width*3j*65); Y1 (((66*R1129*G125*B1128)8) 16) 255 ? 255 : (((66*R1129*G125*B1128)8) 16); U1 ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128)255 ? 255 : ((((-38*R1-74*G1112*B1128)8)((-38*R2-74*G2112*B2128)8))/2 128); Y2 (((66*R2129*G225*B2128)8) 16)255 ? 255 : ((66*R2129*G225*B2128)8) 16; V1 ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128)255 ? 255 : ((((112*R1-94*G1-18*B1128)8) ((112*R2-94*G2-18*B2128)8))/2 128); *(pYUVDatai*width*2j*4) Y1; *(pYUVDatai*width*2j*41) U1; *(pYUVDatai*width*2j*42) Y2; *(pYUVDatai*width*2j*43) V1; } } } } return 0; } // // pGBYUV point to the background YUV data // pFGYUV point to the foreground YUV data // width width of the picture // height height of the picture // alphaBG is there an alpha channel in background YUV data // alphaFG is there an alpha channel in fourground YUV data // int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG) { if (NULL pBGYUV || NULL pFGYUV) { return -1; } unsigned char* pBGData (unsigned char*)pBGYUV; unsigned char* pFGData (unsigned char*)pFGYUV; if (!alphaFG) { if (!alphaBG) { memcpy(pBGData, pFGData, width*height*2); } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { *(pBGDatai*width*2j*4) *(pFGDatai*width*2j*4); *(pBGDatai*width*2j*41) *(pFGDatai*width*2j*41); *(pBGDatai*width*2j*42) *(pFGDatai*width*2j*42); *(pBGDatai*width*2j*43) *(pFGDatai*width*2j*43); } } } } int Y11, U11, V11, Y12, Y21, U21, V21, Y22; int alpha1, alpha2; if (!alphaBG) { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y11 *(pBGDatai*width*2j*4); U11 *(pBGDatai*width*2j*41); Y12 *(pBGDatai*width*2j*42); V11 *(pBGDatai*width*2j*43); Y21 *(pFGDatai*width*3j*6); U21 *(pFGDatai*width*3j*61); Y22 *(pFGDatai*width*3j*62); V21 *(pFGDatai*width*3j*63); alpha1 *(pFGDatai*width*3j*64); alpha2 *(pFGDatai*width*3j*65); *(pBGDatai*width*2j*4) (Y21-16)*alpha1/255(Y11-16)*(255-alpha1)/25516; *(pBGDatai*width*2j*41) ((U21-128)*alpha1/255(U11-128)*(255-alpha1)/255 (U21-128)*alpha2/255(U11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*2j*43) ((V21-128)*alpha1/255(V11-128)*(255-alpha1)/255 (V21-128)*alpha2/255(V11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*2j*42) (Y22-16)*alpha2/255(Y12-16)*(255-alpha2)/25516; } } } else { for (int i0; iheight; i) { for (int j0; jwidth/2; j) { Y11 *(pBGDatai*width*3j*6); U11 *(pBGDatai*width*3j*61); Y12 *(pBGDatai*width*3j*62); V11 *(pBGDatai*width*3j*63); Y21 *(pFGDatai*width*3j*6); U21 *(pFGDatai*width*3j*61); Y22 *(pFGDatai*width*3j*62); V21 *(pFGDatai*width*3j*63); alpha1 *(pFGDatai*width*3j*64); alpha2 *(pFGDatai*width*3j*65); *(pBGDatai*width*3j*6) (Y21-16)*alpha1/255(Y11-16)*(255-alpha1)/25516; *(pBGDatai*width*3j*61) ((U21-128)*alpha1/255(U11-128)*(255-alpha1)/255 (U21-128)*alpha2/255(U11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*3j*63) ((V21-128)*alpha1/255(V11-128)*(255-alpha1)/255 (V21-128)*alpha2/255(V11-128)*(255-alpha2)/255)/2128; *(pBGDatai*width*3j*62) (Y22-16)*alpha2/255(Y12-16)*(255-alpha2)/25516; } } } return 0; } 经测试功能已经实现如有错误或者不妥的地方恳请指出。
mosesyuan at gmail dot com