BMP文件存储格式

最近公司里面有一个需要将yuv保存成bmp文件的任务,但是由于我对bmp文件存储格式不太了解,下面进行了一番搜索,实操,有了这篇文章。最近在学数字图像处理,正好里面也有,所以我感觉这篇文章应该能解决很多人对bmp文件存储格式的疑问。

BMP文件组成

bmp文件是由四部分组成的,其中第三部分位图颜色标可以是有的,也可以是没有的,在下面的内容中会解释到。
首先来看第一部分

位图文件头结构

首先先来看下位图文件头结构

typedef struct tagBITMAPFILEHEADER
{
	WORD bfType;//BM
	DWORD bfSize;//文件大小
	WORD bfReserved1;//0
	WORD bfReserved2;//0
	DWORD bfOffBits;//位图数据的起始位置
}BITMAPFILEHEADER;

首先来看这个数据结构

  • bfType两个字节,如果是BMP,那么它就会显示BM
  • bfSize四个字节,代表文件大小
  • bfReserved1和bfReserved2是保留字,默认设置为0,也是两个字节
  • bfOffBits是位图数据的起始位置,是四个字节
    所以文件头一共占用了14个字节

位图信息头结构

组成的第二部分是位图信息头,结构体如下

typedef struct tagBITMAPINFOHEADER
{
	DWORD biSize;
	LONG  biWidth;
	LONG  biHeight;
	WORD  biPlanes;
	WORD  biBitCount;//每个像素所需的位数
	DWORD biCompression;//位图压缩类型
	DWORD biSizeImage;//位图的大小
	LONG  biXpelPerMeter;//
	LONG  biYPelPerMeter;//
	DWORD biClrUsed;//颜色数
	DWORD biClrImportant;//重要的颜色数
}BITMAPINFOHEADER

biSize:代表信息头大小
biWidth:图像宽
biHeight:图像高
biPanlanes:位元面数,一般为1
biBitCount:每个像素所需要的位数
biCompression:位图压缩类型,一般为0就是不压缩
biSizeImage:位图的大小
后面16个字节默认都设置为0

位图颜色表

首先先来看下位图颜色表的结构体

typedef struct tagRGBQUAD
{
	BYTE rgbBlue;//蓝色
	BYTE rgbGreen;//绿色
	BYTE rgbRed;//红色
	BYTE rgbReserved;//0
}RGBQUAD

位图颜色表可以存在也可以不存在,要根据图像是怎么样的,在后面的例子中会提到。

位图像素数据

struct tagBITMAPINFO
{
	BITMAPINFOHEADER bmiHeader;
	RGBQUAD bmiColors[1];//颜色表
}

用实例来理解上面结构体部分

我这里有一个我保存下来的BMP文件
在这里插入图片描述
这里要用到一款工具 ultraedit。
用ue打开这张图,我们可以看一串十六进制,如下图
在这里插入图片描述通过上面的文件头,信息头等结构体来分析这段。

文件头解析

首先是文件头,我们先把它的结构体摘抄下来。

typedef struct tagBITMAPFILEHEADER
{
	WORD bfType;//BM
	DWORD bfSize;//文件大小
	WORD bfReserved1;//0
	WORD bfReserved2;//0
	DWORD bfOffBits;//位图数据的起始位置
}BITMAPFILEHEADER;

一共十四个字节,我们来看下这张1.bmp的bfType,bfType一共占2个字节,那么就是0和1,是42和4D,转换成十进制,对应的ASCII码是BM
在这里插入图片描述bfSize占4个字节,所以应该是2 3 4 5位置,那么对应的是36 EC 5E 00,由于是小端存储,所以我们得到的应该是 00 5E EC 36,转换的十进制是6,220,854,得到是文件大小的字节,字节转换成KB或者MB,自己去除1024就行,就能得到这个1.bmp的大小了。
在这里插入图片描述后面的bfReserved1和bfReserved2都是2个字节的保留字,那么一共四个字节 也就是 6 7 8 9。如下图。
在这里插入图片描述头文件最后是bfOffBits,是数据区起始位置,占4个字节,就是 a b c d ,对应的是 36 00 00 00,如下图所示。
在这里插入图片描述看到是36,那么我们可以看到 36h位置,也就是我下图中红色框部分。
在这里插入图片描述到此文件头部分已经结束。

信息头解析

先把信息头部分对应的结构体摘抄下来

typedef struct tagBITMAPINFOHEADER
{
	DWORD biSize;
	LONG  biWidth;
	LONG  biHeight;
	WORD  biPlanes;
	WORD  biBitCount;//每个像素所需的位数
	DWORD biCompression;//位图压缩类型
	DWORD biSizeImage;//位图的大小
	LONG  biXpelPerMeter;//
	LONG  biYPelPerMeter;//
	DWORD biClrUsed;//颜色数
	DWORD biClrImportant;//重要的颜色数
}BITMAPINFOHEADER

首先第一个是biSize,也就是信息头大小,从结构体可知,信息头加起来是40,所以我们应该找到biSize的大小是40,当然这是十进制的,转换成十六进制的是28。这只是我们一个推理过程,那么我实际从数据中来看,前面的文件头是14个字节了,现在到16字节,biSize是占4个字节,也就是下面图中红框部分。
在这里插入图片描述这就是信息头biSize部分。
biWidth和biHeight都占4个字节,把对应部分抄下来
biWidth:80 07 00 00 小端 就是 00 00 07 80 十进制是1920
biHeight:38 04 00 00 小端 就是 00 00 04 38 十进制是1080
所以我们知道了这张bmp图是1920*1080。
在这里插入图片描述biPlanes占2个字节,默认是1,对应下图红框部分
在这里插入图片描述biBitCount占2个字节,代表每个像素所占的位数,下图中18是十六进制,转换为十进制就是24。
在这里插入图片描述biCompression默认为0,占用4个字节。(如下图红框所示)
在这里插入图片描述后面部分四个字节代表图像大小,最后26-35可以都设置为0
在这里插入图片描述由于它是24位真彩色,所以是没有调色板的,那么从36这里,也就是4C开始都是它的位图数据区。

NOTE:关于有调色板的例子,到时候再编辑文章。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值