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页