最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

BMP文件格式

IT圈 admin 22浏览 0评论

2024年9月21日发(作者:铎琬凝)

整理:太虚野老

使用工具:WinHex、Photoshop、Windows“画图”工具。

操作系统:Windows 8.1。

本文所有图片文件全部使用Windows“画图”工具转换,原始文件为“24位位图.bmp”。

第1页 共 27页

目录

一、 BMP文件结构: .............................................................................................................. 3

二、 BMP文件头:BITMAPFILEHEADER ................................................................................. 3

三、 位图信息段:BITMAPINFOHEADER ................................................................................ 5

四、 调色板 ............................................................................................................................... 7

五、 位图数据 ........................................................................................................................... 9

①、24位BMP图片: ............................................................................................................ 9

②、2色BMP图片: ............................................................................................................ 10

③、16色BMP图片: .......................................................................................................... 10

④、256色BMP图片: ........................................................................................................ 12

⑤、16位BMP图片: .......................................................................................................... 12

⑥、32位BMP图片: .......................................................................................................... 16

六、 RLE压缩 ........................................................................................................................ 18

RLE 8算法 ............................................................................................................................... 18

RLE 4算法 ............................................................................................................................... 23

第2页 共 27页

BMP文件格式

一、 BMP文件结构:

BMP(Bitmap-File)图形文件,又叫位图文件,是Windows采用的图形文件格式,在

Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各

图像绘制操作都是以BMP为基础的。一个BMP文件由四部分组成:

位图文件头

位图信息段

调色板信息(如果有的话)

位图数据

RGB像素

索引数据

一个BMP文件,可以用代码表示,如下:

typedef struct tagBITMAP_FILE{

BITMAPFILEHEADER bitmapheader; //文件头结构

BITMAPINFOHEADER bitmapinfoheader; //位图信息段结构

PALETTEENTRY palette[256]; //调色板结构

UCHAR *buffer; //UCHAR大小1字节(同BYTE), 在VC6下

} BITMAP_FILE;

信息头信息头

关于数据和BMP尺寸的详细信息

RGBQUAD

位图实际数据

二、 BMP文件头:BITMAPFILEHEADER

typedef struct tagBITMAPFILEHEADER {

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BITMAPFILEHEADER;

第3页 共 27页

bfType

bfSize

bfReserved1

bfReserved2

bfOffBits

说明文件的类型,该值必需是0x4D42,也就是字符'BM',否则表示根本

不是BMP

说明该位图文件的大小,以字节为单位

保留,必须设置为0

保留,必须设置为0

说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是

非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,

所以你可以用这个偏移值迅速的从文件中读取到位数据。

BMP文件(24位位图.bmp):

下面WinHex打开这个BMP文件:

这里:

00H – 01H: bfType:0x4D42(BM);

02H – 05H: bfSize:0X0004EA4E = 322126字节,说明这个位图文件的大小为322126

字节,与图片的“属性”→“常规”中看到的一致:

06 H– 07H: 2字节的保留字节;

08 H– 09H: 2字节的保留字节;

0A H– 0DH: bfOffBits:0X00000036 = 54字节。

第4页 共 27页

三、 位图信息段:BITMAPINFOHEADER

typedef struct tagBITMAPINFOHEADER{

DWORD biSize;

LONG biWidth;

LONG biHeight;

WORD biPlanes;

WORD biBitCount

DWORD biCompression;

DWORD biSizeImage;

LONG biXPelsPerMeter;

LONG biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

} BITMAPINFOHEADER;

biSize

biWidth

biHeight

说明BITMAPINFOHEADER结构所需要的字节数。

说明图象的宽度,以象素为单位。

说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之

外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。

如果该值是一个正数,说明图像是倒向的,即:数据的第一行其实是图像

的最后一行,如果该值是一个负数,则说明图像是正向的。大多数的BMP

文件都是倒向的位图,也就是时,高度值是一个正数。

biPlanes

biBitCount

biCompression

表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1。

说明比特数/象素,其值为1、4、8、16、24、或32。

说明图象数据压缩的类型,其中:

0 - 不压缩 (使用BI_RGB表示)。

1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示)。

2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示)。

3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)。每个象素的比特由指

定的掩码决定。

BI_JPEG:JPEG格式。

biSizeImage

用字节数表示的位图数据的大小。

biXPelsPerMeter

说明水平分辨率,用象素/米表示。

biYPelsPerMeter

说明垂直分辨率,用象素/米表示。

biClrUsed

说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所

有调色板项)。

第5页 共 27页

biClrImportant

说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

这里:

0E H– 11H:

12 H– 15H:

16H– 19H:

1AH– 1BH:

1CH– 1DH:

biSize(

位图信息段大小

)

:0X00000028 = 40字节。

biWidth (图象的宽度)

:0X000001A6 = 422

象素

biHeight (图象的高度)

:0X000000FE = 254

象素

biPlanes

: 0X0001。

biBitCount (比特数/象素)

:0X0018 = 24位。

位图类型

biBitCount=1

biBitCount=4

biBitCount=8

颜色数

2

16

256

biBitCount=16

65536

biBitCount=24

1670万

biBitCount=32

4294967296

(2的32次方)

1EH– 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有压缩)。

22H–25H:

biSizeImage (位图数据的大小)

:0X0004EA18 = 322072

字节

位图数据的大小 = 图象的宽度×(24/8)×图象的高度。

首先计算宽度的字节数:

宽度的字节数= 422 × 3 = 1266.

这里的宽度的字节数必须是4的倍数,即4字节对齐。如果不是4的倍数,则需要取4

的倍数,比如1266,则取1266+2=1268;为什么必须是4的倍数?这里涉及到一个行对

齐的问题:

由于Windows在进行行扫描的时候最小的单位为4个字节,所以当图片宽 X 每个像

素的字节数≠4的整数倍时要在每行的后面补上缺少的字节,以0填充。

位图数据的大小 = 1268 × 254 = 322072字节 = 0X0004EA18字节。

26H–29H: biXPelsPerMeter (水平分辨率):0X00001C20 = 7200象素/米。

2AH–2DH: biYPelsPerMeter (垂直分辨率):0X00001C20 = 7200象素/米。

2EH–31H: biClrUsed:0X00000000 使用所有调色板项。

32H–35H: biClrImportant:0X00000000。

使用Photoshop存储图片时,Photoshop会对图片的总长度进行4字节对齐处理。多余

部分以0填充,并将多余部分的字节数加到biSizeImage (位图数据的大小)中。

下面是同一张图片用Photoshop存储后的位图文件(Photoshop_24位位图.bmp):

文件头:

第6页 共 27页

位图数据的大小为0X0004EA18字节;

从文件头开始到实际的图象数据之间的字节的偏移量bfOffBits为0X00000036;

文件的总长度为0X0004EA18+0X00000036=0X0004EA4E;

文件的总长度4字节对齐0X0004EA4E+2=4EA50;

修改位图数据的大小0X0004EA18+2=4EA1A。

文件尾:

0004EA4CH–0004EA4DH:3037 行尾填充。

0004EA4EH–0004EA4FH:0000 文件的总长度填充。

四、 调色板

我们先来说说三元色RGB概念。

我们知道,自然界中的所有颜色都可以由红、绿、蓝(R,G,B)组合而成。有的颜色

含有红色成分多一些,如深红;有的含有红色成分少一些,如浅红。针对含有红色成分的多

少,可以分成0到255共256个等级,0级表示不含红色成分;255级表示含有100%的红

