【音視頻系列2】RGB24數據格式及BMP文件格式以及存儲方式


RGB24是表明圖像以RGB三原色,每個像素點3個字節表示的一種圖像存儲格式

  注意:在內存中RGB各分量的排列順序為:BGR BGR BGR 

先用ffmpeg生成一個RGB24的圖片,命令如下:

  ffmpeg -i test.jpg -pix_fmt rgb24 test.rgb

生成后下面用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);
	free(bbuf);
	fclose(rgbFp);
	fclose(rFp);
	fclose(gFp);
	fclose(bFp);
}

用YUVPlayer使用Y通道分別查看R,G,B三原色文件,如果均能顯示即表示生成沒有問題

  由此可以學習RGB三原色在文件中的存儲方式

 

RGB24轉儲為BMP文件

BMP文件格式為:

  BMP文件頭+BMP文件信息頭+RGB三原色(注意:此時存儲序列為BGRBGRBGR.....)

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.colorPlane = 1;
	bIHead.bitColor = 24;
	bIHead.realSize = size * 3;
	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文件,可以直接查看生成是否正確


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM