前言

提示:书写目的是为对YUV与RGB存储格式的了解,该代码可以直接用,也存在待优化的地方,后续优化,还请大家多多指点

编译环境:

LINUX下编译的,有gcc编译工具即可

看图工具:

 后续附上

文件列表

  • app_main.c 主函数
  • rgbtoyuv.c 处理文件
  • rgbtoyuv.h 头文件
  • Makefile 编译规则

1、主函数app_main.c

#include <stdio.h>
#include <stdlib.h>#include "rgbtoyuv.h"
int main()
{//make_rgb24_colorbar();  char *RGBfilename = "rgb888.rgb";char *DstRGBfilename_1 = "dst_rgb888_1.rgb";char *DstRGBfilename_2 = "dst_rgb888_2.rgb";char *DstRGBfilename_3 = "dst_rgb888_3.rgb";char *DstRGBfilename_4 = "dst_rgb888_4.rgb";char *DstRGBfilename_5 = "dst_rgb888_5.rgb";char *DstRGBfilename_6 = "dst_rgb888_6.rgb";char *YUV420p_I420_filename = "yuv420p_I420.yuv";char *YUV420p_YV12_filename = "yuv420p_YV12.yuv";char *YUV422p_YU16_filename = "yuv422p_YU16.yuv";char *YUV422p_YV16_filename = "yuv422p_YV16.yuv";char *YUV444p_I444_filename = "yuv444p_I444.yuv";char *YUV444p_YV24_filename = "yuv444p_YV24.yuv";int iRgbSize = 0;int iRet = 0, i = 0;unsigned char c;FILE *fp_rgb       = fopen(RGBfilename, "wb+");FILE *fp_rgb_dst_1  = fopen(DstRGBfilename_1, "wb+");FILE *fp_rgb_dst_2     = fopen(DstRGBfilename_2, "wb+");FILE *fp_rgb_dst_3     = fopen(DstRGBfilename_3, "wb+");FILE *fp_rgb_dst_4     = fopen(DstRGBfilename_4, "wb+");FILE *fp_rgb_dst_5     = fopen(DstRGBfilename_5, "wb+");FILE *fp_rgb_dst_6     = fopen(DstRGBfilename_6, "wb+");FILE *fp_YUV420p_I420 = fopen(YUV420p_I420_filename, "wb+");FILE *fp_yuv420p_YV12 = fopen(YUV420p_YV12_filename, "wb+");FILE *fp_yuv422p_YU16 = fopen(YUV422p_YU16_filename, "wb+");FILE *fp_yuv422p_YV16 = fopen(YUV422p_YV16_filename, "wb+");FILE *fp_yuv444p_I444 = fopen(YUV444p_I444_filename, "wb+");FILE *fp_yuv444p_YV24 = fopen(YUV444p_YV24_filename, "wb+");//-----------------------1、生成 RGB888 图像 -----------------------------iRgbSize = iamge_creat_rgb24(fp_rgb, IMAGE_W, IMAGE_H);if (iRgbSize == ERROR){printf(" iamge_creat_rgb24 error \n");return 0;}fflush(fp_rgb);//---打印RGB实际数据/*fseek(fp_rgb, 0, SEEK_SET);for (i = 0; i < IMAGE_W*IMAGE_H * 3; i++){if (i % (IMAGE_W * 3) == 0)printf("\n");fread(&c, 1, 1, fp_rgb);printf("%3d ",c);}*/printf("-----------write file %s totle  is %d bit \n", RGBfilename, iRgbSize);//-------------------------------- 2、图像转换  RGB_TO_YUV  -----------------------------//---YUV420piRet = image_rgb888_to_yuv420p(fp_rgb, fp_YUV420p_I420, IMAGE_W, IMAGE_H, YUV420P_I420);if(iRet == ERROR){printf(" image_rgb88_to_yuv420p error \n");goto RELASE;}fflush(fp_YUV420p_I420);printf("  [%d] image_rgb888_to_yuv420p  finish !!!!! \n",__LINE__);iRet = image_rgb888_to_yuv420p(fp_rgb, fp_yuv420p_YV12, IMAGE_W, IMAGE_H, YUV420P_YV12);if (iRet == ERROR){printf(" image_rgb88_to_yuv420p error \n");goto RELASE;}fflush(fp_yuv420p_YV12);printf("  [%d] image_rgb888_to_yuv420p  finish !!!!! \n",__LINE__);//---YUV422piRet = image_rgb888_to_yuv422p(fp_rgb, fp_yuv422p_YU16, IMAGE_W, IMAGE_H, YUV422P_YU16);if (iRet == ERROR){printf(" image_rgb88_to_yuv420p error \n");goto RELASE;}fflush(fp_yuv422p_YU16);printf("  [%d] image_rgb888_to_yuv422p  finish !!!!! \n",__LINE__);iRet = image_rgb888_to_yuv422p(fp_rgb, fp_yuv422p_YV16, IMAGE_W, IMAGE_H, YUV422P_YV16);if (iRet == ERROR){printf(" image_rgb888_to_yuv422p error \n");goto RELASE;}fflush(fp_yuv422p_YV16);printf("  [%d] image_rgb888_to_yuv422p  finish !!!!! \n",__LINE__);iRet = image_rgb888_to_yuv444p(fp_rgb, fp_yuv444p_I444, IMAGE_W, IMAGE_H, YUV444P_I444);if (iRet == ERROR){printf(" image_rgb888_to_yuv444p error \n");goto RELASE;}fflush(fp_yuv444p_I444);iRet = image_rgb888_to_yuv444p(fp_rgb, fp_yuv444p_YV24, IMAGE_W, IMAGE_H, YUV444P_YV24);if (iRet == ERROR){printf(" image_rgb888_to_yuv444p error \n");goto RELASE;}fflush(fp_yuv444p_YV24);//--------------------------------------------------------------------------------------------//-------------------------------------- YUV to RGB------------------------------------------------iRet = image_yuv444p_to_rgb888(fp_yuv444p_YV24, fp_rgb_dst_1, IMAGE_W, IMAGE_H, YUV444P_YV24);if (iRet == ERROR){printf(" image_yuv444p_to_rgb888 error \n");goto RELASE;}fflush(fp_rgb_dst_1);iRet = image_yuv444p_to_rgb888(fp_yuv444p_I444, fp_rgb_dst_2, IMAGE_W, IMAGE_H, YUV444P_I444);if (iRet == ERROR){printf(" image_yuv444p_to_rgb888 error \n");goto RELASE;}fflush(fp_rgb_dst_2);iRet = image_yuv420p_to_rgb888(fp_yuv420p_YV12, fp_rgb_dst_3, IMAGE_W, IMAGE_H, YUV420P_YV12);if (iRet == ERROR){printf(" image_yuv420p_to_rgb888 error \n");goto RELASE;}fflush(fp_rgb_dst_3);iRet = image_yuv420p_to_rgb888(fp_YUV420p_I420, fp_rgb_dst_4, IMAGE_W, IMAGE_H, YUV420P_I420);if (iRet == ERROR){printf(" image_yuv420p_to_rgb888 error \n");goto RELASE;}fflush(fp_rgb_dst_4);iRet = image_yuv422p_to_rgb888(fp_yuv422p_YV16, fp_rgb_dst_5, IMAGE_W, IMAGE_H, YUV422P_YV16);if (iRet == ERROR){printf(" image_yuv422p_to_rgb888 error \n");goto RELASE;}fflush(fp_rgb_dst_5);iRet = image_yuv422p_to_rgb888(fp_yuv422p_YU16, fp_rgb_dst_6, IMAGE_W, IMAGE_H, YUV422P_YU16);if (iRet == ERROR){printf(" image_yuv422p_to_rgb888 error \n");goto RELASE;}fflush(fp_rgb_dst_6);printf("---------------------image change OK \n");fclose(fp_rgb);fclose(fp_YUV420p_I420);fclose(fp_yuv420p_YV12);fclose(fp_yuv422p_YU16);fclose(fp_yuv422p_YV16);fclose(fp_yuv444p_I444);fclose(fp_yuv444p_YV24);fclose(fp_rgb_dst_1);fclose(fp_rgb_dst_2);fclose(fp_rgb_dst_3);fclose(fp_rgb_dst_4);fclose(fp_rgb_dst_5);fclose(fp_rgb_dst_6);return OK;//----------------------------- 3、关闭句柄 -------------------------------------
RELASE:fclose(fp_rgb);fclose(fp_YUV420p_I420);fclose(fp_yuv420p_YV12);fclose(fp_yuv422p_YU16);fclose(fp_yuv422p_YV16);fclose(fp_yuv444p_I444);fclose(fp_yuv444p_YV24);fclose(fp_rgb_dst_1);fclose(fp_rgb_dst_2);fclose(fp_rgb_dst_3);fclose(fp_rgb_dst_4);fclose(fp_rgb_dst_5);fclose(fp_rgb_dst_6);return 0;
}

2、处理文件rgbtoyuv.c

/********************************************************************    待优化:*        1、转换函数中的写操作fread操作的参数*      2、malloc改为申请大空间 ,让程序不需要自己计算不同YUV格式需要的空间大小*******
*************************************************************/#include "rgbtoyuv.h"#define IMAGE_PTR_CHEAK(p) \{\if(p == NULL)\{    \printf(" p == NULL !!!!!!");\return ERROR; \}  \}#define IMAGE_ERROR(str) \{\printf("[%s] [%d] : IMAGE_ERROR : %s \n", __FUNCTION__, __LINE__, str);\}#define IMAGE_YUV420_SIZE(w, h) ((w) * (h) * 3 / 2)    /**<---根据数据格式来判断大小 YUV420 按照 w * h * 3 * (3/6)*/#define IMAGE_YUV422_SIZE(w, h)  ((w) * (h) * 2)     /**<---根据数据格式来判断大小 YUV422 按照 w * h * 3 * (4/6)*/#define IMAGE_YUV444_SIZE(w, h) ((w) * (h) * 3)      /**<---根据数据格式来判断大小 YUV444 按照 w * h * 3 * (3/3)*//**
* @brief   限幅像素的取值范围(内部函数)
* @param   [in] val 被限幅的像素值
* @param   [in] min_val 限幅最低值,建议最低为0
* @param   [in] max_val 限幅最高值,建议最高为255
* @return  返回限幅后的像素值
*/
static inline unsigned char image_clip_value(unsigned char val, unsigned char min_val, unsigned char max_val)
{/*if (val > max_val) {return max_val;}else if (val < min_val) {return min_val;}else {return val;}*/return val > max_val ? max_val : (val < min_val ? min_val : val);
}/**
* @brief   将RGB24 图像转换 YUV420p  YUV数据(内部函数)
* @param   [out] pYUVBuf   输出的YUV420p图像数据
* @param   [in] YUVsize        输出的YUV420p图像数据
* @param   [in] RGBBuf     输入的RGB图像数据
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] mode       参考YUV420P_MODE_E 枚举变量
* @return  OK / ERROR 成功/失败
*/
static int rgb_to_yuv420p(unsigned char *pYUVBuf, unsigned int  YUVsize, unsigned char *RGBBuf, int w, int h, YUV420P_MODE_E mode)
{int i = 0, j = 0;unsigned char y, u, v, r, g, b;unsigned char *ptrY, *ptrU, *ptrV, *ptrRGB;IMAGE_PTR_CHEAK(pYUVBuf);IMAGE_PTR_CHEAK(RGBBuf);if (YUVsize < (unsigned int)IMAGE_YUV420_SIZE(w, h)){printf("YUVsize too small ,YUVsize = [%d], need size > [%d]\n", YUVsize, (unsigned int)IMAGE_YUV420_SIZE(w, h));return ERROR;}//---YUV420p存储V、U的两种方式区分:(每4个Y,公用一个U和V分量)ptrY = pYUVBuf;if (mode == YUV420P_I420){ptrU = pYUVBuf + w*h;ptrV = ptrU + (w*h * 1 / 4);}else if(mode == YUV420P_YV12){ptrV = pYUVBuf + w*h;ptrU = ptrV + (w*h * 1 / 4);}else{IMAGE_ERROR(" ------YUV420p mode dismatch !!!!!! ");return ERROR;}//---数据转换for (j = 0; j < h; j++){ptrRGB = RGBBuf + w*j*3;for (i = 0; i < w; i++){r = *(ptrRGB++);g = *(ptrRGB++);b = *(ptrRGB++);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;*(ptrY) = image_clip_value(y, 0, 255);printf("Y");ptrY++;//---根据数据格式给每个像素上填充对应的Y、U、V分量if (j % 2 == 0 && i % 2 == 0){*(ptrU) = image_clip_value(u, 0, 255);printf("U");ptrU++;}else{if (i % 2 == 0){*(ptrV) = image_clip_value(v, 0, 255);printf("V");ptrV++;}}}printf("   [j = %d] \n", j);}return OK;
}/**
* @brief   将RGB24 图像转换 YUV422p  YUV数据(内部函数)
* @param   [out] pYUVBuf   输出的YUV420p图像数据
* @param   [in] YUVsize        输出的YUV420p图像数据
* @param   [in] RGBBuf     输入的RGB图像数据
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] mode       参考YUV422P_MODE_E 枚举变量
* @return  OK / ERROR 成功/失败
*/
static int rgb_to_yuv422p(unsigned char *pYUVBuf, unsigned int  YUVsize, unsigned char *RGBBuf, int w, int h, YUV422P_MODE_E mode)
{int i = 0, j = 0;unsigned char y, u, v, r, g, b;unsigned char *ptrY, *ptrU, *ptrV, *ptrRGB;IMAGE_PTR_CHEAK(pYUVBuf);IMAGE_PTR_CHEAK(RGBBuf);if (YUVsize < (unsigned int)IMAGE_YUV422_SIZE(w, h)){printf("YUVsize too small ,YUVsize = [%d], need size > [%d]\n", YUVsize, (unsigned int)IMAGE_YUV422_SIZE(w, h));return ERROR;}//---YUV422p存储V、U的两种方式区分:(每2个Y,公用一个U和V分量)ptrY = pYUVBuf;if (mode == YUV422P_YU16){ptrU = pYUVBuf + w*h;ptrV = ptrU + (w*h / 2);}else if (mode == YUV422P_YV16){ptrV = pYUVBuf + w*h;ptrU = ptrV + (w*h / 2);}else{IMAGE_ERROR(" ------YUV422p mode dismatch !!!!!! ");return ERROR;}//---数据转换for (j = 0; j < h; j++){ptrRGB = RGBBuf + w*j * 3;for (i = 0; i < w; i++){r = *(ptrRGB++);g = *(ptrRGB++);b = *(ptrRGB++);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;*(ptrY) = image_clip_value(y, 0, 255);printf("Y");ptrY++;//---根据数据格式给每个像素上填充对应的Y、U、V分量if (i % 2 == 0){*(ptrV) = image_clip_value(v, 0, 255);printf("V");ptrV++;*(ptrU) = image_clip_value(u, 0, 255);printf("U");ptrU++;}}printf("   [j = %d] \n", j);}return OK;
}/**
* @brief   将RGB24 图像转换 YUV444p  YUV数据(内部函数)
* @param   [out] pYUVBuf   输出的YUV420p图像数据
* @param   [in] YUVsize        输出的YUV420p图像数据
* @param   [in] RGBBuf     输入的RGB图像数据
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] mode       参考YUV444P_MODE_E 枚举变量
* @return  OK / ERROR 成功/失败
*/
static int rgb_to_yuv444p(unsigned char *pYUVBuf, unsigned int  YUVsize, unsigned char *RGBBuf, int w, int h, YUV444P_MODE_E mode)
{int i = 0, j = 0;unsigned char y, u, v, r, g, b;unsigned char *ptrY, *ptrU, *ptrV, *ptrRGB;IMAGE_PTR_CHEAK(pYUVBuf);IMAGE_PTR_CHEAK(RGBBuf);if (YUVsize < (unsigned int)IMAGE_YUV444_SIZE(w, h))  {printf("YUVsize too small ,YUVsize = [%d], need size > [%d]\n", YUVsize, (unsigned int)IMAGE_YUV444_SIZE(w, h));return ERROR;}//---YUV444p存储V、U的两种方式区分:(不丢失信息,无损)ptrY = pYUVBuf;if (mode == YUV444P_I444){ptrU = pYUVBuf + w*h;ptrV = ptrU + (w*h);}else if (mode == YUV444P_YV24){ptrV = pYUVBuf + w*h;ptrU = ptrV + (w*h);}else{IMAGE_ERROR(" ------YUV444p mode dismatch !!!!!! ");return ERROR;}//---数据转换for (j = 0; j < h; j++){ptrRGB = RGBBuf + w*j * 3;for (i = 0; i < w; i++){r = *(ptrRGB++);g = *(ptrRGB++);b = *(ptrRGB++);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;*(ptrY) = image_clip_value(y, 0, 255);printf("Y");ptrY++;//---根据数据格式给每个像素上填充对应的Y、U、V分量*(ptrV) = image_clip_value(v, 0, 255);printf("V");ptrV++;*(ptrU) = image_clip_value(u, 0, 255);printf("U");ptrU++;}printf("   [j = %d] \n", j);}return OK;
}/**
* @brief   将YUV422p 图像转换 RGB888(内部函数)
* @param   [out] RGBBuf        输出的RGB图像数据
* @param   [in] pYUVBuf        输入的YUV422p图像数据BUFF
* @param   [in] YUVsize        输入的YUV422p图像数据BUFF大小
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] mode       参考YUV420P_MODE_E 枚举变量
* @return  OK / ERROR 成功/失败
*/
static int yuv420p_to_rgb888(unsigned char *RGBBuf, unsigned char  *pYUVBuf, unsigned int YUVsize, int w, int h, YUV420P_MODE_E mode)
{int  i = 0, j = 0;unsigned char *ptrY, *ptrU, *ptrV;unsigned char y, u, v;unsigned char r, g, b;unsigned int  nv_index = 0, rgb_index = 0;IMAGE_PTR_CHEAK(pYUVBuf);IMAGE_PTR_CHEAK(RGBBuf);if (YUVsize < (unsigned int)IMAGE_YUV420_SIZE(w, h)){printf("YUVsize too small ,YUVsize = [%d], need size > [%d]\n", YUVsize, (unsigned int)IMAGE_YUV420_SIZE(w, h));return ERROR;}//---YUV420p存储V、U的两种方式区分:(每4个Y,公用一个U和V分量)ptrY = pYUVBuf;if (mode == YUV420P_I420){ptrU = pYUVBuf + w*h;ptrV = ptrU + (w*h * 1 / 4);}else if(mode == YUV420P_YV12){ptrV = pYUVBuf + w*h;ptrU = ptrV + (w*h * 1 / 4);}else{IMAGE_ERROR(" ------YUV420p mode dismatch !!!!!! ");return ERROR;}//---行扫描的方式for (i = 0; i < h; i++){for (j = 0; j < w ; j++, rgb_index++ ) {nv_index = (i / 2) * (w / 2) + (j / 2);y = *(ptrY++);u = *(ptrU + nv_index);v = *(ptrV + nv_index);r = y + ((351 * (v - 128)) >> 8);  //rg = y - ((179 * (v - 128) + 86 * (u - 128)) >> 8); //gb = y + ((443 * (u - 128)) >> 8); //br = image_clip_value(r, 0, 255);g = image_clip_value(g, 0, 255);b = image_clip_value(b, 0, 255);RGBBuf[rgb_index * 3 + 0] = b;RGBBuf[rgb_index * 3 + 1] = g;RGBBuf[rgb_index * 3 + 2] = r;}}}/**
* @brief   将YUV422p 图像转换 RGB888(内部函数)
* @param   [out] RGBBuf        输出的RGB图像数据
* @param   [in] pYUVBuf        输入的YUV422p图像数据BUFF
* @param   [in] YUVsize        输入的YUV422p图像数据BUFF大小
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] mode       参考YUV422P_MODE_E 枚举变量
* @return  OK / ERROR 成功/失败
*/
static int yuv422p_to_rgb888(unsigned char *RGBBuf, unsigned char  *pYUVBuf, unsigned int YUVsize, int w, int h, YUV422P_MODE_E mode)
{int  i = 0, j = 0;unsigned char *ptrY, *ptrU, *ptrV;unsigned char y, u, v;unsigned char r, g, b;unsigned int  nv_index = 0, rgb_index = 0;//---YUV422p存储V、U的两种方式区分:(每4个Y,公用一个U和V分量)ptrY = pYUVBuf;if (mode == YUV422P_YU16){ptrU = pYUVBuf + w*h;ptrV = ptrU + (w*h * 1 / 2);}else if(mode == YUV422P_YV16){ptrV = pYUVBuf + w*h;ptrU = ptrV + (w*h * 1 / 2);}else{IMAGE_ERROR(" ------YUV422p mode dismatch !!!!!! ");return ERROR;}//---行扫描的方式for (i = 0; i < h; i++){for (j = 0; j < w ; j++, rgb_index++ ) {nv_index = (i) * (w / 2) + (j / 2);y = *(ptrY++);u = *(ptrU + nv_index);v = *(ptrV + nv_index);r = y + ((351 * (v - 128)) >> 8);  //rg = y - ((179 * (v - 128) + 86 * (u - 128)) >> 8); //gb = y + ((443 * (u - 128)) >> 8); //br = image_clip_value(r, 0, 255);g = image_clip_value(g, 0, 255);b = image_clip_value(b, 0, 255);RGBBuf[rgb_index * 3 + 0] = b;RGBBuf[rgb_index * 3 + 1] = g;RGBBuf[rgb_index * 3 + 2] = r;}}}/**
* @brief   将YUV444p 图像转换 RGB888(内部函数)
* @param   [-ut] RGBBuf        输出的RGB图像数据
* @param   [in] pYUVBuf        输入的YUV444p图像数据BUFF
* @param   [in] YUVsize        输入的YUV444p图像数据BUFF大小
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] mode       参考YUV444P_MODE_E 枚举变量
* @return  OK / ERROR 成功/失败
*/
static int yuv444p_to_rgb888(unsigned char *RGBBuf, unsigned char  *pYUVBuf, unsigned int YUVsize, int w, int h, YUV444P_MODE_E mode)
{int  i = 0, j = 0;unsigned char *ptrY, *ptrU, *ptrV;unsigned char y, u, v;unsigned char r, g, b;unsigned int  nv_index = 0, rgb_index = 0;//---YUV444p存储V、U的两种方式区分:(每4个Y,公用一个U和V分量)ptrY = pYUVBuf;if (mode == YUV444P_I444){ptrU = pYUVBuf + w*h;ptrV = ptrU + (w*h);}else if(mode == YUV444P_YV24){ptrV = pYUVBuf + w*h;ptrU = ptrV + (w*h);}else{IMAGE_ERROR(" ------YUV444p mode dismatch !!!!!! ");return ERROR;}//---行扫描的方式for (i = 0; i < h; i++){for (j = 0; j < w ; j++, rgb_index++ ) {y = *(ptrY++);u = *(ptrU++);v = *(ptrV++);r = y + ((351 * (v - 128)) >> 8);  //rg = y - ((179 * (v - 128) + 86 * (u - 128)) >> 8); //gb = y + ((443 * (u - 128)) >> 8); //br = image_clip_value(r, 0, 255);g = image_clip_value(g, 0, 255);b = image_clip_value(b, 0, 255);RGBBuf[rgb_index * 3 + 0] = b;RGBBuf[rgb_index * 3 + 1] = g;RGBBuf[rgb_index * 3 + 2] = r;}}}/**
* @brief   生成RGB24的图像
* @param   [in] filename   图像文件名 .rgb格式
* @param   [in] imageW     生成图像的宽度
* @param   [in] imageH     生成图像的高度
* @return  成功返回图像的大小
*/
int iamge_creat_rgb24(FILE *fp_rgb, int imageW, int imageH)
{int i = 0, imageSize = 0;unsigned char chr = 0;IMAGE_PTR_CHEAK(fp_rgb);if (imageW == 0 || imageH == 0){IMAGE_ERROR("imageW = 0 or imageH = 0");return ERROR;}for (i = 0; i < imageW * imageH; i++){if (i < imageW * imageH / 3){chr = 0;fwrite(&chr, 1, 1, fp_rgb);chr = 0;fwrite(&chr, 1, 1, fp_rgb);chr = 255;fwrite(&chr, 1, 1, fp_rgb);}else if (i < imageW * imageH * 2 / 3){chr = 0;fwrite(&chr, 1, 1, fp_rgb);chr = 255;fwrite(&chr, 1, 1, fp_rgb);chr = 0;fwrite(&chr, 1, 1, fp_rgb);}else{chr = 255;fwrite(&chr, 1, 1, fp_rgb);chr = 0;fwrite(&chr, 1, 1, fp_rgb);chr = 0;fwrite(&chr, 1, 1, fp_rgb);}imageSize++;}//---返回RGB 888 对应的大小 imageSize*3等价于w * h * 3return imageSize*3;
}/**
* @brief   rgb888 (rgb24)    转换为yuv420p
* @param   [in] fp_rgb         RGB图像文件句柄
* @param   [in] fp_yuv         YUV图像文件句柄
* @param   [in] imageW         生成图像的宽度
* @param   [in] imageH         生成图像的高度
* @param   [in] YUV420P_MODE_E YUV420p的格式
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_rgb888_to_yuv420p(FILE *fp_rgb, FILE *fp_yuv, int imageW, int imageH, YUV420P_MODE_E YUVmode)
{unsigned char *pYUVBuff;int iRet = -1;unsigned int i = 0;if (imageW == 0 || imageH == 0){IMAGE_ERROR("imageW = 0 or imageH = 0");return ERROR;}if (fp_rgb == NULL || fp_yuv == NULL){IMAGE_ERROR("fp_rgb or fp_yuv open failed !!!!!!!");return ERROR;}//---1、获取数据  (从开始位置读全部大小写入到转换函数RGB24_TO_YUV420P()的输入数组中)memset(s_uRGB, 0, sizeof(s_uRGB));fseek(fp_rgb, 0, SEEK_SET);iRet = fread(s_uRGB, 1, imageW * imageH * 3, fp_rgb);//---2、动态申请存放YUV的BUFFpYUVBuff = (unsigned char *)malloc(IMAGE_YUV420_SIZE(imageW, imageH)+1);if (pYUVBuff == NULL){IMAGE_ERROR("malloc pYUVBuff failed !!!!!!!!!");return ERROR;}//---3、调用对应转换函数iRet = rgb_to_yuv420p(pYUVBuff, imageW * imageH * 3 / 2, s_uRGB, imageW, imageH, YUVmode);if(iRet == ERROR){IMAGE_ERROR("rgb_to_yuv420p failed !!!!!!!!!");free(pYUVBuff);return ERROR;}//---4、将YUV数据写入文件fseek(fp_yuv, 0, SEEK_SET);fwrite(pYUVBuff, 1, imageW * imageH * 3 / 2, fp_yuv);//---5、再次读文件,验证数据/*memset(pYUVBuff, 0, imageW * imageH * 3 / 2);fseek(fp_yuv, 0, SEEK_SET);fread(pYUVBuff, 1, imageW * imageH * 3 / 2, fp_yuv);for(i = 0; i < imageW * imageH * 3 / 2 ;i++){if (i % imageW == 0)printf("\n");printf("%3d ", pYUVBuff[i]);}printf("\n");*/free(pYUVBuff);return OK;
}/**
* @brief   rgb888 (rgb24)    转换为yuv422p
* @param   [in] fp_rgb         RGB图像文件句柄
* @param   [in] fp_yuv         YUV图像文件句柄
* @param   [in] imageW         生成图像的宽度
* @param   [in] imageH         生成图像的高度
* @param   [in] YUV422P_MODE_E YUV422p的格式
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_rgb888_to_yuv422p(FILE *fp_rgb, FILE *fp_yuv, int imageW, int imageH, YUV422P_MODE_E YUVmode)
{unsigned char *pYUVBuff;int iRet = -1;unsigned int i = 0;if (imageW == 0 || imageH == 0){IMAGE_ERROR("imageW = 0 or imageH = 0");return ERROR;}if (fp_rgb == NULL || fp_yuv == NULL){IMAGE_ERROR("fp_rgb or fp_yuv open failed !!!!!!!");return ERROR;}//---1、获取数据  (从开始位置读全部大小写入到转换函数RGB24_TO_YUV420P()的输入数组中)memset(s_uRGB, 0, sizeof(s_uRGB));fseek(fp_rgb, 0, SEEK_SET);iRet = fread(s_uRGB, 1, imageW * imageH * 3, fp_rgb);     //--------------待优化!!!!!!!!!//---2、动态申请存放YUV的BUFFpYUVBuff = (unsigned char *)malloc(((unsigned int)IMAGE_YUV422_SIZE(imageW, imageH))+1);if (pYUVBuff == NULL){IMAGE_ERROR("malloc pYUVBuff failed !!!!!!!!!");return ERROR;}//---3、调用对应转换函数iRet = rgb_to_yuv422p(pYUVBuff, (unsigned int)IMAGE_YUV422_SIZE(imageW, imageH), s_uRGB, imageW, imageH, YUVmode);    //----待优化输入数据大小if (iRet == ERROR){IMAGE_ERROR("rgb_to_yuv422p failed !!!!!!!!!");free(pYUVBuff);return ERROR;}//---4、将YUV数据写入文件fseek(fp_yuv, 0, SEEK_SET);fwrite(pYUVBuff, 1, imageW * imageH * 2, fp_yuv);//---5、再次读文件,验证数据/*memset(pYUVBuff, 0, imageW * imageH * 3 / 2);fseek(fp_yuv, 0, SEEK_SET);fread(pYUVBuff, 1, imageW * imageH * 3 / 2, fp_yuv);for(i = 0; i < imageW * imageH * 3 / 2 ;i++){if (i % imageW == 0)printf("\n");printf("%3d ", pYUVBuff[i]);}printf("\n");*/free(pYUVBuff);return OK;
}/**
* @brief   rgb888 (rgb24)    转换为yuv444p
* @param   [in] fp_rgb         RGB图像文件句柄
* @param   [in] fp_yuv         YUV图像文件句柄
* @param   [in] imageW         生成图像的宽度
* @param   [in] imageH         生成图像的高度
* @param   [in] YUV444P_MODE_E YUV444p的格式
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_rgb888_to_yuv444p(FILE *fp_rgb, FILE *fp_yuv, int imageW, int imageH, YUV444P_MODE_E YUVmode)
{unsigned char *pYUVBuff;int iRet = -1;unsigned int i = 0;if (imageW == 0 || imageH == 0){IMAGE_ERROR("imageW = 0 or imageH = 0");return ERROR;}if (fp_rgb == NULL || fp_yuv == NULL){IMAGE_ERROR("fp_rgb or fp_yuv open failed !!!!!!!");return ERROR;}//---1、获取数据  (从开始位置读全部大小写入到转换函数RGB24_TO_YUV444P()的输入数组中)memset(s_uRGB, 0, sizeof(s_uRGB));fseek(fp_rgb, 0, SEEK_SET);iRet = fread(s_uRGB, 1, imageW * imageH * 3, fp_rgb);     //--------------待优化!!!!!!!!!//---2、动态申请存放YUV的BUFFpYUVBuff = (unsigned char *)malloc(IMAGE_YUV444_SIZE(imageW, imageH)+1);if (pYUVBuff == NULL){IMAGE_ERROR("malloc pYUVBuff failed !!!!!!!!!");return ERROR;}//---3、调用对应转换函数iRet = rgb_to_yuv444p(pYUVBuff, imageW * imageH * 3, s_uRGB, imageW, imageH, YUVmode);if (iRet == ERROR){IMAGE_ERROR("rgb_to_yuv422p failed !!!!!!!!!");free(pYUVBuff);return ERROR;}//---4、将YUV数据写入文件fseek(fp_yuv, 0, SEEK_SET);fwrite(pYUVBuff, 1, imageW * imageH * 3, fp_yuv);//---5、再次读文件,验证数据/*memset(pYUVBuff, 0, imageW * imageH * 3 / 2);fseek(fp_yuv, 0, SEEK_SET);fread(pYUVBuff, 1, imageW * imageH * 3 / 2, fp_yuv);for(i = 0; i < imageW * imageH * 3 / 2 ;i++){if (i % imageW == 0)printf("\n");printf("%3d ", pYUVBuff[i]);}printf("\n");*/free(pYUVBuff);return OK;
}/**
* @brief   yuv420p 转换为 rgb888 (rgb24)
* @param   [in] fp_yuv     RGB图像文件句柄
* @param   [in] fp_rgb     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] YUV420P_MODE_E 输入图片的YUV420p的格式类型
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_yuv420p_to_rgb888(FILE *fp_yuv, FILE *fp_rgb, int imageW, int imageH, YUV420P_MODE_E YUVmode)
{unsigned char *pRGBBuff;int iRet = -1;unsigned int i = 0;if (imageW == 0 || imageH == 0){IMAGE_ERROR("imageW = 0 or imageH = 0");return ERROR;}if (fp_rgb == NULL || fp_yuv == NULL){IMAGE_ERROR("fp_rgb or fp_yuv open failed !!!!!!!");return ERROR;}//---1、获取数据  (从开始位置读全部大小写入到转换函数 yuv420p_to_rgb888() 的输入数组中)memset(s_uYUV, 0, sizeof(s_uYUV));fseek(fp_yuv, 0, SEEK_SET);iRet = fread(s_uYUV, 1, (uint32)(imageW * imageH * 3 / 2), fp_yuv);      //--------------待优化!!!!!!!!!//---2、动态申请存放RGB的BUFFpRGBBuff = (unsigned char *)malloc(imageW * imageH * 3 + 1);if (pRGBBuff == NULL){IMAGE_ERROR("malloc pRGBBuff failed !!!!!!!!!");return ERROR;}//---3、调用对应转换函数iRet = yuv420p_to_rgb888(pRGBBuff, s_uYUV, sizeof(s_uYUV), imageW, imageH, YUVmode);if (iRet == ERROR){IMAGE_ERROR("yuv420p_to_rgb888 failed !!!!!!!!!");free(pRGBBuff);return ERROR;}//---4、将RGB数据写入文件fseek(fp_rgb, 0, SEEK_SET);fwrite(pRGBBuff, 1, imageW * imageH * 3, fp_rgb);//---5、再次读文件,验证数据/*memset(pYUVBuff, 0, imageW * imageH * 3 / 2);fseek(fp_yuv, 0, SEEK_SET);fread(pYUVBuff, 1, imageW * imageH * 3 / 2, fp_yuv);for(i = 0; i < imageW * imageH * 3 / 2 ;i++){if (i % imageW == 0)printf("\n");printf("%3d ", pYUVBuff[i]);}printf("\n");*/free(pRGBBuff);return OK;
}/**
* @brief   yuv422p 转换为 rgb888 (rgb24)
* @param   [in] fp_yuv     RGB图像文件句柄
* @param   [in] fp_rgb     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] YUV422P_MODE_E 输入图片的YUV422p的格式类型
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_yuv422p_to_rgb888(FILE *fp_yuv, FILE *fp_rgb, int imageW, int imageH, YUV422P_MODE_E YUVmode)
{unsigned char *pRGBBuff;int iRet = -1;unsigned int i = 0;if (imageW == 0 || imageH == 0){IMAGE_ERROR("imageW = 0 or imageH = 0");return ERROR;}if (fp_rgb == NULL || fp_yuv == NULL){IMAGE_ERROR("fp_rgb or fp_yuv open failed !!!!!!!");return ERROR;}//---1、获取数据  (从开始位置读全部大小写入到转换函数 yuv420p_to_rgb888() 的输入数组中)memset(s_uYUV, 0, sizeof(s_uYUV));fseek(fp_yuv, 0, SEEK_SET);iRet = fread(s_uYUV, 1, imageW * imageH * 2, fp_yuv);        //--------------待优化!!!!!!!!!//---2、动态申请存放RGB的BUFFpRGBBuff = (unsigned char *)malloc(imageW * imageH * 3 + 1);if (pRGBBuff == NULL){IMAGE_ERROR("malloc pRGBBuff failed !!!!!!!!!");return ERROR;}//---3、调用对应转换函数iRet = yuv422p_to_rgb888(pRGBBuff, s_uYUV, sizeof(s_uYUV), imageW, imageH, YUVmode);if (iRet == ERROR){IMAGE_ERROR("yuv422p_to_rgb888 failed !!!!!!!!!");free(pRGBBuff);return ERROR;}//---4、将RGB数据写入文件fseek(fp_rgb, 0, SEEK_SET);fwrite(pRGBBuff, 1, imageW * imageH * 3, fp_rgb);//---5、再次读文件,验证数据/*memset(pYUVBuff, 0, imageW * imageH * 3 / 2);fseek(fp_yuv, 0, SEEK_SET);fread(pYUVBuff, 1, imageW * imageH * 3 / 2, fp_yuv);for(i = 0; i < imageW * imageH * 3 / 2 ;i++){if (i % imageW == 0)printf("\n");printf("%3d ", pYUVBuff[i]);}printf("\n");*/free(pRGBBuff);return OK;
}/**
* @brief   yuv444p 转换为 rgb888 (rgb24)
* @param   [in] fp_yuv     RGB图像文件句柄
* @param   [in] fp_rgb     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] YUV444P_MODE_E 输入图片的YUV444p的格式类型
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_yuv444p_to_rgb888(FILE *fp_yuv, FILE *fp_rgb, int imageW, int imageH, YUV444P_MODE_E YUVmode)
{unsigned char *pRGBBuff;int iRet = -1;unsigned int i = 0;if (imageW == 0 || imageH == 0){IMAGE_ERROR("imageW = 0 or imageH = 0");return ERROR;}if (fp_rgb == NULL || fp_yuv == NULL){IMAGE_ERROR("fp_rgb or fp_yuv open failed !!!!!!!");return ERROR;}//---1、获取数据  (从开始位置读全部大小写入到转换函数 yuv420p_to_rgb888() 的输入数组中)memset(s_uYUV, 0, sizeof(s_uYUV));fseek(fp_yuv, 0, SEEK_SET);iRet = fread(s_uYUV, 1, imageW * imageH * 3, fp_yuv);        //--------------待优化!!!!!!!!!//---2、动态申请存放RGB的BUFFpRGBBuff = (unsigned char *)malloc(imageW * imageH * 3 + 1);if (pRGBBuff == NULL){IMAGE_ERROR("malloc pRGBBuff failed !!!!!!!!!");return ERROR;}//---3、调用对应转换函数iRet = yuv444p_to_rgb888(pRGBBuff, s_uYUV, sizeof(s_uYUV), imageW, imageH, YUVmode);if (iRet == ERROR){IMAGE_ERROR("yuv444p_to_rgb888 failed !!!!!!!!!");free(pRGBBuff);return ERROR;}//---4、将RGB数据写入文件fseek(fp_rgb, 0, SEEK_SET);fwrite(pRGBBuff, 1, imageW * imageH * 3, fp_rgb);//---5、再次读文件,验证数据/*memset(pYUVBuff, 0, imageW * imageH * 3 / 2);fseek(fp_yuv, 0, SEEK_SET);fread(pYUVBuff, 1, imageW * imageH * 3 / 2, fp_yuv);for(i = 0; i < imageW * imageH * 3 / 2 ;i++){if (i % imageW == 0)printf("\n");printf("%3d ", pYUVBuff[i]);}printf("\n");*/free(pRGBBuff);return OK;
}

3、处理函数头文件rgbtoyuv.h

#ifndef  _RGB_TO_YUV_H
#define  _RGB_TO_YUV_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define IMAGE_W        352     //---图像宽度
#define IMAGE_H     288     //---图像高度
#define IMAGE_CHAL  3       //---通道#define ERROR -1
#define OK 0typedef unsigned char uint8_t;
typedef unsigned int  uint32;static unsigned char s_rgb[IMAGE_W][IMAGE_H][IMAGE_CHAL] = { 0 };
static unsigned char s_uRGB[IMAGE_W * IMAGE_H * IMAGE_CHAL] = { 0 };   /** <存放RGB图像数据的数组,用于RGB to YUV */
static unsigned char s_uYUV[IMAGE_W * IMAGE_H * IMAGE_CHAL] = { 0 };   /** <存放YUV图像数据的数组, 用于YUV to RGB */typedef enum
{YUV420P_I420 = 0, //I420 数据格式——YYYY U VYUV420P_YV12 = 1, //YV12 数据格式——YYYY V U
}YUV420P_MODE_E;typedef enum
{YUV422P_YU16 = 0, //YU16 数据格式——YY U VYUV422P_YV16 = 1,   //YV16 数据格式——YY V U
}YUV422P_MODE_E;typedef enum
{YUV444P_I444 = 0, //I444 数据格式——YY UU VVYUV444P_YV24 = 1, //YV24 数据格式——YY VV UU
}YUV444P_MODE_E;/**
* @brief   生成RGB24的图像
* @param   [in] fp_rgb     图像文件名句柄
* @param   [in] imageW     生成图像的宽度
* @param   [in] imageH     生成图像的高度
* @return  成功返回图像的大小
*/
int iamge_creat_rgb24(FILE *fp_rgb, int imageW, int imageH);/**
* @brief   将RGB24 图像转换 YUV420p  YUV数据(内部函数)
* @param   [in] fp_rgb     RGB图像文件句柄
* @param   [in] fp_yuv     YUV图像文件句柄s
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] mode       参考YUV420P_MODE_E 枚举变量
* @return  OK / ERROR 成功/失败
*/
int image_rgb888_to_yuv420p(FILE *fp_rgb, FILE *fp_yuv, int imageW, int imageH, YUV420P_MODE_E YUVmode);/**
* @brief   rgb888 (rgb24)    转换为yuv422p
* @param   [in] fp_rgb     RGB图像文件句柄
* @param   [in] fp_yuv     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度s
* @param   [in] YUV422P_MODE_E YUV422p的格式
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_rgb888_to_yuv422p(FILE *fp_rgb, FILE *fp_yuv, int imageW, int imageH, YUV422P_MODE_E YUVmode);/**
* @brief   rgb888 (rgb24)    转换为yuv444p
* @param   [in] fp_rgb     RGB图像文件句柄
* @param   [in] fp_yuv     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] YUV444P_MODE_E YUV444p的格式
* @return  返回转换结果 OK/ERROR  成功/失败
*/
int image_rgb888_to_yuv444p(FILE *fp_rgb, FILE *fp_yuv, int imageW, int imageH, YUV444P_MODE_E YUVmode);/**
* @brief   rgb888 (rgb24)    转换为yuv420p
* @param   [in] fp_yuv     RGB图像文件句柄
* @param   [in] fp_rgb     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] YUV420P_MODE_E 输入图片的YUV420p的格式类型
* @return  [return]OK or ERROR         返回转换结果成功 or 失败
*/
int image_yuv420p_to_rgb888(FILE *fp_yuv, FILE *fp_rgb, int imageW, int imageH, YUV420P_MODE_E YUVmode);/**
* @brief   rgb888 (rgb24)    转换为yuv422p
* @param   [in] fp_yuv     RGB图像文件句柄
* @param   [in] fp_rgb     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] YUV422P_MODE_E 输入图片的YUV422p的格式类型
* @return  [return]OK or ERROR         返回转换结果成功 or 失败
*/
int image_yuv422p_to_rgb888(FILE *fp_yuv, FILE *fp_rgb, int imageW, int imageH, YUV422P_MODE_E YUVmode);/**
* @brief   rgb888 (rgb24)    转换为yuv444p
* @param   [in] fp_yuv     RGB图像文件句柄
* @param   [in] fp_rgb     YUV图像文件句柄
* @param   [in] w          输入图像的宽度
* @param   [in] h          输入图像的高度
* @param   [in] YUV444P_MODE_E 输入图片的YUV444p的格式类型
* @return  [return]OK or ERROR         返回转换结果成功 or 失败
*/
int image_yuv444p_to_rgb888(FILE *fp_yuv, FILE *fp_rgb, int imageW, int imageH, YUV444P_MODE_E YUVmode);#endif

4、Makefile 编译规则

app_main:rgbtoyuv.o app_main.ogcc -o app_main  rgbtoyuv.o app_main.oapp_main.o:app_main.c rgbtoyuv.hgcc -c app_main.crgbtoyuv.o:rgbtoyuv.cgcc -c rgbtoyuv.cclean:rm *.yuv *.rgb app_main

执行方式

四文件在同级目录下,执行Makefile生成执行程序app_main :

make clean
make && ./app_main

执行结果

创建的RGB图像:

转换出来的YUV420_I420格式图像:

再次转换YUV —> RGB图像:

【音视频】实操YUV与RGB互转(planar模式 YUV420、YUV422、YUV444与RGB888)相关推荐

  1. 抖音短视频实操:如何写出爆款标题(下)爆款标题的五种形式

    抖音短视频实操:如何写出爆款标题(下)爆款标题的五种形式 今天我们继续来聊聊抖音的标题.上一篇关于抖音标题的分类,简单回顾一下,故事类的标题,共鸣类的标题和话题性的标题,这篇就给大家说下爆款标题的五种 ...

  2. 抖音短视频实操:矩阵号之为什么要做矩阵号和如何做矩阵号(下)

    抖音短视频实操:矩阵号之为什么要做矩阵号和如何做矩阵号(下) 前两篇讲了矩阵号的基础信息和为什么要做矩阵号,明白了矩阵号的意义,我们再来看看怎么去做这个矩阵的账号呢? 无论企业还是个人,我们都是可以做 ...

  3. 抖音短视频实操:如何选题,形成自己的垂直领域视频体系

    抖音短视频实操:如何选题,形成自己的垂直领域视频体系 前面给大家讲了账号注册和日常操作的小技巧,然后我们就可以开始发视频了,这里就涉及到我们日常的视频选题从何而来. 直接入正题,我们可以搜一下同行业的 ...

  4. 抖音短视频实操:抖音热门视频的分类特点,如何选择视频内容并创作(下)

    抖音短视频实操:抖音热门视频的分类特点,如何选择视频内容并创作(下) 前面上篇和中篇给大家聊了聊短视频的种类和怎么选择我们的视频内容,选好内容以后,就涉及到了内容创作,内容创作上我们要如何去分析.找到 ...

  5. 音视频之渲染yuv图片

    音视频之opengl绘制三角形 音视频之opengl渲染图片 音视频之渲染yuv图片 前一篇我们讨论了如何渲染一个普通图片(rgb) 现在我们来讨论如何渲染一个yuv图片. 什么是yuv我们这里有一个 ...

  6. 音视频基础知识---像素格式RGB

    音视频基础知识汇总: 音视频基础知识---协议相关RTSP RTMP HLS 音视频基础知识---封装格式 音视频基础知识---视频编码格式 音视频基础知识---音频编码格式 音视频基础知识---像素 ...

  7. YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别)

    转自:YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别!!!) - 罗引杰 - 博客园 关于写这篇文章的原因: 本人也是摸索了很长时间才弄懂其中的原理,里面涉及的知识点太多了 ...

  8. 音视频学习之-YUV裸数据

    音视频技术分层结构(雷神的图) 1 什么是yuv? YUV中,Y表示明亮度,也就是灰度值:而U,V则表示色度,用于描述影像色彩及饱和度,用于指定像素的颜色. YUV将亮度信息Y与色彩信息UV分离,没有 ...

  9. YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别!!!)

    一. 公式:基于BT.601-6 BT601 UV 的坐标图(量化后): (横坐标为u,纵坐标为v,左下角为原点) 通过坐标图我们可以看到UV并不会包含整个坐标系,而是呈一个旋转了一定角度的八边形, ...

  10. 一份风控模型性能提升秘籍奉上|附视频+实操(详版)

    最近,番茄星球课堂为大家带来了一次主题为"信贷风控拒绝演绎实战"的直播课盛宴,内容充实,干货满满! 课程分为两次专题展开,分别为<拒绝推论场景描述.方法介绍与案例分享> ...

最新文章

  1. sql优化ppt_一款跨平台免费的开源 SQL 编辑器和数据库管理器!
  2. url参数中有+、空格、=、%、、#等特殊符号的问题解决
  3. linux下怎么查看ssh的用户登录日志
  4. root用户连接mysql数据库出错 1045 access denied for user 'root'@'localhost' using password yes
  5. linux更改文件属性宁静,shell /dev/null 21 ( linux空设备文件和重定向)
  6. D3D自定义的设备丢失对象
  7. Eclipse中 Junit 正常运行完了 可是方法覆盖率全红 解决办法 (附带②EclEmma插件安装方法④覆盖率抽出与合并)
  8. 微信公众号数据2019_如何制作微信公众号图文素材 微信公众号采集器好用吗
  9. jmeter web监听结果_监听器-聚合报告监听性能测试结果
  10. mac install wget
  11. eclipse主题改变
  12. 中华石杉-- --消息队列的笔记
  13. 使用Safari只要打开echarts图表的网址会使Safari未响应
  14. UI设计理论和UI总结
  15. 闪存颗粒-2D和3D闪存之间的区别和联系
  16. 中国人民银行清算总中心CDA业务数据分析师培训正式开课
  17. RT-Thread 入门学习笔记 - 熟悉邮箱rt_mailbox的使用
  18. 一份手游代理合同,让你知道游戏代理商该干什么!
  19. 今日金融词汇---网格交易,是什么?
  20. 计算机英语项目教学法,基于项目教学法的计算机英语论文

热门文章

  1. html站点地图怎么做,如何制作网站地图,制作网站地图的步骤
  2. c语言strcmp函数使程序终止,c语言strcmp函数如何使用
  3. 网易云音乐播放器部分问题集
  4. Swift高仿iOS网易云音乐Moya+RxSwift+Kingfisher+MVC+MVVM
  5. vscode+TexLive+SumatraPDF
  6. 从刷卡到二维码再到刷脸,无现金方式如何掀起支付革命?丨Xtecher 视角
  7. matlab 异常,Matlab 2017b 异常信息。程序奔溃。
  8. 毕业设计| 语音识别智能家居制作
  9. qt linux 视频教程,详解 QT 显示视频 Linux下 Qt 和 Xv实现
  10. Matlab实现Hermite插值多项式