- int RGB24_TO_YUV420(unsigned char *pucRGBBuffer,int width,int height,unsigned char *pucYUVBuffer)
- {
- unsigned char y, u, v; /**< 一个像素点对应的 YUV 分量 */
- unsigned char *pucY, *pucU, *pucV; /**< YUV 数组对应的指针 */
- unsigned char r, g, b; /**< 一个像素点对应的 RGB 分类 */
- unsigned char *pucRGB; /**< RGB24 对应的指针 */
- int iY = 0 ;
- int iX = 0 ;
- // 存储空间大小 Y : width*height ; U : width/2 * height/2 ; V : width/2 * height/2
- pucY = pucYUVBuffer;
- pucU = pucYUVBuffer + width*height; /**< U 数组在 YUV 数组的偏移量 */
- pucV = pucU + (width*height*1/4); /**< V 数组在 YUV 数组的偏移量 */
- for (iY = 0; iY < height;iY++){
- pucRGB = pucRGBBuffer + width*iY*3 ;
- for ( iX = 0;iX < width ; iX++){
- /**< 读取像素点的 RGB 分量 */
- r = *(pucRGB++);
- g = *(pucRGB++);
- b = *(pucRGB++);
- /**< 通过公式将 RGB 转换成为 YUV */
- y = (unsigned char)( ( 66 * r + 129 * g + 25 * b + 128)>> 8) + 16 ;
- u = (unsigned char)( ( -38 * r - 74 * g + 112 * b + 128)>> 8) + 128 ;
- v = (unsigned char)( ( 112 * r - 94 * g - 18 * b + 128)>> 8) + 128 ;
- /**< Y 分量直接写入 Y 数组 */*(pucY++) = clip_value(y,0,255);
- // 采样: 水平一半, 垂直一半, 实验证明这两种方式都可以
- if ( iY%2==0 && iX%2 == 0){
- /**< 偶数行偶数列时将 U 分量写入 U 数组, 即一个 4*4 方块的左上角 *$*
- * 0 1 2 3
- *
- *0 | U | | U | |
- * -------------------
- *1 | | | | |
- *
- */*(pucU++) = clip_value(u,0,255);
- }
- else{ /**< else 表示奇数行的情况 *$**< 奇数行偶数列时将 U 分量写入 U 数组, 即一个 4*4 方块的左下角 *$*
- * 0 1 2 3
- *
- *0 | | | | |
- * -------------------
- *1 | V | | V | |
- *
- */
- if ( iX%2 == 0 ){
- *(pucV++) = clip_value(v,0,255);
- }
- }
- }
- }
- return 1;
- }
来源: https://www.cnblogs.com/qiabaowei/p/8687487.html