现在的位置: 首页 > 综合 > 正文

BMP位图图像格式简介

2013年11月02日 ⁄ 综合 ⁄ 共 6973字 ⁄ 字号 评论关闭

BMP位图图像格式简介

1. 文件结构

 

位图文件可看成由4个部分组成:位图文件头(bitmap-fileheader)、位图信息头(bitmap-informationheader)、彩色表(colortable)和定义位图的字节阵列,它具有如下所示的形式。

 

位图文件的组成

结构名称

符号

位图文件头(bitmap-file header)

BITMAPFILEHEADER

bmfh

位图信息头(bitmap-information header)

BITMAPINFOHEADER

bmih

彩色表(color table)

RGBQUAD

aColors[]

图象数据阵列字节

BYTE

aBitmapBits[]

 

位图文件结构可综合在表1中。

 

 

偏移量

域的名称

大小

内容

图像文件头

0000h

文件标识

2 byte

两字节的内容用来识别位图的类型:

‘BM’ : Windows 3.1x, 95, NT, …

‘BA’ :OS/2 Bitmap Array

‘CI’ :OS/2 Color Icon

‘CP’ :OS/2 Color Pointer

‘IC’ : OS/2 Icon

‘PT’ :OS/2 Pointer

注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行

0002h

File Size

1 dword

用字节表示的整个文件的大小

0006h

Reserved

1 dword

保留,必须设置为0

000Ah

Bitmap Data Offset

1 dword

从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量

图像信息头

000Eh

Bitmap Header Size

1 dword

位图信息头(Bitmap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:

28h - Windows 3.1x, 95, NT, …

0Ch - OS/2 1.x

F0h - OS/2 2.x

注:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。

0012h

Width

1 dword

位图的宽度,以象素为单位

0016h

Height

1 dword

位图的高度,以象素为单位

001Ah

Planes

1 word

位图的位面数(注:该值将总是1)

001Ch

Bits Per Pixel

1 word

每个象素的位数。

1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)

4 - 16 色位图

8 - 256 色位图

16 - 16bit 高彩色位图

24 - 24bit 真彩色位图

32 - 32bit 增强型真彩色位图

001Eh

Compression

1 dword

压缩说明:

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

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

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

3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)

0022h

Bitmap Data Size

1 dword

用字节数表示的位图数据的大小。该数必须是4的倍数

0026h

HResolution

1 dword

用象素/米表示的水平分辨率

002Ah

VResolution

1 dword

用象素/米表示的垂直分辨率

002Eh

Colors

1 dword

位图使用的颜色数。如8-比特/象素表示为100h或者 256

0032h

Important

1 dword

指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要

调色板数据

根据BMP版本的不同而不同

Palette

N * 4 byte

调色板规范。对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:

  1字节用于蓝色分量

1字节用于绿色分量

1字节用于红色分量

1字节用于填充符(设置为0)

图象数据

根据BMP版本及调色板尺寸的不同而不同

Bitmap Data

xxx bytes

该域的大小取决于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。

 

2 四个部分在位图图像数据中的相应位置,(位置偏移均以位图数据开始处为基准)

  起始位置偏移
<=
各部分数据具体存放位置
<
结束位置偏移

   第一部分,图像头:

起始位置偏移 0,

长度:0x0EH (2byte + 3 * dword = 14)

结束位置偏移:起始位置偏移 + 长度

第二部分,图像信息头:

起始位置偏移:上一部分结束位置偏移

长度:从 0x0EH 处读取到的 dword 的数据值

结束位置偏移:起始位置偏移 + 长度

 

       第三部分,调色板:

起始位置偏移:上一部分结束位置偏移

长度:从 0x0AH 处读取到的 dword 的数据值- 起始位置偏移

结束位置偏移:起始位置偏移 + 长度

 

       第四部分,位图数据:

              起始位置偏移:上一部分结束位置偏移

              长度:从 0x22H 处读取到的 dword 的数据值

              结束位置偏移:文件结束

 

3 单色位图图像数据的表示方法

   在单色位图图像中,只有两种颜色,黑色或白色,每一个像素只需要一个比特就能够完成表示,为了清楚比特0或1具体表示哪一种颜色,可以通过查询调色板。

   在单色位图图像中,调色板只包含两种颜色,每一种颜色用R G B 0 四个字节表示 (在实际的字节流中,顺序是 B G R 0)

   所以,位图图像数据中的0 代表调色板中 第一种颜色的颜色值, 1 代表调色板中 第二种颜色的颜色值。

 

