前言
最近在从零学习音视频,在看雷神的教学帖,雷神通过c去将RGB像素数据封装为BMP图像,在这里通过c++进行一个简单的复现。也记录一下自己的音视频之路
RGB24
首先,先了解一下RGB,RGB是一种颜色空间,它由三个颜色通道组成,即红色(R)、绿色(G)和蓝色(B)。每个通道的值可以在0到255之间取值,表示了该颜色通道在该像素中的亮度值。通过组合这三个通道的值,可以得到所有可能的颜色。至于储存格式是用的packed,也就是RGBRGBRGB,想更详细的了解可以参考这个博主的文章:RGB与YUV转换以及存储格式
RGB24格式是指一种图像存储格式,每个像素用24个比特表示,分别用8个比特表示红、绿、蓝三个颜色通道的数值。RGB24格式通常用于视频流或图像序列的传输和处理。除了RGB24格式外,还有其他的RGB格式,如RGB32、RGB565、RGB555等。这些格式的区别在于每个像素用多少比特表示,以及每个颜色通道的分辨率不同。例如,RGB32格式每个像素用32个比特表示,其中8个比特表示透明度,另外8个比特表示红、绿、蓝三个颜色通道的数值。RGB565格式每个像素用16个比特表示,其中5个比特表示红色通道,6个比特表示绿色通道,5个比特表示蓝色通道。RGB555格式也是用16个比特表示,其中5个比特表示红、绿、蓝三个颜色通道的数值,还有1个比特表示透明度。
BMP图像
BMP(Bitmap)是一种常见的图像文件格式,它是Windows操作系统中最早使用的原生位图文件格式之一。BMP图像文件以二进制形式存储,可以存储单色、16色、256色、24位色等不同颜色深度的图像,其中24位色即每个像素用24个比特表示,分别表示红、绿、蓝三个颜色通道的数值。BMP图像文件的结构比较简单,由文件头、位图信息头、调色板和像素数据组成。其中文件头包含文件类型、文件大小、保留字段等信息,位图信息头包含图像宽度、高度、位深度等信息,调色板用于存储颜色信息,像素数据则是实际的图像数据。由于BMP图像文件存储的是原始图像数据,因此文件大小相对较大,但读取速度较快,适合用于图像处理和编辑。BMP图像文件格式已被广泛应用于Windows操作系统中的各种应用程序中,如画图、Word、PowerPoint等。
代码实现
我们需要定义两个结构体一个是文件头,一个是信息头,可看这篇博客,BMP格式详解
我们首先定义BMP文件头的结构体:
// BMP文件头结构体
struct BMPFileHeader {
uint16_t type; // 文件类型,必须为"BM"
uint32_t size; // 文件大小,单位为字节
uint16_t reserved1; // 保留字段,必须为0
uint16_t reserved2; // 保留字段,必须为0
uint32_t offset; // 像素数据起始位置,单位为字节
};
BMP 文件头是 BMP 图像文件的重要组成部分,必须包含以下字段:
文件类型(type):必须为 “BM”,即 0x42,0x4D。
文件大小(size):整个 BMP 文件的大小,包括 BMP 文件头、位图信息头、调色板和像素数据等所有数据,单位为字节。
保留字段(reserved1 和 reserved2):必须为 0。
像素数据起始位置(offset):表示 BMP 文件头和位图信息头的长度,即位图数据在文件中的偏移量,单位为字节。
然后定义信息头
// BMP位图信息头结构体
struct BMPInfoHeader {
uint32_t size; // 信息头大小,必须为40
int32_t width; // 图像宽度,单位为像素
int32_t height; // 图像高度,单位为像素
uint16_t planes; // 颜色平面数,必须为1
uint16_t bit_count; // 每个像素的位数,必须为24
uint32_t compression; // 压缩方式,必须为0
uint32_t size_image; // 像素数据大小,单位为字节
int32_t x_pels_per_meter; // X方向像素数/米
int32_t y_pels_per_meter; // Y方向像素数/米
uint32_t clr_used; // 使用的颜色数,必须为0
uint32_t clr_important; // 重要的颜色数,必须为0
};
BMP 信息头一般包含以下字段:
信息头大小(size):必须为40,表示这个结构体的大小。
图像宽度(width):单位为像素。
图像高度(height):单位为像素。
颜色平面数(planes):必须为1,表示颜色平面数为1。
每个像素的位数(bit_count):必须为24,表示每个像素用24个比特存储,分别表示红、绿、蓝三个颜色通道的数值。
压缩方式(compression):必须为0,表示不压缩。
像素数据大小(size_image):单位为字节,表示实际图像数据的大小,包括填充字节。
X方向像素数/米(x_pel