【音视频系列2】RGB24数据格式及BMP文件格式以及存储方式
RGB24是表明图像以RGB三原色,每个像素点3个字节表示的一种图像存储格式
注意:在内存中RGB各分量的排列顺序为:BGR BGR BGR
先用ffmpeg生成一个RGB24的图片,命令如下:
ffmpeg -i test.jpg -pix_fmt rgb24 test.rgb
生成后下面用C++代码拆分RGB24的三原色并保存:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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文件头如下:
1 2 3 4 5 6 7 8 | typedef struct tagBITMAPFILEHEADER { UINT16 bfType; DWORD bfSize; UINT16 bfReserved1; UINT16 bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; |
BMP文件信息头如下:
调色板可略
使用C++代码将RGB数据转储为BMP文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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文件,可以直接查看生成是否正确
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现