目录
RGB文件与YUV文件格式
- RGB文件格式
RGB三个分量按照B、G、R的顺序储存(4:4:4)
- YUV文件格式
此次选用YUV420文件格式,每四个Y共用一组U、V分量(4:2:0)
RGB到YUV的转换公式
Y = 0.299 R + 0.587 G + 0.114 B
U = - 0.1687 R - 0.3313 G + 0.5 B + 128
V = 0.5 R - 0.4187 G - 0.0813 B + 128
c++代码实现
#include <stdio.h>
#include <cstring>
#include <cstdlib>
using namespace std;
int main(int argc, char* argv[])
{
FILE *fp = NULL;
FILE *out_yuv = NULL;
if (!(fp=fopen(argv[1], "rb")))
{
printf("输入rgb文件打开失败!\n");
}
if (!(out_yuv=fopen( argv[2], "wb") ))
{
printf("输出yuv文件打开失败!\n");
}
int w,h;
w = atoi(argv[3]);
h = atoi(argv[4]);
unsigned char* buffer = (unsigned char *)malloc(sizeof(unsigned char)*w*h * 3);
unsigned char* ybuf = (unsigned char *)malloc(sizeof(unsigned char)*w*h);
unsigned char* ubuf = (unsigned char *)malloc(sizeof(unsigned char)*w*h/4);
unsigned char* vbuf = (unsigned char *)malloc(sizeof(unsigned char)*w*h/4);
fread(buffer, sizeof(unsigned char), 3 * w * h, fp);
int uvnum=0;
for (int i = 0; i < w*h; i++)
{
ybuf[i] = 0.299 * buffer[3 * i + 2] + 0.587 * buffer[3 * i + 1] + 0.114 * buffer[3 * i];
if (ybuf[i] <= 15)
ybuf[i] = 16;
if (ybuf[i] >=236)
ybuf[i] =235;
}
for(int i = 0;i < h;i++) {
for (int j = 0; j < w; j++) {
if (i % 2 == 0 && j % 2 == 0) {
ubuf[uvnum] = -0.1684 * buffer[3 * (i * w + j) + 2] - 0.3316 * buffer[3 * (i * w + j) + 1]
+ 0.5 * buffer[3 * (i * w + j)] + 128;
if (ubuf[i] <= 15)
ubuf[i] = 16;
if (ubuf[i] >= 241)
ubuf[i] = 240;
vbuf[uvnum] = 0.5 * buffer[3 * (i * w + j) + 2] - 0.4187 * buffer[3 * (i * w + j) + 1]
- 0.0183 * buffer[3 * (i * w + j)] + 128;
if (vbuf[uvnum] <= 15)
vbuf[uvnum] = 16;
if (vbuf[uvnum] >= 241)
vbuf[uvnum] = 240;
uvnum++;
}
}
}
fwrite(ybuf, sizeof(unsigned char), w*h, out_yuv);
fwrite(ubuf, sizeof(unsigned char), w*h / 4, out_yuv);
fwrite(vbuf, sizeof(unsigned char), w*h / 4, out_yuv);
fclose(fp);
fclose(out_yuv);
free(buffer);
free(ybuf);
free(ubuf);
free(vbuf);
getchar();
return 0;
}
并设置命令行参数
结果展示