分析BMP图像格式文件

一、存储算法

BMP文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大很多。例如,一个800×600的24位几乎占据1.4MB空间。因此它们通常不适合在因特网或者其他低速或者有容量限制的介质上进行传输。

根据颜色深度的不同,图像上的一个像素可以用一个或者多个字节表示,它由n/8所确定(n是位深度,1字节包含8个数据位)。图片浏览器等基于字节的ASCII值计算像素的颜色,然后从调色板中读出相应的值。更为详细的信息请参阅下面关于位图文件的部分。

n位2n种颜色的包含调色板的位图近似字节数可以用下面的公式计算:
B M P 文 件 大 小 ≈ 54 + 4 ⋅ 2 n + w i d t h ⋅ h e i g h t ⋅ n 8 BMP文件大小\approx 54+4 \cdot 2^n+\frac{width\cdot height\cdot n}{8} BMP54+42n+8widthheightn其中高度(height)和宽度(width)都以像素为单位。

需要注意的是上面公式中的 54 54 54是位图文件的文件头, 4 ⋅ 2 n 4 \cdot 2^n 42n是彩色调色板的大小。 如果位图文件不包含调色板,如24位,32位位图,则位图的近似字节数可以用下面的公式计算: B M P 文 件 大 小 ≈ 54 + w i d t h ⋅ h e i g h t ⋅ n 8 BMP文件大小\approx 54+\frac{width\cdot height\cdot n}{8} BMP54+8widthheightn其中高度(height)和宽度(width)都以像素为单位。

另外需要注意的是这是一个近似值,对于n位的位图图像来说,尽管可能有最多$ 2^n$种颜色,一个特定的图像可能并不会使用这些所有的颜色。由于彩色调色板仅仅定义了图像所用的颜色,所以实际的彩色调色板将小于 4 ⋅ 2 n 4 \cdot 2^n 42n

由于存储算法本身决定的因素,根据几个图像参数的不同计算出的大小与实际的文件大小将会有一些细小的差别。

二、文件格式

位图图像文件由若干大小固定(文件头)和大小可变的结构体按一定的顺序构成。由于该文件格式几经演进,这些结构体的版本也很多。

位图文件由以下结构体依次构成:

在这里插入图片描述
2.1 位图文件头

这部分数据块位于文件开头,用于进行文件的识别。典型的应用程序会首先普通读取这部分数据以确保的确是位图文件并且没有损坏。所有的整数值都以小端序存放(即最低有效位前置)。

2.2 调色板

这部分定义了图像中所用的颜色。如上所述,位图图像一个像素接着一个像素储存,每个像素使用一个或者多个字节的值表示,所以调色板的目的就是要告诉应用程序这些值所对应的实际颜色。

典型的位图文件使用RGB彩色模型。在这种模型中,每种颜色都是由不同强度(从0到最大强度)的红色(R)、绿色(G)和蓝色(B)组成的,也就是说,每种颜色都可以使用红色、绿色和蓝色的值所定义。

在位图文件的实现中,调色板可以包含很多条目,条目个数就是图像中所使用的颜色的个数。

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

每个条目用来描述一种颜色,包含4个字节,其中三个表示蓝色、绿色和红色,第四个字节没有使用(大多数应用程序将它设为0);对于每个字节,数值0表示该颜色分量在当前的颜色中没有使用,而数值255表示这种颜色分量使用最大的强度。

2.3 像素存储

表示位图中像素的比特是以行为单位对齐存储的,每一行的大小都向上取整为4字节(32位DWORD)的倍数。如果图像的高度大于1,多个经过填充实现对齐的行就形成了像素数组。

完整存储的一行像素所需的字节数可以通过这个公式计算: R o w S i z e = [ B i t s P e r P i x e l ⋅ I m a g e W i d t h + 31 32 ] ⋅ 4 RowSize=[\frac{BitsPerPixel\cdot ImageWidth+31}{32}]\cdot 4 RowSize=[32BitsPerPixelImageWidth+31]4
其中 I m a g e W i d t h ImageWidth ImageWidth以像素为单位

2.3.1 像素数组

这部分逐个像素表示图像。每个像素使用一个或者多个字节表示。

通常,像素是从下到上、从左到右保存的。但如果使用的不是BITMAPCOREHEADER,那么未压缩的Windows位图还可以从上到下存储,此时图像高度为负值。

每一行的末尾通过填充若干个字节的数据(并不一定为0)使该行的长度为4字节的倍数。像素数组读入内存后,每一行的起始地址必须为4的倍数。这个限制仅针对内存中的像素数组,针对存储时,仅要求每一行的大小为4字节的倍数,对文件的偏移没有限制。

例如:对于24位色的位图,如果它的宽度为1像素,那么除了每一行的数据(蓝、绿、红)需要占3字节外,还会填充1字节;而如果宽为2像素,则需要2字节的填充;宽为3像素时,需要3字节填充;宽为4像素时则不需要填充。

图像相同的条件下,位图图像文件通常比使用其它压缩算法的图像文件大很多。

2.3.2 压缩

索引色图像可以使用4位或8位RLE或霍夫曼1D算法压缩。

OS/2 BITMAPCOREHEADER2 24位色图像则可以使用24位RLE算法压缩。

16位色与32位色图像始终为未压缩数据。

如果需要,任何色深的图像都可以以未压缩形式存储。

2.3.3 像素格式

无论是磁盘上的位图文件还是内存中的位图图像,像素都由一组位(英语:bit)表示。

  • 每像素占1位(色深为1位,1bpp)的格式支持2种不同颜色。像素值直接对应一个位的值,最左像素对应第一个字节的最高位。使用该位的值用来对色表的索引:为0表示色表中的第一项,为1表示色表中的第二项(即最后一项)。
  • 每像素占2位(色深为2位,2bpp)的格式支持4种不同颜色。每个字节对应4个像素,最左像素为最高的两位(仅在Windows CE中有效)。需要使用像素值来对一张含有4个颜色值的色表进行索引。
  • 每像素占4位(色深为4位,4bpp)的格式支持16种不同的颜色。每个字节对应2个像素,最左像素为最高的四位。需要使用像素值来对一张含有16个颜色值的色表进行索引。
  • 每像素占8位(色深为8位,8bpp)的格式支持256种不同的颜色。每个字节对应1个像素。需要使用像素值来对一张含有256个颜色值的色表进行索引。
  • 每像素占16位(色深为16位,16bpp)的格式支持65536种不同的颜色,每2个字节(byte)对应一个像素。该像素的不透明度(英语:alpha)、红、绿、蓝采样值即存储在该2个字节中。
  • 每像素占24位(色深为24位,24bpp)的格式支持16777216种不同的颜色,每3个字节对应一个像素。
  • 每像素占32位(色深为32位,32bpp)的格式支持4294967296种不同的颜色,每4个字节对应一个像素。

为了区分一个颜色值中的哪些位表示哪种采样值,DIB头给出了一套默认规则,同时也允许使用BITFIELDS将某组位指定为像素中的某个通道。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值