色成分。同样,绿色和蓝色也被分成256级。这种分级概念称为量化。

常见颜色的RGB组合值

颜色

绿

当一幅图中每个象素赋予不同的RGB值时,就能呈现出五彩缤纷的颜色了,这样就形

成了彩色图。

让我们举例说明什么是调色板?为什么需要调色板?

有一个长宽各为200个象素,颜色数为16色的彩色图,每一个象素都用R、G、B三个

分量表示。因为每个分量有256个级别,要用8位(bit),即一个字节(byte)来表示,所

R

255

0

0

255

255

0

255

0

128

G

0

0

255

255

0

255

255

0

128

B

0

255

0

0

255

255

255

0

128

第7页 共 27页

以每个象素需要用3个字节。整个图象要用200×200×3,约120k字节,可不是一个小数

目呀!如果我们用下面的方法,就能省的多。

因为是一个16色图,也就是说这幅图中最多只有16种颜色,我们可以用一个表:表中

的每一行记录一种颜色的R、G、B值。这样当我们表示一个象素的颜色时,只需要指出该

颜色是在第几行,即该颜色在表中的索引值。举个例子,如果表的第0行为255,0,0(红

色),那么当某个象素为红色时,只需要标明0即可。

让我们再来计算一下:16种状态可以用4位(bit)表示,所以一个象素要用半个字节。

整个图象要用200×200×0.5,约20k字节,再加上表占用的字节为3×16=48字节.整个占

用的字节数约为前面的1/6。

这张R、G、B的表,就是我们常说的调色板(Palette),另一种叫法是颜色查找表

LUT(Look Up Table),似乎更确切一些。调色板在windows里的结构定义如下:

typedef struct tagPALETTEENTRY {

BYTE peRed;

BYTE peGreen;

BYTE peBlue;

BYTE peFlags;

} PALETTEENTRY;

我们这张BMP是24位真彩色的BMP,不带调色板。所谓真彩色图(true color),就是

它的颜色数高达256×256×256种,也就是说包含我们上述提到的R、G、B颜色表示方法

中所有的颜色。真彩色图并不是说一幅图包含了所有的颜色,而是说它具有显示所有颜色的

能力,即最多可以包含所有的颜色。表示真彩色图时,每个象素直接用R、G、B三个分量

字节表示,而不采用调色板技术。原因很明显:如果用调色板,表示一个象素也要用24位,

这是因为每种颜色的索引要用24位(因为总共有256×256×256种颜色,即调色板有256

×256×256行),和直接用R,G,B三个分量表示用的字节数一样,不但没有任何便宜,还

要加上一个256×256×256×3个字节的大调色板。所以真彩色图直接用R、G、B三个分量

表示,它又叫做24位色图。

这么看来BMP文件不能一概而论了,其是否用调色板或者是RGB掩码,位图数据中的

数据的真正含义直接与biBitCount 有关,不同类型的位图,其中的设计原理也不同,下面对

此作一个对比:

位图类型

biBitCount=1

//保留,设置为0.

像素表示

每个像素用

1位调色板

索引表示

每个像素用

4位调色板

索引表示

每个像素用

8位调色板

索引表示

每个像素用

取色策略

调色板索引值,调色板项范围:0-1。

压缩类型

调色板索引值,调色板项范围:0-15。

RLE

biBitCount=4

调色板索引值,调色板项范围:0-255。

RLE

biBitCount=8

biBitCount=16

直接存储RGB分量值;最低的5位表示

BI_RGB

第8页 共 27页

16位表示 蓝色分量,中间的5位表示绿色分量,

高的5位表示红色分量,一共占用了15

位,最高的一位保留,设为0。

直接存储RGB分量值;并且原来调色板

的位置被3个DWORD变量占据,称为

BI_BITFIELDS

红、绿、蓝掩码。分别用于描述红、绿、

蓝分量在16位中所占的位置。

biBitCount=24

每个像素用

24位表示

直接存储RGB分量值;3个字节分别对

应于颜色R、G、B。

直接存储RGB分量值;32位中有24位

用于存放RGB值,顺序是:最高8位保

留,红8位、绿8位、蓝8位。

BI_RGB

BI_RGB

biBitCount=32

每个像素用

32位表示

直接存储RGB分量值;并且原来调色板

的位置被3个DWORD变量占据,称为

BI_BITFIELDS

红、绿、蓝掩码。分别用于描述红、绿、

蓝分量在24位中所占的位置。

五、 位图数据

①、24位BMP图片:

不需要调色板。

每3个字节表示一个像素,3个字节分别表示B、G、R的分量值

第一个像素2A 0E 2E : R=2E、G=0E、B=2A;

第二个像素2A 0E 2D : R=2D、G=0E、B=2A。

由于位图信息头中的图像高度是正数,所以位图数据在文件中的排列顺序是从左下角到

右上角,以行为主序排列的。

下面把“24位位图.bmp”下面第五行的前10个像素修改为红色:

从文件头开始到实际的图象数据之间的字节的偏移量bfOffBits:0X00000036=54;

填充后的宽度的字节数:1268;

第五行第一个像素起始地址:54+1268×5=6394=18FAH;

第五行第十个像素结束地址:6394+30=6424=1918H。

原像素如下:

第9页 共 27页

修改后的像素如下:

双击该图片,将图片放到最大,可以看到如下所示(修改颜色后的24位位图.bmp):

②、2色BMP图片:

表示位图最多有两种颜色,缺省情况下是黑色和白色,你也可以自己定义这两种颜色。

图像信息头调色板中将有两个调色板项,称为索引0和索引1。图象数据阵列中的每一位表

示一个象素。如果一个位是0,显示时就使用索引0的RGB值,如果位是1,则使用索引1

的RGB值。

③、16色BMP图片:

表示位图最多有16种颜色。每个象素用4位表示,并用这4位作为彩色表的表项来查

找该象素的颜色。例如,如果位图中的第一个字节为0x1F,它表示有两个象素,第一象素

的颜色就在彩色表的第2表项中查找,而第二个象素的颜色就在彩色表的第16表项中查找。

此时,调色板中缺省情况下会有16个RGB 项。对应于索引0到索引15。

使用Photoshop存储16色BMP图片的方法:

点击“图像”→“模式”→“索引颜色”

第10页 共 27页

打开“索引颜色”对话框

设置“颜色”为16。

计算16色BMP图片位图数据的大小:

12 H– 15H:

biWidth (图象的宽度)

:0X000001A6 = 422

象素

16H– 19H:

biHeight (图象的高度)

:0X000000FE = 254

象素

位图数据的大小 = 图象的宽度×(1/2)×图象的高度。这里除以2,是因为一个像素

用1/2个字节表示。

首先计算宽度的字节数:

宽度的字节数= 422 ÷2 = 211.

这里的宽度的字节数必须是4的倍数,即4字节对齐。如果不是4的倍数,则需要取4

的倍数,比如211,则取211+1=212;

第11页 共 27页

位图数据的大小 = 212× 254 = 53848字节 = 0X0000D258字节。

④、256色BMP图片:

表示位图最多有256种颜色。每个象素用8位表示,并用这8位作为彩色表的表项来查

找该象素的颜色。例如,如果位图中的第一个字节为0x1F,这个象素的颜色就在彩色表的

第32表项中查找。此时,缺省情况下,调色板中会有256个RGB项,对应于索引0到索引

255。

使用Photoshop存储256色BMP图片的方法与存储16色BMP图片的方法相同,设置“颜

色”为256。

计算256色BMP图片位图数据的大小:

12 H– 15H:

biWidth (图象的宽度)

:0X000001A6 = 422

象素

16H– 19H:

biHeight (图象的高度)

:0X000000FE = 254

象素

位图数据的大小 = 图象的宽度×图象的高度。这里一个像素用1个字节表示。

这里的宽度的字节数必须是4的倍数,即4字节对齐。如果不是4的倍数,则需要取4

的倍数,比如422,则取422+2=424;

位图数据的大小 = 424× 254 = 107696字节 = 0X0001A4B0字节。

⑤、16位BMP图片:

表示位图最多有2

16

种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,

或叫增强型16位色,或64K色。 它的情况比较复杂,当biCompression成员的值是BI_RGB

时,它没有调色板。16位中,最高的一位保留,设为0,高的5位表示红色分量,中间的5

位表示绿色分量, 低的5位表示蓝色分量,一共占用了15位。这种格式也被称作555 16

位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调

色板的位置被三个DWORD变量占据, 称为红、绿、蓝掩码。分别用于描述红、绿、蓝分

量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和

565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式

下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码"

与"上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系

统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来

是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,

它更多的被用于游戏软件)。

Windows“画图”工具没有提供16位bmp文件格式。Photoshop提供了16位bmp文

件格式。

在Photoshop中打开24位位图.bmp。点击“文件”→“存储为(A)…”,打开“存储为”

对话框,在“格式”中选择BMP,点击“保存”,打开“BMP选项”对话框:

第12页 共 27页

点击“高级模式”,打开“BMP高级模式”对话框:

在这里可以选择BMP文件的存储模式。

“X1 R5 G5 B5”模式(最高的一位保留):

选择“X1 R5 G5 B5”模式,存储为不带alpha通道的555格式

0AH– 0DH: bfOffBits:0X00000036 = 54字节。实际的图象数据开始于36H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0010 = 16位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有掩码)

第13页 共 27页

36H – 37H: 第一个像素数据为“08 A6”。最高的一位为0。

可以看到Photoshop提供的555格式,没有掩码。

“R5 G6 B5”模式:

选择“R5 G6 B5”模式,存储为565格式

0AH– 0DH: bfOffBits:0X00000046。实际的图象数据开始于46H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0010 = 16位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000003(有掩码)

36H – 45H: 红、绿、蓝掩码。最高4个字节保留,红、绿、蓝掩码分别为:0x0000F800、

0x000007E0、0x0000001F。

36H – 37H: 第一个像素数据为“11 46”。

“A1 R5 G5 B5”模式(带alpha通道的555格式):

由于24位位图没有alpha通道,所以存储“A1 R5 G5 B5”模式时,需要添加alpha通道。

在Photoshop中,点击“通道”面板下方的“创建新通道”按钮,可以添加一个alpha

通道。

Photoshop可以将16位位图的最高1位作为alpha通道。由于只有1位,所以只能存储

2级灰度的alpha通道。“1”为黑色,“0”为白色。

点击alpha通道“alpha1”

第14页 共 27页

alpha通道默认前景色为白,背景色为黑。

使用“画笔”显示前景色,将alpha通道左下角涂白。

设置了alpha通道后,在“存储为”对话框中会出现alpha通道选项。

选择“A1 R5 G5 B5”模式,存储为带alpha通道的555格式

0AH– 0DH: bfOffBits:0X00000046。实际的图象数据开始于46H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0010 = 16位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000003(有掩码)

36H – 45H: 掩码。

36H – 39H:红掩码,为0x00007C00;

第15页 共 27页

3AH – 3DH:绿掩码,为0x000003E0;

3EH – 41H:蓝掩码,为0x00001F00;

42H – 45H:alpha通道掩码,掩码为:0x00008000。

46H – 47H: 第一个像素数据为“88 A6”。88 A6 = 1110,最高位为”1“;

6EH – 6FH: 第21个像素数据为“0C C6”。88 A6 = 11,最高位为”0“。

第一行从第21个像素开始,最高位为”0“。

⑥、32位BMP图片:

表示位图最多有2

32

种颜色。这种位图的结构与16位位图结构非常类似,当

biCompression成员的值是 BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,

顺序是:红8位、绿8位、蓝8位,最低8位保留。这种格式也被成为888 32位图。如果

biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,

成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在Windows 95(or

98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF000000、0xFF0000、

0xFF00。而在NT系统中,你只要注意使掩码之间不产生重叠就行。(注:这种图像格式比较

规整,因为它是DWORD对齐的,所以在内存中进行图像处理时可进行汇编级的代码优化(简

单))。

“X8 R8 G8 B8”模式:

选择“X8 R8 G8 B8”模式,存储为不带alpha通道的888格式

0AH– 0DH: bfOffBits:0X00000046。实际的图象数据开始于46H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0020 = 32位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000003(有掩码)

36H – 45H: 红、绿、蓝掩码。最高4个字节保留,红、绿、蓝掩码分别为:0xFF000000、

0x00FF0000、0x000000FF。

36H – 37H: 第一个像素数据为“0E 2A 2E 00”。

可以看到,在“X8 R8 G8 B8”模式下,最低8位保留。

“A8 R8 G8 B8”模式

未修改alpha通道时:

0AH– 0DH: bfOffBits:0X00000036。实际的图象数据开始于36H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0020 =32位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有掩码)

36H – 39H: 第一个像素数据为“00 0E 2A 2E”。

第16页 共 27页

其中R = ”0E“、G = ”2A“、B = ”2E“;

可以看到,在“A8 R8 G8 B8”模式下,最高8位保留。

把alpha通道背景色设置为60%。

上面的框为前景色,下面的框为背景色。

修改alpha通道后:

使用“橡皮擦”显示背景色,将alpha通道左下角涂灰。

选择“A8 R8 G8 B8”模式,存储为带alpha通道的888格式

0AH– 0DH: bfOffBits:0X00000036。实际的图象数据开始于36H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0020 =32位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有掩码)

36H – 39H: 第一个像素数据为“66 0E 2A 2E”。

其中alpha通道为”66“;R = ”0E“、G = ”2A“、B = ”2E“;

7AH – 7DH: 第18个像素数据为“00 17 33 37”。其中alpha通道为”00“。

第一行从第18个像素开始,alpha通道为”00“。

第17页 共 27页

Windows应用虽然能够识别带alpha通道的“A8 R8 G8 B8”模式,但是不能显示alpha

通道的数据。

某些应用程序将白色识别为透明色。

由于32位BMP图片每个像素的最高8位保留,所以32位BMP图片实际颜色数与24

位BMP图片相同,即1670万色,而不是4294967296(2的32次方)。

六、 RLE压缩

RLE(Run Length Encoding)行程长度压缩算法(也称游程长度压缩算法),是最早

出现、也是最简单的无损数据压缩算法。

RLE只对位图数据进行压缩,不对位图文件头、位图信息段、调色板信息进行压缩。

本文只介绍Photoshop提供的RLE算法。

RLE 8算法

使用Photoshop提供的RLE算法的方法:

点击“图像”→“模式”→“索引颜色”,设置“颜色”为256;

点击“文件”→“存储为(A)…”。

文件头与位图信息段标志:

0A H–0DH: (bfOffBits)从文件头开始到实际的图象数据之间的字节的偏移量为

0X00000436。

1CH– 1DH:

biBitCount (比特数/象素)

:0X0008 = 8位(256色)。

第18页 共 27页

1EH– 21H:

biCompression (图象数据压缩的类型)

:0X00000001(

RLE 8

压缩)。

相同索引的压缩算法:

以两个字节代表一串相同像素,第一个字节代表相同像素的个数,第二个字节代表相

同像素的索引。相同像素的个数大于等于4。

如果相同像素的个数等于3,按照不同像素处理,参考识别码部分。

如果相同像素的个数小于等于2,则分别在各个相同像素的前面用“01”(一个索引)

表示。

相同索引在行首(非0索引):

压缩前:

压缩后:

相同索引在中间

如果相同索引的前面是另一串相同索引,则压缩后,把后面的压缩数据直接附加在前面

的压缩数据的后面。

压缩前:

压缩后:

相同像素的个数小于等于2:

压缩前:

压缩后:

如果相同索引的前面是另一串不同索引,参考识别码部分。

识别码:

第一个字节必须是“0x00”;第二个字节代表:

a)、00 一行图像的结束

b)、01 一幅图像的结束

c)、02 X Y 0x00 02必须位于行首。如果Y为0,X表示从行首开始索引0的个数;

第19页 共 27页

如果Y不为0,X表示从行首开始第Y+1行的索引0的个数。Y表示从行首开始索引0的

的行数。X大于等于4。如果X小于等于3,采用方案d压缩。

d)、N N个不同的像素索引的个数,N的后面是N个不同的像素索引。N大于等于3。

如果N是奇数,后面的相同索引的压缩码以识别码“0x00”开始;如果N是偶数,后

面的相同索引的压缩码直接附加到N个不同的像素索引的后面。

当方案d中的N小于等于2时,这N个像素索引分别用两个字节表示,第一个字节用

“01”(一个索引)表示,第二个字节为像素索引。此时,如果索引的后面是一串相同

索引,则压缩后,把后面的压缩数据直接附加在前面的压缩数据的后面。

识别码“0x00 00”:

压缩前:

“00 00”为行尾填充字符。

压缩后:

“00 00”为一行图像的结束的识别码。在这里可以看到,压缩后去掉了行尾填充字符。

识别码“0x00 01”:

压缩前:

“00 00”为行尾填充字符。

压缩后:

“00 01”为一幅图像的结束的识别码。

识别码“0x00 X Y”:

压缩前:

压缩前,行首索引0的个数为5,索引0所占的行数为0。

压缩后:

把第一行以及第二行前5个索引修改为0。

由bfOffBits得知第一行开始于0X00000436,行宽422(取424 = 1A8H),0X00000436

第20页 共 27页

+0X000001A8 = 0X000005DE。所以第二行开始于0X000005DE。

压缩前:

红框内的“00 00”为行尾填充字符。

压缩后:

索引0的行数为1,第二行行首索引0的个数为5。

当行首索引0的个数小于等于3时的压缩方案:

压缩前:

“00 00”表示行首索引0的个数为2.

压缩后:

第21页 共 27页

识别码“0x00 N”:

N大于等于3,并且N是奇数:

压缩前:

压缩后:

N大于等于3,并且N是偶数:

压缩前:

压缩后:

N小于等于2,位于行首:

压缩前:

压缩后:

N小于等于2,位于行中:

压缩前:

压缩后:

第22页 共 27页

相同像素的个数等于3:

压缩前:

压缩后:

第二个索引为“00”的压缩算法:

压缩前:

压缩后:

解压缩时,由识别码“00 08”判断其后是8个不同的索引号,第二个索引“00”不会

被当作识别码来处理。

RLE 4算法

RLE 4

算法与

RLE 8

算法基本相同。

文件头与位图信息段标志:

0A H–0DH: (bfOffBits)从文件头开始到实际的图象数据之间的字节的偏移量为

0X00000076。

1CH– 1DH:

biBitCount (比特数/象素)

:0X0004 = 4位(16色)。

1EH– 21H:

biCompression (图象数据压缩的类型)

:0X00000002(

RLE 4

压缩)。

相同索引的压缩算法:

以两个字节代表一串相同像素,第一个字节代表相同像素的个数,第二个字节代表相

同像素的索引。相同像素的个数大于等于8。

如果相同像素的个数等于6,按照不同像素处理,参考识别码部分。

第23页 共 27页

如果相同像素的个数小于等于4,则分别在相同像素(以字节为单位)的前面用“02”

(2个索引)表示。

相同索引在行首(非0索引)

压缩前:

压缩后:

相同像素的个数小于等于4:

压缩前:

压缩后:

相同索引在中间

如果相同索引的前面是另一串相同索引,则压缩后,把后面的压缩数据直接附加在前面

的压缩数据的后面。

压缩前:

压缩后:

如果相同索引的前面是另一串不同索引,参考识别码部分。

识别码:

第一个字节必须是“0x00”;第二个字节代表:

a)、00 一行图像的结束

b)、01 一幅图像的结束

c)、02 X Y 0x00 02必须位于行首。如果Y为0,X表示从行首开始索引0的个数;

如果Y不为0,X表示从行首开始第Y+1行的索引0的个数。Y表示从行首开始索引0的

的行数。X大于等于4。如果X小于等于3,采用方案d压缩。

d)、N N个不同的像素索引的个数,N的后面是N个不同的像素索引。N大于等于6。

如果N除以2是奇数,后面的相同索引的压缩码以识别码“0x00”开始;如果N除以

2是偶数,后面的相同索引的压缩码直接附加到N个不同的像素索引的后面。

当方案d中的N小于等于4时,这N个像素索引分别用两个字节表示,第一个字节用

“02”(两个索引)表示,第二个字节为像素索引(以字节为单位)。此时,如果索引

第24页 共 27页

的后面是一串相同索引,则压缩后,把后面的压缩数据直接附加在前面的压缩数据的后

面。

识别码“0x00 00”:

压缩前:

“00”为行尾填充字符。

压缩后:

“00 00”为一行图像的结束的识别码。在这里可以看到,压缩后去掉了行尾填充字符。

识别码“0x00 01”:

压缩前:

“00”为行尾填充字符。

压缩后:

“00 01”为一幅图像的结束的识别码。

识别码“0x00 X Y”:

压缩前(X大于等于4):

压缩前,行首索引0的个数为9,索引0所占的行数为0。

压缩后(X大于等于4):

可以看到“04”字节中的“0”也被计算在内。在后面的处理中,“04”又被作为单独

字节处理。

把第一行以及第二行前10个索引修改为0。

由bfOffBits得知第一行开始于0X00000076;

行宽422,行宽所占字节数为422÷2=211,取212(D4)。

0X00000076 +0X000000D4 = 0X0000014A。所以第二行开始于0X0000014A。

压缩前:

第25页 共 27页

红框内的“00”为行尾填充字符。

压缩后:

索引0的行数为1,第二行行首索引0的个数为10。

当行首索引0的个数小于等于3时的压缩方案:

压缩前:

“00 05”表示行首索引0的个数为3。.

压缩后:

识别码“0x00 N”:

N大于等于6,并且N除以2是奇数:

压缩前:

压缩后:

N大于等于6,并且N除以2是偶数:

压缩前:

第26页 共 27页

压缩后:

N小于等于4,位于行首:

压缩前:

压缩后:

N小于等于4,位于行中:

压缩前:

压缩后:

相同像素的个数等于6:

压缩前:

压缩后:

如果把所有索引都设置为0,则压缩图片直接以“00 01”结束:

第27页 共 27页

2024年9月21日发(作者:铎琬凝)

整理:太虚野老

使用工具:WinHex、Photoshop、Windows“画图”工具。

操作系统:Windows 8.1。

本文所有图片文件全部使用Windows“画图”工具转换,原始文件为“24位位图.bmp”。

第1页 共 27页

目录

一、 BMP文件结构: .............................................................................................................. 3

二、 BMP文件头:BITMAPFILEHEADER ................................................................................. 3

三、 位图信息段:BITMAPINFOHEADER ................................................................................ 5

四、 调色板 ............................................................................................................................... 7

五、 位图数据 ........................................................................................................................... 9

①、24位BMP图片: ............................................................................................................ 9

②、2色BMP图片: ............................................................................................................ 10

③、16色BMP图片: .......................................................................................................... 10

④、256色BMP图片: ........................................................................................................ 12

⑤、16位BMP图片: .......................................................................................................... 12

⑥、32位BMP图片: .......................................................................................................... 16

六、 RLE压缩 ........................................................................................................................ 18

RLE 8算法 ............................................................................................................................... 18

RLE 4算法 ............................................................................................................................... 23

第2页 共 27页

BMP文件格式

一、 BMP文件结构:

BMP(Bitmap-File)图形文件,又叫位图文件,是Windows采用的图形文件格式,在

Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各

图像绘制操作都是以BMP为基础的。一个BMP文件由四部分组成:

位图文件头

位图信息段

调色板信息(如果有的话)

位图数据

RGB像素

索引数据

一个BMP文件,可以用代码表示,如下:

typedef struct tagBITMAP_FILE{

BITMAPFILEHEADER bitmapheader; //文件头结构

BITMAPINFOHEADER bitmapinfoheader; //位图信息段结构

PALETTEENTRY palette[256]; //调色板结构

UCHAR *buffer; //UCHAR大小1字节(同BYTE), 在VC6下

} BITMAP_FILE;

信息头信息头

关于数据和BMP尺寸的详细信息

RGBQUAD

位图实际数据

二、 BMP文件头:BITMAPFILEHEADER

typedef struct tagBITMAPFILEHEADER {

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BITMAPFILEHEADER;

第3页 共 27页

bfType

bfSize

bfReserved1

bfReserved2

bfOffBits

说明文件的类型,该值必需是0x4D42,也就是字符'BM',否则表示根本

不是BMP

说明该位图文件的大小,以字节为单位

保留,必须设置为0

保留,必须设置为0

说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是

非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,

所以你可以用这个偏移值迅速的从文件中读取到位数据。

BMP文件(24位位图.bmp):

下面WinHex打开这个BMP文件:

这里:

00H – 01H: bfType:0x4D42(BM);

02H – 05H: bfSize:0X0004EA4E = 322126字节,说明这个位图文件的大小为322126

字节,与图片的“属性”→“常规”中看到的一致:

06 H– 07H: 2字节的保留字节;

08 H– 09H: 2字节的保留字节;

0A H– 0DH: bfOffBits:0X00000036 = 54字节。

第4页 共 27页

三、 位图信息段:BITMAPINFOHEADER

typedef struct tagBITMAPINFOHEADER{

DWORD biSize;

LONG biWidth;

LONG biHeight;

WORD biPlanes;

WORD biBitCount

DWORD biCompression;

DWORD biSizeImage;

LONG biXPelsPerMeter;

LONG biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

} BITMAPINFOHEADER;

biSize

biWidth

biHeight

说明BITMAPINFOHEADER结构所需要的字节数。

说明图象的宽度,以象素为单位。

说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之

外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。

如果该值是一个正数,说明图像是倒向的,即:数据的第一行其实是图像

的最后一行,如果该值是一个负数,则说明图像是正向的。大多数的BMP

文件都是倒向的位图,也就是时,高度值是一个正数。

biPlanes

biBitCount

biCompression

表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1。

说明比特数/象素,其值为1、4、8、16、24、或32。

说明图象数据压缩的类型,其中:

0 - 不压缩 (使用BI_RGB表示)。

1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示)。

2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示)。

3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)。每个象素的比特由指

定的掩码决定。

BI_JPEG:JPEG格式。

biSizeImage

用字节数表示的位图数据的大小。

biXPelsPerMeter

说明水平分辨率,用象素/米表示。

biYPelsPerMeter

说明垂直分辨率,用象素/米表示。

biClrUsed

说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所

有调色板项)。

第5页 共 27页

biClrImportant

说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

这里:

0E H– 11H:

12 H– 15H:

16H– 19H:

1AH– 1BH:

1CH– 1DH:

biSize(

位图信息段大小

)

:0X00000028 = 40字节。

biWidth (图象的宽度)

:0X000001A6 = 422

象素

biHeight (图象的高度)

:0X000000FE = 254

象素

biPlanes

: 0X0001。

biBitCount (比特数/象素)

:0X0018 = 24位。

位图类型

biBitCount=1

biBitCount=4

biBitCount=8

颜色数

2

16

256

biBitCount=16

65536

biBitCount=24

1670万

biBitCount=32

4294967296

(2的32次方)

1EH– 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有压缩)。

22H–25H:

biSizeImage (位图数据的大小)

:0X0004EA18 = 322072

字节

位图数据的大小 = 图象的宽度×(24/8)×图象的高度。

首先计算宽度的字节数:

宽度的字节数= 422 × 3 = 1266.

这里的宽度的字节数必须是4的倍数,即4字节对齐。如果不是4的倍数,则需要取4

的倍数,比如1266,则取1266+2=1268;为什么必须是4的倍数?这里涉及到一个行对

齐的问题:

由于Windows在进行行扫描的时候最小的单位为4个字节,所以当图片宽 X 每个像

素的字节数≠4的整数倍时要在每行的后面补上缺少的字节,以0填充。

位图数据的大小 = 1268 × 254 = 322072字节 = 0X0004EA18字节。

26H–29H: biXPelsPerMeter (水平分辨率):0X00001C20 = 7200象素/米。

2AH–2DH: biYPelsPerMeter (垂直分辨率):0X00001C20 = 7200象素/米。

2EH–31H: biClrUsed:0X00000000 使用所有调色板项。

32H–35H: biClrImportant:0X00000000。

使用Photoshop存储图片时,Photoshop会对图片的总长度进行4字节对齐处理。多余

部分以0填充,并将多余部分的字节数加到biSizeImage (位图数据的大小)中。

下面是同一张图片用Photoshop存储后的位图文件(Photoshop_24位位图.bmp):

文件头:

第6页 共 27页

位图数据的大小为0X0004EA18字节;

从文件头开始到实际的图象数据之间的字节的偏移量bfOffBits为0X00000036;

文件的总长度为0X0004EA18+0X00000036=0X0004EA4E;

文件的总长度4字节对齐0X0004EA4E+2=4EA50;

修改位图数据的大小0X0004EA18+2=4EA1A。

文件尾:

0004EA4CH–0004EA4DH:3037 行尾填充。

0004EA4EH–0004EA4FH:0000 文件的总长度填充。

四、 调色板

我们先来说说三元色RGB概念。

我们知道,自然界中的所有颜色都可以由红、绿、蓝(R,G,B)组合而成。有的颜色

含有红色成分多一些,如深红;有的含有红色成分少一些,如浅红。针对含有红色成分的多

少,可以分成0到255共256个等级,0级表示不含红色成分;255级表示含有100%的红

色成分。同样,绿色和蓝色也被分成256级。这种分级概念称为量化。

常见颜色的RGB组合值

颜色

绿

当一幅图中每个象素赋予不同的RGB值时,就能呈现出五彩缤纷的颜色了,这样就形

成了彩色图。

让我们举例说明什么是调色板?为什么需要调色板?

有一个长宽各为200个象素,颜色数为16色的彩色图,每一个象素都用R、G、B三个

分量表示。因为每个分量有256个级别,要用8位(bit),即一个字节(byte)来表示,所

R

255

0

0

255

255

0

255

0

128

G

0

0

255

255

0

255

255

0

128

B

0

255

0

0

255

255

255

0

128

第7页 共 27页

以每个象素需要用3个字节。整个图象要用200×200×3,约120k字节,可不是一个小数

目呀!如果我们用下面的方法,就能省的多。

因为是一个16色图,也就是说这幅图中最多只有16种颜色,我们可以用一个表:表中

的每一行记录一种颜色的R、G、B值。这样当我们表示一个象素的颜色时,只需要指出该

颜色是在第几行,即该颜色在表中的索引值。举个例子,如果表的第0行为255,0,0(红

色),那么当某个象素为红色时,只需要标明0即可。

让我们再来计算一下:16种状态可以用4位(bit)表示,所以一个象素要用半个字节。

整个图象要用200×200×0.5,约20k字节,再加上表占用的字节为3×16=48字节.整个占

用的字节数约为前面的1/6。

这张R、G、B的表,就是我们常说的调色板(Palette),另一种叫法是颜色查找表

LUT(Look Up Table),似乎更确切一些。调色板在windows里的结构定义如下:

typedef struct tagPALETTEENTRY {

BYTE peRed;

BYTE peGreen;

BYTE peBlue;

BYTE peFlags;

} PALETTEENTRY;

我们这张BMP是24位真彩色的BMP,不带调色板。所谓真彩色图(true color),就是

它的颜色数高达256×256×256种,也就是说包含我们上述提到的R、G、B颜色表示方法

中所有的颜色。真彩色图并不是说一幅图包含了所有的颜色,而是说它具有显示所有颜色的

能力,即最多可以包含所有的颜色。表示真彩色图时,每个象素直接用R、G、B三个分量

字节表示,而不采用调色板技术。原因很明显:如果用调色板,表示一个象素也要用24位,

这是因为每种颜色的索引要用24位(因为总共有256×256×256种颜色,即调色板有256

×256×256行),和直接用R,G,B三个分量表示用的字节数一样,不但没有任何便宜,还

要加上一个256×256×256×3个字节的大调色板。所以真彩色图直接用R、G、B三个分量

表示,它又叫做24位色图。

这么看来BMP文件不能一概而论了,其是否用调色板或者是RGB掩码,位图数据中的

数据的真正含义直接与biBitCount 有关,不同类型的位图,其中的设计原理也不同,下面对

此作一个对比:

位图类型

biBitCount=1

//保留,设置为0.

像素表示

每个像素用

1位调色板

索引表示

每个像素用

4位调色板

索引表示

每个像素用

8位调色板

索引表示

每个像素用

取色策略

调色板索引值,调色板项范围:0-1。

压缩类型

调色板索引值,调色板项范围:0-15。

RLE

biBitCount=4

调色板索引值,调色板项范围:0-255。

RLE

biBitCount=8

biBitCount=16

直接存储RGB分量值;最低的5位表示

BI_RGB

第8页 共 27页

16位表示 蓝色分量,中间的5位表示绿色分量,

高的5位表示红色分量,一共占用了15

位,最高的一位保留,设为0。

直接存储RGB分量值;并且原来调色板

的位置被3个DWORD变量占据,称为

BI_BITFIELDS

红、绿、蓝掩码。分别用于描述红、绿、

蓝分量在16位中所占的位置。

biBitCount=24

每个像素用

24位表示

直接存储RGB分量值;3个字节分别对

应于颜色R、G、B。

直接存储RGB分量值;32位中有24位

用于存放RGB值,顺序是:最高8位保

留,红8位、绿8位、蓝8位。

BI_RGB

BI_RGB

biBitCount=32

每个像素用

32位表示

直接存储RGB分量值;并且原来调色板

的位置被3个DWORD变量占据,称为

BI_BITFIELDS

红、绿、蓝掩码。分别用于描述红、绿、

蓝分量在24位中所占的位置。

五、 位图数据

①、24位BMP图片:

不需要调色板。

每3个字节表示一个像素,3个字节分别表示B、G、R的分量值

第一个像素2A 0E 2E : R=2E、G=0E、B=2A;

第二个像素2A 0E 2D : R=2D、G=0E、B=2A。

由于位图信息头中的图像高度是正数,所以位图数据在文件中的排列顺序是从左下角到

右上角,以行为主序排列的。

下面把“24位位图.bmp”下面第五行的前10个像素修改为红色:

从文件头开始到实际的图象数据之间的字节的偏移量bfOffBits:0X00000036=54;

填充后的宽度的字节数:1268;

第五行第一个像素起始地址:54+1268×5=6394=18FAH;

第五行第十个像素结束地址:6394+30=6424=1918H。

原像素如下:

第9页 共 27页

修改后的像素如下:

双击该图片,将图片放到最大,可以看到如下所示(修改颜色后的24位位图.bmp):

②、2色BMP图片:

表示位图最多有两种颜色,缺省情况下是黑色和白色,你也可以自己定义这两种颜色。

图像信息头调色板中将有两个调色板项,称为索引0和索引1。图象数据阵列中的每一位表

示一个象素。如果一个位是0,显示时就使用索引0的RGB值,如果位是1,则使用索引1

的RGB值。

③、16色BMP图片:

表示位图最多有16种颜色。每个象素用4位表示,并用这4位作为彩色表的表项来查

找该象素的颜色。例如,如果位图中的第一个字节为0x1F,它表示有两个象素,第一象素

的颜色就在彩色表的第2表项中查找,而第二个象素的颜色就在彩色表的第16表项中查找。

此时,调色板中缺省情况下会有16个RGB 项。对应于索引0到索引15。

使用Photoshop存储16色BMP图片的方法:

点击“图像”→“模式”→“索引颜色”

第10页 共 27页

打开“索引颜色”对话框

设置“颜色”为16。

计算16色BMP图片位图数据的大小:

12 H– 15H:

biWidth (图象的宽度)

:0X000001A6 = 422

象素

16H– 19H:

biHeight (图象的高度)

:0X000000FE = 254

象素

位图数据的大小 = 图象的宽度×(1/2)×图象的高度。这里除以2,是因为一个像素

用1/2个字节表示。

首先计算宽度的字节数:

宽度的字节数= 422 ÷2 = 211.

这里的宽度的字节数必须是4的倍数,即4字节对齐。如果不是4的倍数,则需要取4

的倍数,比如211,则取211+1=212;

第11页 共 27页

位图数据的大小 = 212× 254 = 53848字节 = 0X0000D258字节。

④、256色BMP图片:

表示位图最多有256种颜色。每个象素用8位表示,并用这8位作为彩色表的表项来查

找该象素的颜色。例如,如果位图中的第一个字节为0x1F,这个象素的颜色就在彩色表的

第32表项中查找。此时,缺省情况下,调色板中会有256个RGB项,对应于索引0到索引

255。

使用Photoshop存储256色BMP图片的方法与存储16色BMP图片的方法相同,设置“颜

色”为256。

计算256色BMP图片位图数据的大小:

12 H– 15H:

biWidth (图象的宽度)

:0X000001A6 = 422

象素

16H– 19H:

biHeight (图象的高度)

:0X000000FE = 254

象素

位图数据的大小 = 图象的宽度×图象的高度。这里一个像素用1个字节表示。

这里的宽度的字节数必须是4的倍数,即4字节对齐。如果不是4的倍数,则需要取4

的倍数,比如422,则取422+2=424;

位图数据的大小 = 424× 254 = 107696字节 = 0X0001A4B0字节。

⑤、16位BMP图片:

表示位图最多有2

16

种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,

或叫增强型16位色,或64K色。 它的情况比较复杂,当biCompression成员的值是BI_RGB

时,它没有调色板。16位中,最高的一位保留,设为0,高的5位表示红色分量,中间的5

位表示绿色分量, 低的5位表示蓝色分量,一共占用了15位。这种格式也被称作555 16

位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调

色板的位置被三个DWORD变量占据, 称为红、绿、蓝掩码。分别用于描述红、绿、蓝分

量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和

565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式

下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码"

与"上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系

统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来

是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,

它更多的被用于游戏软件)。

Windows“画图”工具没有提供16位bmp文件格式。Photoshop提供了16位bmp文

件格式。

在Photoshop中打开24位位图.bmp。点击“文件”→“存储为(A)…”,打开“存储为”

对话框,在“格式”中选择BMP,点击“保存”,打开“BMP选项”对话框:

第12页 共 27页

点击“高级模式”,打开“BMP高级模式”对话框:

在这里可以选择BMP文件的存储模式。

“X1 R5 G5 B5”模式(最高的一位保留):

选择“X1 R5 G5 B5”模式,存储为不带alpha通道的555格式

0AH– 0DH: bfOffBits:0X00000036 = 54字节。实际的图象数据开始于36H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0010 = 16位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有掩码)

第13页 共 27页

36H – 37H: 第一个像素数据为“08 A6”。最高的一位为0。

可以看到Photoshop提供的555格式,没有掩码。

“R5 G6 B5”模式:

选择“R5 G6 B5”模式,存储为565格式

0AH– 0DH: bfOffBits:0X00000046。实际的图象数据开始于46H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0010 = 16位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000003(有掩码)

36H – 45H: 红、绿、蓝掩码。最高4个字节保留,红、绿、蓝掩码分别为:0x0000F800、

0x000007E0、0x0000001F。

36H – 37H: 第一个像素数据为“11 46”。

“A1 R5 G5 B5”模式(带alpha通道的555格式):

由于24位位图没有alpha通道,所以存储“A1 R5 G5 B5”模式时,需要添加alpha通道。

在Photoshop中,点击“通道”面板下方的“创建新通道”按钮,可以添加一个alpha

通道。

Photoshop可以将16位位图的最高1位作为alpha通道。由于只有1位,所以只能存储

2级灰度的alpha通道。“1”为黑色,“0”为白色。

点击alpha通道“alpha1”

第14页 共 27页

alpha通道默认前景色为白,背景色为黑。

使用“画笔”显示前景色,将alpha通道左下角涂白。

设置了alpha通道后,在“存储为”对话框中会出现alpha通道选项。

选择“A1 R5 G5 B5”模式,存储为带alpha通道的555格式

0AH– 0DH: bfOffBits:0X00000046。实际的图象数据开始于46H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0010 = 16位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000003(有掩码)

36H – 45H: 掩码。

36H – 39H:红掩码,为0x00007C00;

第15页 共 27页

3AH – 3DH:绿掩码,为0x000003E0;

3EH – 41H:蓝掩码,为0x00001F00;

42H – 45H:alpha通道掩码,掩码为:0x00008000。

46H – 47H: 第一个像素数据为“88 A6”。88 A6 = 1110,最高位为”1“;

6EH – 6FH: 第21个像素数据为“0C C6”。88 A6 = 11,最高位为”0“。

第一行从第21个像素开始,最高位为”0“。

⑥、32位BMP图片:

表示位图最多有2

32

种颜色。这种位图的结构与16位位图结构非常类似,当

biCompression成员的值是 BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,

顺序是:红8位、绿8位、蓝8位,最低8位保留。这种格式也被成为888 32位图。如果

biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,

成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在Windows 95(or

98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF000000、0xFF0000、

0xFF00。而在NT系统中,你只要注意使掩码之间不产生重叠就行。(注:这种图像格式比较

规整,因为它是DWORD对齐的,所以在内存中进行图像处理时可进行汇编级的代码优化(简

单))。

“X8 R8 G8 B8”模式:

选择“X8 R8 G8 B8”模式,存储为不带alpha通道的888格式

0AH– 0DH: bfOffBits:0X00000046。实际的图象数据开始于46H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0020 = 32位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000003(有掩码)

36H – 45H: 红、绿、蓝掩码。最高4个字节保留,红、绿、蓝掩码分别为:0xFF000000、

0x00FF0000、0x000000FF。

36H – 37H: 第一个像素数据为“0E 2A 2E 00”。

可以看到,在“X8 R8 G8 B8”模式下,最低8位保留。

“A8 R8 G8 B8”模式

未修改alpha通道时:

0AH– 0DH: bfOffBits:0X00000036。实际的图象数据开始于36H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0020 =32位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有掩码)

36H – 39H: 第一个像素数据为“00 0E 2A 2E”。

第16页 共 27页

其中R = ”0E“、G = ”2A“、B = ”2E“;

可以看到,在“A8 R8 G8 B8”模式下,最高8位保留。

把alpha通道背景色设置为60%。

上面的框为前景色,下面的框为背景色。

修改alpha通道后:

使用“橡皮擦”显示背景色,将alpha通道左下角涂灰。

选择“A8 R8 G8 B8”模式,存储为带alpha通道的888格式

0AH– 0DH: bfOffBits:0X00000036。实际的图象数据开始于36H。

1CH – 1DH:

biBitCount (比特数/象素)

:0X0020 =32位。

1EH – 21H:

biCompression (图象数据压缩的类型)

:0X00000000(没有掩码)

36H – 39H: 第一个像素数据为“66 0E 2A 2E”。

其中alpha通道为”66“;R = ”0E“、G = ”2A“、B = ”2E“;

7AH – 7DH: 第18个像素数据为“00 17 33 37”。其中alpha通道为”00“。

第一行从第18个像素开始,alpha通道为”00“。

第17页 共 27页

Windows应用虽然能够识别带alpha通道的“A8 R8 G8 B8”模式,但是不能显示alpha

通道的数据。

某些应用程序将白色识别为透明色。

由于32位BMP图片每个像素的最高8位保留,所以32位BMP图片实际颜色数与24

位BMP图片相同,即1670万色,而不是4294967296(2的32次方)。

六、 RLE压缩

RLE(Run Length Encoding)行程长度压缩算法(也称游程长度压缩算法),是最早

出现、也是最简单的无损数据压缩算法。

RLE只对位图数据进行压缩,不对位图文件头、位图信息段、调色板信息进行压缩。

本文只介绍Photoshop提供的RLE算法。

RLE 8算法

使用Photoshop提供的RLE算法的方法:

点击“图像”→“模式”→“索引颜色”,设置“颜色”为256;

点击“文件”→“存储为(A)…”。

文件头与位图信息段标志:

0A H–0DH: (bfOffBits)从文件头开始到实际的图象数据之间的字节的偏移量为

0X00000436。

1CH– 1DH:

biBitCount (比特数/象素)

:0X0008 = 8位(256色)。

第18页 共 27页