4 C/C++中数据类型的长度

       byte: 1个字节, 8位(比特)

       word: 2个字节,由 unsigned short定义

       dword:4 个字节,由 unsigned long定义

 

5 根据前面的位图文件结构表,可以通过自定义数据结构 struct的方式来读取 相应的数据。

 

6 位图数据的存储方式:(自下而上,从左到右)

       扫描行是由底向上存储的,这就是说,位图数据的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素。

 

7 一行单色位图数据的存储格式规定

       每一扫描行的字节数必需是4的整倍数,当不够4的整数倍时,需要加0补齐

 

以 720 × 450 的单色位图图像为例

   水平扫描行的长度为720,则需要720比特来表示一个扫描行,即需要 720/8=90字节来表示,但是 90不是 4 的整数倍,因此需要用0补齐,直至为4的整数倍,即需要额外的2个填充字节。

   最终,长度为720的水平扫描行使用了 92 个字节来表示。

 

8 仅考虑分辨率为 256×192
128×96
两种模式

BMP文件分析(一)---单色BMP文件 收藏

最近需要用到BMP文件信息,参考网上的一些资料,把自己理解的东西整理一下。呵呵

 

以下是以单色bmp为例子分析,其中bmp中的头部8个pixel与尾部8个pixel画上了黑点

 

42 4D 3E 04 00 00 00 00  00 00 3E 00 00 00 28 00

00 00 80 00 00 00 40 00  00 00 01 00 01 00 00 00

00 00 00 04 00 00 C4 0E  00 00 C4 0E 00 00 00 00

00 00 00 00 00 00 00 00  00 00 FF FF FF 00 FF FF

FF FF FF FF FF FF FF FF  FF FF FF FF FF 00 FF FF  尾部

           ~~

.......................  .......................

.......................  .......................

FF FF FF FF FF FF FF FF  FF FF FF FF FF FF 00 FF  头部

              ~~

FF FF FF FF FF FF FF FF  FF FF FF FF FF FF

 

“~~”为头尾的8个pixel为黑点,头尾顺序反转,同一行也顺序反转

由于128÷8 = 16,所以每行就用16位来控制

 

------------------

------------------

42 4D  2 bytes 文件类型BM

3E 04 00 00   1 dword 文件大小1086

00 00 00 00   1 dword 保留,必须设置为0(include reserved1+reserved2)

3E 00 00 00   1 dword 从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量 3E(H) = 62(D)

---------------

