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?
  1. //
  2. // YUV2RGB
  3. // pYUV         point to the YUV data
  4. // pRGB         point to the RGB data
  5. // width        width of the picture
  6. // height       height of the picture
  7. // alphaYUV     is there an alpha channel in YUV
  8. // alphaRGB     is there an alpha channel in RGB
  9. //
  10. int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB)
  11. {
  12. if (NULL == pYUV)
  13. {
  14. return -1;
  15. }
  16. unsigned char* pYUVData = (unsigned char *)pYUV;
  17. unsigned char* pRGBData = (unsigned char *)pRGB;
  18. if (NULL == pRGBData)
  19. {
  20. if (alphaRGB)
  21. {
  22. pRGBData = new unsigned char[width*height*4];
  23. }
  24. else
  25. pRGBData = new unsigned char[width*height*3];
  26. }
  27. int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2;
  28. int C1, D1, E1, C2;
  29. if (alphaRGB)
  30. {
  31. if (alphaYUV)
  32. {
  33. for (int i=0; i<height; ++i)
  34. {
  35. for (int j=0; j<width/2; ++j)
  36. {
  37. Y1 = *(pYUVData+i*width*3+j*6);
  38. U1 = *(pYUVData+i*width*3+j*6+1);
  39. Y2 = *(pYUVData+i*width*3+j*6+2);
  40. V1 = *(pYUVData+i*width*3+j*6+3);
  41. alpha1 = *(pYUVData+i*width*3+j*6+4);
  42. alpha2 = *(pYUVData+i*width*3+j*6+5);
  43. C1 = Y1-16;
  44. C2 = Y2-16;
  45. D1 = U1-128;
  46. E1 = V1-128;
  47. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  48. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  49. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  50. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  51. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  52. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  53. *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
  54. *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
  55. *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
  56. *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha1;
  57. *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
  58. *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
  59. *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
  60. *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha2;
  61. }
  62. }
  63. }
  64. else
  65. {
  66. int alpha = 255;
  67. for (int i=0; i<height; ++i)
  68. {
  69. for (int j=0; j<width/2; ++j)
  70. {
  71. Y1 = *(pYUVData+i*width*2+j*4);
  72. U1 = *(pYUVData+i*width*2+j*4+1);
  73. Y2 = *(pYUVData+i*width*2+j*4+2);
  74. V1 = *(pYUVData+i*width*2+j*4+3);
  75. C1 = Y1-16;
  76. C2 = Y2-16;
  77. D1 = U1-128;
  78. E1 = V1-128;
  79. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  80. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  81. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  82. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  83. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  84. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  85. *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
  86. *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
  87. *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
  88. *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha;
  89. *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
  90. *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
  91. *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
  92. *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha;
  93. }
  94. }
  95. }
  96. }
  97. else
  98. {
  99. if (alphaYUV)
  100. {
  101. for (int i=0; i<height; ++i)
  102. {
  103. for (int j=0; j<width/2; ++j)
  104. {
  105. Y1 = *(pYUVData+i*width*3+j*4);
  106. U1 = *(pYUVData+i*width*3+j*4+1);
  107. Y2 = *(pYUVData+i*width*3+j*4+2);
  108. V1 = *(pYUVData+i*width*3+j*4+3);
  109. C1 = Y1-16;
  110. C2 = Y2-16;
  111. D1 = U1-128;
  112. E1 = V1-128;
  113. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  114. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  115. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  116. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  117. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  118. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  119. *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
  120. *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
  121. *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
  122. *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
  123. *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
  124. *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
  125. }
  126. }
  127. }
  128. else
  129. {
  130. for (int i=0; i<height; ++i)
  131. {
  132. for (int j=0; j<width/2; ++j)
  133. {
  134. Y1 = *(pYUVData+i*width*2+j*4);
  135. U1 = *(pYUVData+i*width*2+j*4+1);
  136. Y2 = *(pYUVData+i*width*2+j*4+2);
  137. V1 = *(pYUVData+i*width*2+j*4+3);
  138. C1 = Y1-16;
  139. C2 = Y2-16;
  140. D1 = U1-128;
  141. E1 = V1-128;
  142. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  143. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  144. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  145. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  146. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  147. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  148. *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
  149. *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
  150. *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
  151. *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
  152. *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
  153. *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
  154. }
  155. }
  156. }
  157. }
  158. return 0;
  159. }
  160. //
  161. // RGB2YUV
  162. // pRGB         point to the RGB data
  163. // pYUV         point to the YUV data
  164. // width        width of the picture
  165. // height       height of the picture
  166. // alphaYUV     is there an alpha channel in YUV
  167. // alphaRGB     is there an alpha channel in RGB
  168. //
  169. int RGB2YUV(void* pRGB, void* pYUV, int width, int height, bool alphaYUV, bool alphaRGB)
  170. {
  171. if (NULL == pRGB)
  172. {
  173. return -1;
  174. }
  175. unsigned char* pRGBData = (unsigned char *)pRGB;
  176. unsigned char* pYUVData = (unsigned char *)pYUV;
  177. if (NULL == pYUVData)
  178. {
  179. if (alphaYUV)
  180. {
  181. pYUVData = new unsigned char[width*height*3];
  182. }
  183. else
  184. pYUVData = new unsigned char[width*height*2];
  185. }
  186. int R1, G1, B1, R2, G2, B2, Y1, U1, Y2, V1;
  187. int alpha1, alpha2;
  188. if (alphaYUV)
  189. {
  190. if (alphaRGB)
  191. {
  192. for (int i=0; i<height; ++i)
  193. {
  194. for (int j=0; j<width/2; ++j)
  195. {
  196. B1 = *(pRGBData+(height-i-1)*width*4+j*8);
  197. G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
  198. R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
  199. alpha1 = *(pRGBData+(height-i-1)*width*4+j*8+3);
  200. B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
  201. G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
  202. R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
  203. alpha2 = *(pRGBData+(height-i-1)*width*4+j*8+7);
  204. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  205. 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);
  206. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  207. 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);
  208. *(pYUVData+i*width*3+j*6) = Y1;
  209. *(pYUVData+i*width*3+j*6+1) = U1;
  210. *(pYUVData+i*width*3+j*6+2) = Y2;
  211. *(pYUVData+i*width*3+j*6+3) = V1;
  212. *(pYUVData+i*width*3+j*6+4) = alpha1;
  213. *(pYUVData+i*width*3+j*6+5) = alpha2;
  214. }
  215. }
  216. }
  217. else
  218. {
  219. unsigned char alpha = 255;
  220. for (int i=0; i<height; ++i)
  221. {
  222. for (int j=0; j<width/2; ++j)
  223. {
  224. B1 = *(pRGBData+(height-i-1)*width*3+j*6);
  225. G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
  226. R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
  227. B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
  228. G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
  229. R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
  230. Y1 = ((66*R1+129*G1+25*B1+128)>>8) + 16;
  231. U1 = ((-38*R1-74*G1+112*B1+128)>>8+(-38*R2-74*G2+112*B2+128)>>8)/2 + 128;
  232. Y2 = ((66*R2+129*G2+25*B2+128)>>8) + 16;
  233. V1 = ((112*R1-94*G1-18*B1+128)>>8 + (112*R2-94*G2-18*B2+128)>>8)/2 + 128;
  234. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  235. 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);
  236. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  237. 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);
  238. *(pYUVData+i*width*3+j*6) = Y1;
  239. *(pYUVData+i*width*3+j*6+1) = U1;
  240. *(pYUVData+i*width*3+j*6+2) = Y2;
  241. *(pYUVData+i*width*3+j*6+3) = V1;
  242. *(pYUVData+i*width*3+j*6+4) = alpha;
  243. *(pYUVData+i*width*3+j*6+5) = alpha;
  244. }
  245. }
  246. }
  247. }
  248. else
  249. {
  250. if (alphaRGB)
  251. {
  252. for (int i=0; i<height; ++i)
  253. {
  254. for (int j=0; j<width/2; ++j)
  255. {
  256. B1 = *(pRGBData+(height-i-1)*width*4+j*8);
  257. G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
  258. R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
  259. B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
  260. G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
  261. R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
  262. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  263. 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);
  264. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  265. 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);
  266. *(pYUVData+i*width*2+j*4) = Y1;
  267. *(pYUVData+i*width*2+j*4+1) = U1;
  268. *(pYUVData+i*width*2+j*4+2) = Y2;
  269. *(pYUVData+i*width*2+j*4+3) = V1;
  270. }
  271. }
  272. }
  273. else
  274. {
  275. for (int i=0; i<height; ++i)
  276. {
  277. for (int j=0; j<width/2; ++j)
  278. {
  279. B1 = *(pRGBData+(height-i-1)*width*3+j*6);
  280. G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
  281. R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
  282. B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
  283. G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
  284. R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
  285. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  286. 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);
  287. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  288. 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);
  289. *(pYUVData+i*width*2+j*4) = Y1;
  290. *(pYUVData+i*width*2+j*4+1) = U1;
  291. *(pYUVData+i*width*2+j*4+2) = Y2;
  292. *(pYUVData+i*width*2+j*4+3) = V1;
  293. }
  294. }
  295. }
  296. }
  297. return 0;
  298. }
  299. //
  300. // pGBYUV           point to the background YUV data
  301. // pFGYUV           point to the foreground YUV data
  302. // width            width of the picture
  303. // height           height of the picture
  304. // alphaBG          is there an alpha channel in background YUV data
  305. // alphaFG          is there an alpha channel in fourground YUV data
  306. //
  307. int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG)
  308. {
  309. if (NULL == pBGYUV || NULL == pFGYUV)
  310. {
  311. return -1;
  312. }
  313. unsigned char* pBGData = (unsigned char*)pBGYUV;
  314. unsigned char* pFGData = (unsigned char*)pFGYUV;
  315. if (!alphaFG)
  316. {
  317. if (!alphaBG)
  318. {
  319. memcpy(pBGData, pFGData, width*height*2);
  320. }
  321. else
  322. {
  323. for (int i=0; i<height; ++i)
  324. {
  325. for (int j=0; j<width/2; ++j)
  326. {
  327. *(pBGData+i*width*2+j*4) = *(pFGData+i*width*2+j*4);
  328. *(pBGData+i*width*2+j*4+1) = *(pFGData+i*width*2+j*4+1);
  329. *(pBGData+i*width*2+j*4+2) = *(pFGData+i*width*2+j*4+2);
  330. *(pBGData+i*width*2+j*4+3) = *(pFGData+i*width*2+j*4+3);
  331. }
  332. }
  333. }
  334. }
  335. int Y11, U11, V11, Y12, Y21, U21, V21, Y22;
  336. int alpha1, alpha2;
  337. if (!alphaBG)
  338. {
  339. for (int i=0; i<height; ++i)
  340. {
  341. for (int j=0; j<width/2; ++j)
  342. {
  343. Y11 = *(pBGData+i*width*2+j*4);
  344. U11 = *(pBGData+i*width*2+j*4+1);
  345. Y12 = *(pBGData+i*width*2+j*4+2);
  346. V11 = *(pBGData+i*width*2+j*4+3);
  347. Y21 = *(pFGData+i*width*3+j*6);
  348. U21 = *(pFGData+i*width*3+j*6+1);
  349. Y22 = *(pFGData+i*width*3+j*6+2);
  350. V21 = *(pFGData+i*width*3+j*6+3);
  351. alpha1 = *(pFGData+i*width*3+j*6+4);
  352. alpha2 = *(pFGData+i*width*3+j*6+5);
  353. *(pBGData+i*width*2+j*4) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
  354. *(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;
  355. *(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;
  356. *(pBGData+i*width*2+j*4+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
  357. }
  358. }
  359. }
  360. else
  361. {
  362. for (int i=0; i<height; ++i)
  363. {
  364. for (int j=0; j<width/2; ++j)
  365. {
  366. Y11 = *(pBGData+i*width*3+j*6);
  367. U11 = *(pBGData+i*width*3+j*6+1);
  368. Y12 = *(pBGData+i*width*3+j*6+2);
  369. V11 = *(pBGData+i*width*3+j*6+3);
  370. Y21 = *(pFGData+i*width*3+j*6);
  371. U21 = *(pFGData+i*width*3+j*6+1);
  372. Y22 = *(pFGData+i*width*3+j*6+2);
  373. V21 = *(pFGData+i*width*3+j*6+3);
  374. alpha1 = *(pFGData+i*width*3+j*6+4);
  375. alpha2 = *(pFGData+i*width*3+j*6+5);
  376. *(pBGData+i*width*3+j*6) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
  377. *(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;
  378. *(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;
  379. *(pBGData+i*width*3+j*6+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
  380. }
  381. }
  382. }
  383. return 0;
  384. }
[c-sharp] view plaincopyprint?
  1. //
  2. // YUV2RGB
  3. // pYUV         point to the YUV data
  4. // pRGB         point to the RGB data
  5. // width        width of the picture
  6. // height       height of the picture
  7. // alphaYUV     is there an alpha channel in YUV
  8. // alphaRGB     is there an alpha channel in RGB
  9. //
  10. int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB)
  11. {
  12. if (NULL == pYUV)
  13. {
  14. return -1;
  15. }
  16. unsigned char* pYUVData = (unsigned char *)pYUV;
  17. unsigned char* pRGBData = (unsigned char *)pRGB;
  18. if (NULL == pRGBData)
  19. {
  20. if (alphaRGB)
  21. {
  22. pRGBData = new unsigned char[width*height*4];
  23. }
  24. else
  25. pRGBData = new unsigned char[width*height*3];
  26. }
  27. int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2;
  28. int C1, D1, E1, C2;
  29. if (alphaRGB)
  30. {
  31. if (alphaYUV)
  32. {
  33. for (int i=0; i<height; ++i)
  34. {
  35. for (int j=0; j<width/2; ++j)
  36. {
  37. Y1 = *(pYUVData+i*width*3+j*6);
  38. U1 = *(pYUVData+i*width*3+j*6+1);
  39. Y2 = *(pYUVData+i*width*3+j*6+2);
  40. V1 = *(pYUVData+i*width*3+j*6+3);
  41. alpha1 = *(pYUVData+i*width*3+j*6+4);
  42. alpha2 = *(pYUVData+i*width*3+j*6+5);
  43. C1 = Y1-16;
  44. C2 = Y2-16;
  45. D1 = U1-128;
  46. E1 = V1-128;
  47. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  48. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  49. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  50. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  51. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  52. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  53. *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
  54. *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
  55. *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
  56. *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha1;
  57. *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
  58. *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
  59. *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
  60. *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha2;
  61. }
  62. }
  63. }
  64. else
  65. {
  66. int alpha = 255;
  67. for (int i=0; i<height; ++i)
  68. {
  69. for (int j=0; j<width/2; ++j)
  70. {
  71. Y1 = *(pYUVData+i*width*2+j*4);
  72. U1 = *(pYUVData+i*width*2+j*4+1);
  73. Y2 = *(pYUVData+i*width*2+j*4+2);
  74. V1 = *(pYUVData+i*width*2+j*4+3);
  75. C1 = Y1-16;
  76. C2 = Y2-16;
  77. D1 = U1-128;
  78. E1 = V1-128;
  79. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  80. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  81. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  82. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  83. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  84. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  85. *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
  86. *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
  87. *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
  88. *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha;
  89. *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
  90. *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
  91. *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
  92. *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha;
  93. }
  94. }
  95. }
  96. }
  97. else
  98. {
  99. if (alphaYUV)
  100. {
  101. for (int i=0; i<height; ++i)
  102. {
  103. for (int j=0; j<width/2; ++j)
  104. {
  105. Y1 = *(pYUVData+i*width*3+j*4);
  106. U1 = *(pYUVData+i*width*3+j*4+1);
  107. Y2 = *(pYUVData+i*width*3+j*4+2);
  108. V1 = *(pYUVData+i*width*3+j*4+3);
  109. C1 = Y1-16;
  110. C2 = Y2-16;
  111. D1 = U1-128;
  112. E1 = V1-128;
  113. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  114. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  115. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  116. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  117. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  118. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  119. *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
  120. *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
  121. *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
  122. *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
  123. *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
  124. *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
  125. }
  126. }
  127. }
  128. else
  129. {
  130. for (int i=0; i<height; ++i)
  131. {
  132. for (int j=0; j<width/2; ++j)
  133. {
  134. Y1 = *(pYUVData+i*width*2+j*4);
  135. U1 = *(pYUVData+i*width*2+j*4+1);
  136. Y2 = *(pYUVData+i*width*2+j*4+2);
  137. V1 = *(pYUVData+i*width*2+j*4+3);
  138. C1 = Y1-16;
  139. C2 = Y2-16;
  140. D1 = U1-128;
  141. E1 = V1-128;
  142. R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
  143. G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);
  144. B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);
  145. R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
  146. G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
  147. B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);
  148. *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
  149. *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
  150. *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
  151. *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
  152. *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
  153. *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
  154. }
  155. }
  156. }
  157. }
  158. return 0;
  159. }
  160. //
  161. // RGB2YUV
  162. // pRGB         point to the RGB data
  163. // pYUV         point to the YUV data
  164. // width        width of the picture
  165. // height       height of the picture
  166. // alphaYUV     is there an alpha channel in YUV
  167. // alphaRGB     is there an alpha channel in RGB
  168. //
  169. int RGB2YUV(void* pRGB, void* pYUV, int width, int height, bool alphaYUV, bool alphaRGB)
  170. {
  171. if (NULL == pRGB)
  172. {
  173. return -1;
  174. }
  175. unsigned char* pRGBData = (unsigned char *)pRGB;
  176. unsigned char* pYUVData = (unsigned char *)pYUV;
  177. if (NULL == pYUVData)
  178. {
  179. if (alphaYUV)
  180. {
  181. pYUVData = new unsigned char[width*height*3];
  182. }
  183. else
  184. pYUVData = new unsigned char[width*height*2];
  185. }
  186. int R1, G1, B1, R2, G2, B2, Y1, U1, Y2, V1;
  187. int alpha1, alpha2;
  188. if (alphaYUV)
  189. {
  190. if (alphaRGB)
  191. {
  192. for (int i=0; i<height; ++i)
  193. {
  194. for (int j=0; j<width/2; ++j)
  195. {
  196. B1 = *(pRGBData+(height-i-1)*width*4+j*8);
  197. G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
  198. R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
  199. alpha1 = *(pRGBData+(height-i-1)*width*4+j*8+3);
  200. B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
  201. G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
  202. R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
  203. alpha2 = *(pRGBData+(height-i-1)*width*4+j*8+7);
  204. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  205. 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);
  206. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  207. 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);
  208. *(pYUVData+i*width*3+j*6) = Y1;
  209. *(pYUVData+i*width*3+j*6+1) = U1;
  210. *(pYUVData+i*width*3+j*6+2) = Y2;
  211. *(pYUVData+i*width*3+j*6+3) = V1;
  212. *(pYUVData+i*width*3+j*6+4) = alpha1;
  213. *(pYUVData+i*width*3+j*6+5) = alpha2;
  214. }
  215. }
  216. }
  217. else
  218. {
  219. unsigned char alpha = 255;
  220. for (int i=0; i<height; ++i)
  221. {
  222. for (int j=0; j<width/2; ++j)
  223. {
  224. B1 = *(pRGBData+(height-i-1)*width*3+j*6);
  225. G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
  226. R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
  227. B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
  228. G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
  229. R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
  230. Y1 = ((66*R1+129*G1+25*B1+128)>>8) + 16;
  231. U1 = ((-38*R1-74*G1+112*B1+128)>>8+(-38*R2-74*G2+112*B2+128)>>8)/2 + 128;
  232. Y2 = ((66*R2+129*G2+25*B2+128)>>8) + 16;
  233. V1 = ((112*R1-94*G1-18*B1+128)>>8 + (112*R2-94*G2-18*B2+128)>>8)/2 + 128;
  234. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  235. 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);
  236. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  237. 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);
  238. *(pYUVData+i*width*3+j*6) = Y1;
  239. *(pYUVData+i*width*3+j*6+1) = U1;
  240. *(pYUVData+i*width*3+j*6+2) = Y2;
  241. *(pYUVData+i*width*3+j*6+3) = V1;
  242. *(pYUVData+i*width*3+j*6+4) = alpha;
  243. *(pYUVData+i*width*3+j*6+5) = alpha;
  244. }
  245. }
  246. }
  247. }
  248. else
  249. {
  250. if (alphaRGB)
  251. {
  252. for (int i=0; i<height; ++i)
  253. {
  254. for (int j=0; j<width/2; ++j)
  255. {
  256. B1 = *(pRGBData+(height-i-1)*width*4+j*8);
  257. G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
  258. R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
  259. B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
  260. G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
  261. R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
  262. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  263. 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);
  264. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  265. 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);
  266. *(pYUVData+i*width*2+j*4) = Y1;
  267. *(pYUVData+i*width*2+j*4+1) = U1;
  268. *(pYUVData+i*width*2+j*4+2) = Y2;
  269. *(pYUVData+i*width*2+j*4+3) = V1;
  270. }
  271. }
  272. }
  273. else
  274. {
  275. for (int i=0; i<height; ++i)
  276. {
  277. for (int j=0; j<width/2; ++j)
  278. {
  279. B1 = *(pRGBData+(height-i-1)*width*3+j*6);
  280. G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
  281. R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
  282. B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
  283. G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
  284. R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
  285. Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
  286. 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);
  287. Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
  288. 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);
  289. *(pYUVData+i*width*2+j*4) = Y1;
  290. *(pYUVData+i*width*2+j*4+1) = U1;
  291. *(pYUVData+i*width*2+j*4+2) = Y2;
  292. *(pYUVData+i*width*2+j*4+3) = V1;
  293. }
  294. }
  295. }
  296. }
  297. return 0;
  298. }
  299. //
  300. // pGBYUV           point to the background YUV data
  301. // pFGYUV           point to the foreground YUV data
  302. // width            width of the picture
  303. // height           height of the picture
  304. // alphaBG          is there an alpha channel in background YUV data
  305. // alphaFG          is there an alpha channel in fourground YUV data
  306. //
  307. int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG)
  308. {
  309. if (NULL == pBGYUV || NULL == pFGYUV)
  310. {
  311. return -1;
  312. }
  313. unsigned char* pBGData = (unsigned char*)pBGYUV;
  314. unsigned char* pFGData = (unsigned char*)pFGYUV;
  315. if (!alphaFG)
  316. {
  317. if (!alphaBG)
  318. {
  319. memcpy(pBGData, pFGData, width*height*2);
  320. }
  321. else
  322. {
  323. for (int i=0; i<height; ++i)
  324. {
  325. for (int j=0; j<width/2; ++j)
  326. {
  327. *(pBGData+i*width*2+j*4) = *(pFGData+i*width*2+j*4);
  328. *(pBGData+i*width*2+j*4+1) = *(pFGData+i*width*2+j*4+1);
  329. *(pBGData+i*width*2+j*4+2) = *(pFGData+i*width*2+j*4+2);
  330. *(pBGData+i*width*2+j*4+3) = *(pFGData+i*width*2+j*4+3);
  331. }
  332. }
  333. }
  334. }
  335. int Y11, U11, V11, Y12, Y21, U21, V21, Y22;
  336. int alpha1, alpha2;
  337. if (!alphaBG)
  338. {
  339. for (int i=0; i<height; ++i)
  340. {
  341. for (int j=0; j<width/2; ++j)
  342. {
  343. Y11 = *(pBGData+i*width*2+j*4);
  344. U11 = *(pBGData+i*width*2+j*4+1);
  345. Y12 = *(pBGData+i*width*2+j*4+2);
  346. V11 = *(pBGData+i*width*2+j*4+3);
  347. Y21 = *(pFGData+i*width*3+j*6);
  348. U21 = *(pFGData+i*width*3+j*6+1);
  349. Y22 = *(pFGData+i*width*3+j*6+2);
  350. V21 = *(pFGData+i*width*3+j*6+3);
  351. alpha1 = *(pFGData+i*width*3+j*6+4);
  352. alpha2 = *(pFGData+i*width*3+j*6+5);
  353. *(pBGData+i*width*2+j*4) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
  354. *(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;
  355. *(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;
  356. *(pBGData+i*width*2+j*4+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
  357. }
  358. }
  359. }
  360. else
  361. {
  362. for (int i=0; i<height; ++i)
  363. {
  364. for (int j=0; j<width/2; ++j)
  365. {
  366. Y11 = *(pBGData+i*width*3+j*6);
  367. U11 = *(pBGData+i*width*3+j*6+1);
  368. Y12 = *(pBGData+i*width*3+j*6+2);
  369. V11 = *(pBGData+i*width*3+j*6+3);
  370. Y21 = *(pFGData+i*width*3+j*6);
  371. U21 = *(pFGData+i*width*3+j*6+1);
  372. Y22 = *(pFGData+i*width*3+j*6+2);
  373. V21 = *(pFGData+i*width*3+j*6+3);
  374. alpha1 = *(pFGData+i*width*3+j*6+4);
  375. alpha2 = *(pFGData+i*width*3+j*6+5);
  376. *(pBGData+i*width*3+j*6) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
  377. *(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;
  378. *(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;
  379. *(pBGData+i*width*3+j*6+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
  380. }
  381. }
  382. }
  383. return 0;
  384. }
 经测试,功能已经实现,如有错误或者不妥的地方,恳请指出。
mosesyuan at gmail dot com

RGB 24和YUY2相互转换相关推荐

  1. 使用C++实现YUV格式图像与RGB格式图像之间相互转换

    使用C++实现YUV格式图像与RGB格式图像之间相互转换 一.RGB与YUV转换公式 1.RGB转YUV 1)RGB转换亮度与色差信号公试: 2)归一化为YUV的转化公试为: 2.YUV转RGB 二. ...

  2. YUYV 转 RGB 24

    直入正题吧, 关于YUYV编码流的官方介绍: http://linuxtv.org/downloads/v4l-dvb-apis/V4L2-PIX-FMT-YUYV.html 我们一起看看, YUYV ...

  3. RGB、YUY2、YUYV、YVYU、UYVY、AYUV、YUV444、YUV422、YUV420、YUV411

    1) YUV 4:4:4YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节.下面的四个像素为: [Y0 ...

  4. 谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV

    计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红.绿.蓝磷光材料发光而产生色彩. ...

  5. RGB、YUY2、YUYV、YVYU、UYVY、AYUV

    小知识:RGB与YUV----摘自<DirectShow实务精选> 作者:陆其明 计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加 ...

  6. 谈谈“色彩空间表示方法”——RGB、YUY2、YUYV、YVYU、UYVY、AYUV

    转自:http://bbs.chinavideo.org/viewthread.php?tid=4143 还可参考http://www.fourcc.org/yuv.php 小知识:RGB与YUV-- ...

  7. RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解

    计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红.绿.蓝磷光材料发光而产生色彩. ...

  8. RGB与YUV颜色空间

    计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red).G(Green).B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红.绿.蓝磷光材料发光而产生色彩. ...

  9. 使用OpenCV实现RGB、HSI、CMYK颜色空间的转换

    RGB to HSI.CMYK的代码实现 前言: 在之前博文的基础上,我使用OpenCV2实现了RGB颜色空间向HIS.CMYK转换的代码.下列链接为各种经典颜色空间的介绍及转换公式的介绍. http ...

最新文章

  1. jdbcutils.java_空指针异常错误哪个地方错了Exception in thread main (JdbcUtils.java:62) main(JdbcUtils.java:87)...
  2. 不一样的随机数生成方法(C/C++)
  3. UI组件之AdapterView及其子类关系,Adapter接口及其实现类关系
  4. springboot使用HttpSessionListener监听器统计在线用户数
  5. 深度学习--数据增强
  6. linux服务器文件索引inodes满了
  7. 深入理解Linux内核之内存寻址
  8. mac redis 客户端_分享一个免费好用的Redis桌面客户端
  9. centeros6.8 mysql_Center os6.5 mysql
  10. VisualSVN安装图解
  11. 用JMS578转接板开卡PS3111主控pSLC模式,带固件下载
  12. 一个简单的HTML网页 故宫学生网页设计作品 dreamweaver作业静态HTML网页设计模板 旅游景点网页作业制作
  13. java中decrement,Java LongAdder decrement()用法及代码示例
  14. STM32 ISP烧录过程
  15. python-Matplotlib图形上添加箭头指示
  16. Win11WSA无法启动的解决办法
  17. 评测TFN F4 高性能OTDR光时域反射仪性能
  18. Unix 时间戳 (Unix Timestamp) 与 Windows 时间转换工具
  19. 计算机lg符号,网上总出现LG的符号,是什么意思
  20. ICT界的基建狂魔—上海季冠:借助闪星云平台一天改造150家品牌珠宝店

热门文章

  1. 【转】1.4 Magento2语法讲解
  2. 【iOS开发】崩溃问题汇总
  3. C语言实现DES加解密算法
  4. 【LeetCode-SQL每日一练】—— 1179. 重新格式化部门表
  5. mysql 更新错误1062_mysql 出现1062错误怎么办
  6. 【POJ - 2096】Collecting Bugs(概率dp)
  7. 【2019浙江省赛 - E】Sequence in the Pocket(思维)
  8. 【牛客 - 327G】处女座与复读机(可编辑距离问题,dp)
  9. mysql 递归实现树形_Mysql实现树形递归查询
  10. c语言课题设计字符串处理函数报告,C语言输入输出库函数设计实验报告.doc