1EH– 21H:

biCompression (图象数据压缩的类型)

:0X00000001(

RLE 8

压缩)。

相同索引的压缩算法:

以两个字节代表一串相同像素,第一个字节代表相同像素的个数,第二个字节代表相

同像素的索引。相同像素的个数大于等于4。

如果相同像素的个数等于3,按照不同像素处理,参考识别码部分。

如果相同像素的个数小于等于2,则分别在各个相同像素的前面用“01”(一个索引)

表示。

相同索引在行首(非0索引):

压缩前:

压缩后:

相同索引在中间

如果相同索引的前面是另一串相同索引,则压缩后,把后面的压缩数据直接附加在前面

的压缩数据的后面。

压缩前:

压缩后:

相同像素的个数小于等于2:

压缩前:

压缩后:

如果相同索引的前面是另一串不同索引,参考识别码部分。

识别码:

第一个字节必须是“0x00”;第二个字节代表:

a)、00 一行图像的结束

b)、01 一幅图像的结束

c)、02 X Y 0x00 02必须位于行首。如果Y为0,X表示从行首开始索引0的个数;

第19页 共 27页

如果Y不为0,X表示从行首开始第Y+1行的索引0的个数。Y表示从行首开始索引0的

的行数。X大于等于4。如果X小于等于3,采用方案d压缩。

d)、N N个不同的像素索引的个数,N的后面是N个不同的像素索引。N大于等于3。

如果N是奇数,后面的相同索引的压缩码以识别码“0x00”开始;如果N是偶数,后

面的相同索引的压缩码直接附加到N个不同的像素索引的后面。

当方案d中的N小于等于2时,这N个像素索引分别用两个字节表示,第一个字节用

“01”(一个索引)表示,第二个字节为像素索引。此时,如果索引的后面是一串相同

索引,则压缩后,把后面的压缩数据直接附加在前面的压缩数据的后面。

识别码“0x00 00”:

压缩前:

“00 00”为行尾填充字符。

压缩后:

“00 00”为一行图像的结束的识别码。在这里可以看到,压缩后去掉了行尾填充字符。

识别码“0x00 01”:

压缩前:

“00 00”为行尾填充字符。

压缩后:

“00 01”为一幅图像的结束的识别码。

识别码“0x00 X Y”:

压缩前:

压缩前,行首索引0的个数为5,索引0所占的行数为0。

压缩后:

把第一行以及第二行前5个索引修改为0。

由bfOffBits得知第一行开始于0X00000436,行宽422(取424 = 1A8H),0X00000436

第20页 共 27页

+0X000001A8 = 0X000005DE。所以第二行开始于0X000005DE。

压缩前:

红框内的“00 00”为行尾填充字符。

压缩后:

索引0的行数为1,第二行行首索引0的个数为5。

当行首索引0的个数小于等于3时的压缩方案:

压缩前:

“00 00”表示行首索引0的个数为2.

压缩后:

第21页 共 27页

识别码“0x00 N”:

N大于等于3,并且N是奇数:

压缩前:

压缩后:

N大于等于3,并且N是偶数:

压缩前:

压缩后:

N小于等于2,位于行首:

压缩前:

压缩后:

N小于等于2,位于行中:

压缩前:

压缩后:

第22页 共 27页

相同像素的个数等于3:

压缩前:

压缩后:

第二个索引为“00”的压缩算法:

压缩前:

压缩后:

解压缩时,由识别码“00 08”判断其后是8个不同的索引号,第二个索引“00”不会

被当作识别码来处理。

RLE 4算法

RLE 4

算法与

RLE 8

算法基本相同。

文件头与位图信息段标志:

0A H–0DH: (bfOffBits)从文件头开始到实际的图象数据之间的字节的偏移量为

0X00000076。

1CH– 1DH:

biBitCount (比特数/象素)

:0X0004 = 4位(16色)。

1EH– 21H:

biCompression (图象数据压缩的类型)

:0X00000002(

RLE 4

压缩)。

相同索引的压缩算法:

以两个字节代表一串相同像素,第一个字节代表相同像素的个数,第二个字节代表相

同像素的索引。相同像素的个数大于等于8。

如果相同像素的个数等于6,按照不同像素处理,参考识别码部分。

第23页 共 27页

如果相同像素的个数小于等于4,则分别在相同像素(以字节为单位)的前面用“02”

(2个索引)表示。

相同索引在行首(非0索引)

压缩前:

压缩后:

相同像素的个数小于等于4:

压缩前:

压缩后:

相同索引在中间

如果相同索引的前面是另一串相同索引,则压缩后,把后面的压缩数据直接附加在前面

的压缩数据的后面。

压缩前:

压缩后:

如果相同索引的前面是另一串不同索引,参考识别码部分。

识别码:

第一个字节必须是“0x00”;第二个字节代表:

a)、00 一行图像的结束

b)、01 一幅图像的结束

c)、02 X Y 0x00 02必须位于行首。如果Y为0,X表示从行首开始索引0的个数;

如果Y不为0,X表示从行首开始第Y+1行的索引0的个数。Y表示从行首开始索引0的

的行数。X大于等于4。如果X小于等于3,采用方案d压缩。

d)、N N个不同的像素索引的个数,N的后面是N个不同的像素索引。N大于等于6。

如果N除以2是奇数,后面的相同索引的压缩码以识别码“0x00”开始;如果N除以

2是偶数,后面的相同索引的压缩码直接附加到N个不同的像素索引的后面。

当方案d中的N小于等于4时,这N个像素索引分别用两个字节表示,第一个字节用

“02”(两个索引)表示,第二个字节为像素索引(以字节为单位)。此时,如果索引

第24页 共 27页

的后面是一串相同索引,则压缩后,把后面的压缩数据直接附加在前面的压缩数据的后

面。

识别码“0x00 00”:

压缩前:

“00”为行尾填充字符。

压缩后:

“00 00”为一行图像的结束的识别码。在这里可以看到,压缩后去掉了行尾填充字符。

识别码“0x00 01”:

压缩前:

“00”为行尾填充字符。

压缩后:

“00 01”为一幅图像的结束的识别码。

识别码“0x00 X Y”:

压缩前(X大于等于4):

压缩前,行首索引0的个数为9,索引0所占的行数为0。

压缩后(X大于等于4):

可以看到“04”字节中的“0”也被计算在内。在后面的处理中,“04”又被作为单独

字节处理。

把第一行以及第二行前10个索引修改为0。

由bfOffBits得知第一行开始于0X00000076;

行宽422,行宽所占字节数为422÷2=211,取212(D4)。

0X00000076 +0X000000D4 = 0X0000014A。所以第二行开始于0X0000014A。

压缩前:

第25页 共 27页

红框内的“00”为行尾填充字符。

压缩后:

索引0的行数为1,第二行行首索引0的个数为10。

当行首索引0的个数小于等于3时的压缩方案:

压缩前:

“00 05”表示行首索引0的个数为3。.

压缩后:

识别码“0x00 N”:

N大于等于6,并且N除以2是奇数:

压缩前:

压缩后:

N大于等于6,并且N除以2是偶数:

压缩前:

第26页 共 27页

压缩后:

N小于等于4,位于行首:

压缩前:

压缩后:

N小于等于4,位于行中:

压缩前:

压缩后:

相同像素的个数等于6:

压缩前:

压缩后:

如果把所有索引都设置为0,则压缩图片直接以“00 01”结束:

第27页 共 27页

发布评论

评论列表 (0)

  1. 暂无评论