28 00 00 00   1 dword 位图信息头(Bitmap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:28h - Windows 3.1x, 95, NT, …

80 00 00 00   1 dword 位图的宽度,以象素为单位bmp的长128

40 00 00 00   1 dword 位图的高度,以象素为单位bmp的宽64

01 00   1 word 位图的位面数(注:该值将总是1Pages =1

01 00          1 word 每个象素的位数,1 - 单色位图Colors=2(BLACK & WHITE)

00 00 00 00   1 dword 压缩说明,0 - 不压缩 (使用BI_RGB表示)

00 04 00 00   1 dword 用字节数表示的位图数据的大小。该数必须是4的倍数 1024 =128*64/8 (长×宽÷每位表示8个pixel)

C4 0E 00 00   1 dword 用象素/米表示的水平分辨率,水平3780

C4 0E 00 00   1 dword 用象素/米表示的垂直分辨率,垂直3780

00 00 00 00      1 dword 位图使用的颜色数

00 00 00 00     1 dword 指定重要的颜色数

---------------

00 00 00 00   N * 4 byte 调色板规范。对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值,根据BMP版本的不同而不同

FF FF FF 00     这里的N=2

 

从这里开始为bmp数据,可以根据偏移量得到3E(H) = 62(D)

 

-----------------------

-----------------------

数据段取值规律

每8个pixel由1个byte来控制从FF--00

FF  7F   3F   1F 0F  07  03 01  00

255 127  63  31 15  7  3 1  0

11111111 01111111 00111111 00011111 0000111100000111 00000011 00000001 00000000

由上述规律可以得到

当取出一个byte的数据要进行以下转换才知道那个pixel被画黑

1、从16进制到10进制转换

2、从10进制到2进制转换

将得到的2进制数中为0的pixel画黑

 

算法实现

1、以二进制文件打开文件

2、按照BMP文件信息和BMP图片信息开始读取,这里的长度是固定的

3、根据BMP文件信息中的数据偏移量得到,数据段的开始位置

4、读取数据信息根据每行用16位来描述以及数据反转的原因,故每次读取16个byte来进行每行的数据处理(可以使用递归)

5、用一个数组来存储bmp数据信息BMPINFO[128][64]

6、每byte都为8个pixel的信息

 

--------------------------------------------

--------------------------------------------

通用数据存储格式

1、数据是按照每一行的数据进行存储

2、根据x、y的pixel来确定

3、如果0<x<=32,则用4个bytes来存储,32<x<=64,则用8bytes来存储,以此类推a<=b*8

4、多余的bytes则为浪费的空间,例如x=33的bmp,要用8bytes来存储每行的信息,但是每行只用到5bytes,所以x的范围在很大程度上决定了bmp文件的大小

 

通用算法

1、以二进制文件打开文件

2、按照BMP文件信息和BMP图片信息开始读取,这里的长度是固定的

3、根据BMP文件信息中的数据偏移量得到,数据段的开始位置

4、根据BMP图片信息中x的pixel来取得每行需要读取的bytes

5、用一个数组来存储bmp数据信息BMPINFO[x][y]

6、每byte都为8个pixel的信息,多余部分不处理

 

 

一、这是我自己以16x16单色bmp位图格式保存的文件,用uedit打开学习它的数据格式:
 
          00   01   02   03   04  05   06   07   08   09   0a   0b   0c  0d   0e   0f      

  ---------------------------------------------------  
  00h:   42   4d   7e   00   00   00   00  00   00   00   3e   00   00   00   28  00  

  10h:   00   00   20   00   00   00  20   00   00   00   01   00   01   00  00   00  

  20h:   00   00   80   00   00   00  c4   0e   00   00   c4   0e    00  00  00   00  

  30h:   00   00   00   00   00   00  00   00   00   00   ff    ff    ff    00   ff   ff  

  40h:   00   00   ff    ff    00   00   ff    ff    00   00   ff    ff    00   00   ff   ff  

  50h:   00   00   ff    ff    00   00   ff    ff    00   00   ff    ff    00   00   ff   ff  

  60h:   00   00   ff    ff    00   00   ff    ff    00   00   ff    ff    00   00   ff   ff  

  70h:   00   00   ff    ff    00   00   ff    ff    00   00   ff    ff    00   00  

   
 
二、问题:  
  1,
按照格式,偏移0ah处的值3eh,是图像数据的偏移位置,照此去读图像数据: 

  2,
按理16x16的单色位图应该有16*16/8=32字节的图像数据,但这个文件有64个字节,
 
     
这是个全白图片,应该每行对应两字节:ffh    ffh,然实际是:ffh   ffh  00h   00h
 
  3,
发现32x32尺寸的图片是对的:每行对应四个字节,ffh   ffh   ffh   ffh(全白)
 
     
然而,48x48尺寸的图片有不对了:ffh   ffh   ffh   ffh   ffh   ffh  00h   00h,后面又
 
      "
"了两个字节的00(16x16的类似),似乎要补足4的倍数?
 
   
 
三、bmp文件头格式:  

  ----------------------------------------------------------------------- 
 
偏移       bmp  
文件头结构                   
说明  
  -----------------------------------------------------------------------  
  00h           word   bftype                       "bm"  
  02h         dword   bfsize                       
文件总长度  

  06h           word   bfreserved1             
保留:固定为

  08h           word   bfreserved2             
保留:固定为

  0eh         dword   bisize                       
实际图像数据(离头)的偏移
 
  12h         dword   biwidth                     
图像宽度  

  16h         dword   biheight                   
图像高度  

  1ah           word   biplanes                   
色平面数  

  1ch           word   bibitcount               
每个像素所占位元数 

  1eh         dword   bicompression         
压缩方式,0表示无压缩  

  22h         dword   bisizeimage             
图像(数据)的大小(字节)
 
  26h         dword   bixpelspermeter      x  
解析度(点数/)
 
  2ah         dword   biypelspermeter      y  
解析度(点数/)
 
  2eh         dword   biclrused                 
图像数据实际用到的颜色数 

  32h         dword   biclrimportant       
调色板中有多少颜色数在显示时是重要的 

   
 
四、调色板  
  1,
緊接bmp  
圖像資料頭結構之後的是調色板資料,每個顏色佔用   4  
個位元組。 
  2,
調色板顏色數量是由bmp  
圖像資料開頭結構中   biclrused  
決定,如果  biclrused  
  0,則調色板中顏色的數量是   2bibitcount  

  3,
每個顏色的   4  
個位元組依序分別代表藍色(blue)、綠色(green)、紅色(red)、保留,每個顏色的分量最小為
  0  
,最大是   255 

  4,
對於   bibitcount  >=   16   (全彩
的圖檔而言,並不包含調色盤資料。  

抱歉!评论已关闭.