如何读写BMP图像

由于BMP格式的图像简单,读写BMP图的实现也相对容易,读写bmp图像的具体实现见Github项目:QQImageProcess,其中的Src/ImageProcess/Bmp.h和Src/ImageProcess/Bmp.cpp包含了读写BMP图像的具体实现,下面简要说一下bmp的基本原理。


BMP图像的组成

BMP图像由4个部分组成:

  1. 文件头:BITMAPFILEHEADER(14字节)
  2. 信息头:BITMAPINFOHEADER(40字节)
  3. 颜色表:RGBQUAD(8位的为1024字节)(小于24位的图有,24位没有)
  4. 图像数据

BITMAPFILEHEADER和BITMAPINFOHEADER的定义在windows和linux上略有不同,具体参考Src/Utility/BmpDefinition_Windows.h和Src/Utility/BmpDefinition_Linux.h。下面以windows为例来说明。

文件头 BITMAPFILEHEADER

typedef struct tagBITMAPFILEHEADER 
{ 
WORD  bfType; //位图文件的类型,该值必需是0x4D42,也就是字符'BM'。 
DWORD bfSize; //位图文件大小:文件头+信息头+颜色表+数据部分
WORD  bfReserved1; //保留字,为0,留做扩展,对实际的解码格式没有影响。
WORD  bfReserved2; //同上 
DWORD bfOffBits; //位图文件头到图像数据的偏移量,以字节为单位
} BITMAPFILEHEADER;
这个结构的长度是固定的,为14个字节(WORD为无符号16位整数,DWORD为无符号32位整数)。该结果体作为文件存储的时候用。

信息头BITMAPINFOHEADER

这部分告诉应用程序图像的详细信息,在屏幕上显示图像将会使用这些信息,它从文件的第15个字节开始。
typedef struct tagBITMAPINFOHEADER 
{
DWORD biSize; //BITMAPINFOHEADER结构大小,字节为单位 
LONG biWidth; //宽度(以像素为单位,不是每行字节数!!)
LONG biHeight; //高度(以像素为单位)
WORD biPlanes; //目标设备的级别,必须为1 
WORD biBitCount; //颜色深度,每个像素所需要的位数
DWORD biCompression; //位图的压缩类型
DWORD biSizeImage; //位图数据部分的大小,以字节为单位(4字节对齐)
LONG biXPelsPerMeter; //位图水平分辨率,每米像素数
LONG biYPelsPerMeter; //位图垂直分辨率,每米像素数
DWORD biClrUsed; //位图实际使用的颜色表中的颜色数
DWORD biClrImportant; //位图显示过程中重要的颜色数
} BITMAPINFOHEADER;

该结构体大小为40字节。

颜色表RGBQUAD

BMP只能存储单色(1位),16色(4位),256色(8位),和真彩色(24位)4种格式的数据,只有真彩色没有调色板(颜色表)。

8位的BMP中,每个像素的数值就是颜色表数组的下标。而24位的BMP图,每个像素的数值就是表示实际的像素值。

typedef struct tagRGBQUAD {
  BYTE    rgbBlue; 
  BYTE    rgbGreen; 
  BYTE    rgbRed; 
  BYTE    rgbReserved; 
} RGBQUAD;

图像数据

在8位BMP中,每个像素8位,存放的是颜色表的索引,24位BMP中每个像素24位,3个字节,存放原始的BGR数据,所以BMP图像是没有经过任何压缩处理的,能够完全保留原始图像的所有信息,是一种无损格式

要注意两点:

(1) 每一行的字节数必须是4的整倍数,如果不是,则需要补齐。也就是4字节对齐。
(2) bmp文件的数据从下到上,从左到右的。也就是说,从文件中最先读到的是图象最下面一行的左边第一个像素,然后是左边第二个像素……接下来是倒数第二行左边第一个像素,左边第二个像素……依次类推 ,最后得到的是最上面一行的最右一个像素。


2017-1-10 18:35:33


非常感谢您的阅读,如果您觉得这篇文章对您有帮助,欢迎扫码进行赞赏。
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值