【⾳视频系列2】RGB24数据格式及BMP⽂件格式以及存储⽅式RGB24是表明图像以RGB三原⾊,每个像素点3个字节表⽰的⼀种图像存储格式
  注意:在内存中RGB各分量的排列顺序为:BGR BGR BGR
先⽤ffmpeg⽣成⼀个RGB24的图⽚,命令如下:
  ffmpeg -i test.jpg -pix_fmt b
⽣成后下⾯⽤C++代码拆分RGB24的三原⾊并保存:
void read_split_rgbfile(const char* file, int width, int height, int frames) {
FILE* rgbFp = fopen(file, "rb+");
FILE* rFp = fopen("e:\\test_r.y", "wb+");
FILE* gFp = fopen("e:\\test_g.y", "wb+");
FILE* bFp = fopen("e:\\test_b.y", "wb+");
int size = width * height;
unsigned char * buf = (unsigned char*)malloc(size * 3);
unsigned char * rbuf = (unsigned char*)malloc(size);
unsigned char * gbuf = (unsigned char*)malloc(size);
unsigned char * bbuf = (unsigned char*)malloc(size);
int ridx, gidx, bidx;
ridx = gidx = bidx = 0;
for (int i = 0; i < frames; i++)
{
fread(buf, 1, size * 3, rgbFp);
for (int rgbidx = 0; rgbidx < size * 3; rgbidx = rgbidx + 3)
{
rbuf[ridx++] = buf[rgbidx];
gbuf[gidx++] = buf[rgbidx + 1];
bbuf[bidx++] = buf[rgbidx + 2];
}
fwrite(rbuf, 1, size, rFp);
fwrite(gbuf, 1, size, gFp);
fwrite(bbuf, 1, size, bFp);
}
free(buf);
free(rbuf);
free(gbuf);
fread和fwrite的区别
free(bbuf);
fclose(rgbFp);
fclose(rFp);
fclose(gFp);
fclose(bFp);
}
⽤YUVPlayer使⽤Y通道分别查看R,G,B三原⾊⽂件,如果均能显⽰即表⽰⽣成没有问题
  由此可以学习RGB三原⾊在⽂件中的存储⽅式
RGB24转储为BMP⽂件
BMP⽂件格式为:
  BMP⽂件头+BMP⽂件信息头+RGB三原⾊(注意:此时存储序列为)
BMP⽂件头如下:
typedef struct tagBITMAPFILEHEADER
{
UINT16 bfType;
DWORD bfSize;
UINT16 bfReserved1;
UINT16 bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
BMP⽂件信息头如下:
调⾊板可略
使⽤C++代码将RGB数据转储为BMP⽂件代码如下:
typedef struct
{
long imageSize;
long blank;
long startPos;
}BMPHead;
typedef struct {
long length;
long width;
long height;
unsigned short colorPlane;
unsigned short bitColor;
long zipFormat;
long realSize;
long xPels;
long yPels;
long colorUse;
long colorImportant;
}INFOHead;
void muxer_rgb24_to_bmp(const char* rgbfile, int width, int height, const char * bmpfile) { FILE* rgbFp = fopen(rgbfile, "rb+");
FILE* bmpFp = fopen(bmpfile, "wb+");
int size = width * height;
char bmpType[] = { 'B','M' };
BMPHead bHead = { 0 };
INFOHead bIHead = { 0 };
int head_length = sizeof(bmpType) + sizeof(BMPHead) + sizeof(INFOHead);
bHead.imageSize = size * 3 + head_length;
bHead.startPos = head_length;
bIHead.length = sizeof(INFOHead);
bIHead.width = width;
bIHead.height = -height; //注意此处的⾼度为负
bIHead.bitColor = 24;
fwrite(bmpType, 1, sizeof(bmpType), bmpFp);
fwrite(&bHead, 1, sizeof(BMPHead), bmpFp);
fwrite(&bIHead, 1, sizeof(INFOHead), bmpFp);
unsigned char* rgbBuf = (unsigned char*)malloc(size * 3);
fread(rgbBuf, 1, size * 3, rgbFp);
for (int i=0;i <size*3;i+=3)  //调整R和B的顺序
{
int tmp = rgbBuf[i];
rgbBuf[i] = rgbBuf[i + 2];
rgbBuf[i + 2] = tmp;
}
fwrite(rgbBuf, 1, size * 3, bmpFp);
free(rgbBuf);
fclose(bmpFp);
fclose(rgbFp);
}
 输出⽂件为BMP⽂件,可以直接查看⽣成是否正确