BMP文件格式具体解释

BMP文件格式具体解释(BMP file format)

BMP文件格式,又称为Bitmap(位图)或是DIB(Device-Independent Device,设备无关位图),是Windows系统中广泛使用的图像文件格式。由于它能够不作不论什么变换地保存图像像素域的数据。因此成为我们取得RAW数据的重要来源。Windows的图形用户界面(graphical user interfaces)也在它的内建图像子系统GDI中对BMP格式提供了支持。

以下以Notepad++为分析工具,结合Windows的位图数据结构对BMP文件格式进行一个深度的剖析。

BMP文件的数据依照从文件头開始的先后顺序分为四个部分:

?         bmp文件头(bmp file header):提供文件的格式、大小等信息

?         位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息

?         调色板(color palette):可选。如使用索引来表示图像。调色板就是索引与其相应的颜色的映射表

?         位图数据(bitmap data):就是图像数据啦^_^

以下结合Windows结构体的定义。通过一个表来分析这四个部分。

我们一般见到的图像以24位图像为主。即R、G、B三种颜色各用8个bit来表示,这样的图像我们称为真彩色。这样的情况下是不须要调色板的。也就是所位图信息头后面紧跟的就是位图数据了。因此,我们经常见到有这样一种说法:位图文件从文件头開始偏移54个字节就是位图数据了,这事实上说的是24或32位图的情况。这也就解释了我们依照这样的程序写出来的程序为什么对某些位图文件没用了。

  以下针对一幅特定的图像进行分析,来看看在位图文件里这四个数据段的排布以及组成。

我们使用的图像显演示样例如以下:

这是一幅16位的位图文件。因此它是含有调色板的。

在拉出图像数据进行分析之前,我们首先进行几个约定:

1. 在BMP文件里,假设一个数据须要用几个字节来表示的话,那么该数据的存放字节顺序为“低地址村存放低位数据。高地址存放高位数据”。如数据0x1756在内存中的存储顺序为:

这样的存储方式称为小端方式(little endian) , 与之相反的是大端方式(big endian)。对两者的使用情况有兴趣的能够深究一下,当中还是有学问的。

2.  以下所有分析均以字节为序号单位进行。

以下我们对从文件里拉出来的数据进行剖析:

一、bmp文件头
Windows为bmp文件头定义了例如以下结构体:

  

typedef struct tagBITMAPFILEHEADER 
{  
UINT16 bfType;    
DWORD bfSize; 
UINT16 bfReserved1; 
UINT16 bfReserved2; 
DWORD bfOffBits;
} BITMAPFILEHEADER;

当中:

对比文件数据我们看到:

1-2  :424dh = ‘BM‘,表示这是Windows支持的位图格式。有非常多声称开头两个字节必须为‘BM‘才是位图文件,从上表来看应为开头两个字节必须为‘BM‘才是Windows位图文件。

3-5  :00010436h = 66614 B = 65.05 kB。通过查询文件属性发现一致。

6-9  :这是两个保留段。为0。

A-D:00000436h = 1078。

即从文件头到位图数据需偏移1078字节。我们稍后将验证这个数据。

共同拥有14个字节。

二、位图信息头
相同地,Windows为位图信息头定义了例如以下结构体:

  

代码  

 

对比数据文件: 

0E-11:00000028h = 40,这就是说我这个位图信息头的大小为40个字节。

前面我们已经说过位图信息头一般有40个字节。既然是这样,为什么这里还要给一个字段来说明呢?这里涉及到一些历史,事实上位图信息头原本有非常多大小的版本号的。

我们看一下下表:

出于兼容性的考虑,大多数应用使用了旧版的位图信息头来保存文件。

而 OS/2 已经过时了,因此如今最经常使用的格式就仅有V3 header了。因此,我们在前面说位图信息头的大小为40字节。

12-15:00000100h = 256,图像宽为255像素。与文件属性一致。

16-19:00000100h = 256。图像高为255像素,与文件属性一致。这是一个正数,说明图像数据是从图像左下角到右上角排列的。

1A-1B:0001h, 该值总为1。

1C-1D:0008h = 8, 表示每一个像素占8个比特,即该图像共同拥有256种颜色。

1E-21:00000000h,BI_RGB。 说明本图像不压缩。

22-25:00000000h。图像的大小。由于使用BI_RGB,所以设置为0。

26-29:00000000h,水平分辨率。缺省。

2A-2D:00000000h,垂直分辨率。缺省。

2E-31:00000100h = 256,说明本位图实际使用的颜色索引数为256,与1C-ID得到的结论一致。

32-35:00000100h = 256,说明本位图重要的颜色索引数为256,与前面得到的结论一致。

三、调色板
以下的数据就是调色板了。前面也已经提过。调色板事实上是一张映射表,标识颜色索引號与其代表的颜色的相应关系。它在文件里的布局就像一个二维数组palette[N][4],当中N表示总的颜色索引数,每行的四个元素分别表示该索引相应的B、G、R和Alpha的值,每一个分量占一个字节。如不设透明通道时。Alpha为0。由于前面知道,本图有256个颜色索引,因此N = 256。

索引號就是所在行的行号,相应的颜色就是所在行的四个元素。

这里截取一些数据来说明:

                           

 

索引:(蓝。绿,红,Alpha)

0号:(fe,fa,fd,00)

1号:(fd,f3。fc,00)

2号:(f4,f3。fc,00)

3号:(fc。f2。f4,00)

4号:(f6,f2。f2,00)

5号:(fb。f9,f6。00) 等等。

一共同拥有256种颜色,每一个颜色占用4个字节。就是一共1024个字节,再加上前面的文件信息头和位图信息头的54个字节加起来一共是1078个字节。也就是说在位图数据出现之前一共同拥有1078个字节,与我们在文件信息头得到的信息:文件头到文图数据区的偏移为1078个字节一致!

四、位图数据

以下就是位图数据了。每一个像素占一个字节。取得这个字节后。以该字节为索引查询相应的颜色,并显示到相应的显示设备上就能够了。

注意:由于位图信息头中的图像高度是正数,所以位图数据在文件里的排列顺序是从左下角到右上角。以行为主序排列的。

也即我们见到的第一个像素60是图像最左下角的数据。第二个人像素60为图像最后一行第二列的数据。…一直到最后一行的最后一列数据,后面紧接的是倒数第二行的第一列的数据,依此类推。

假设图像是24位或是32位数据的位图的话,位图数据区就不是索引而是实际的像素值了。以下说明一下,此时位图数据区的每一个像素的RGB颜色阵列排布:

24位RGB依照BGR的顺序来存储每一个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个下一个像素,不进行交织存储。

32位数据依照BGRA的顺序存储,其余与24位位图的方式一样。

像素的排布规则与前述一致。

对齐规则

讲完了像素的排列规则以及各像素的颜色分量的排列规则,最后我们谈谈数据的对齐规则。

我们知道Windows默认的扫描的最小单位是4字节,假设数据对齐满足这个值的话对于数据的获取速度等都是有非常大的增益的。

因此,BMP图像顺应了这个要求,要求每行的数据的长度必须是4的倍数,假设不够须要进行比特填充(以0填充),这样能够达到按行的高速存取。

这时。位图数据区的大小就未必是 图片宽×每像素字节数×图片高 能表示的了,由于每行可能还须要进行比特填充。

填充后的每行的字节数为:

,当中BPP(Bits Per Pixel)为每像素的比特数。

在程序中,我们能够表示为:

int iLineByteCnt = (((m_iImageWidth * m_iBitsPerPixel) + 31) >> 5) << 2;

这样。位图数据区的大小为:

 m_iImageDataSize = iLineByteCnt * m_iImageHeight;

我们在扫描完一行数据后。也可能接下来的数据并非下一行的数据,可能须要跳过一段填充数据:

  skip = 4 - ((m_iImageWidth * m_iBitsPerPixel)>>3) & 3;

五、拾遗

至此,我们通过分析一个具体的位图文件样例具体地剖析了位图文件的组成。须要注意的是:我们讲的主要是PC机上的位图文件的构成,对于嵌入式平台,可能在调色板数据段与PC机的不同。如在嵌入式平台上常见的16位r5g6b5位图实际上採用的掩模的方式而不是索引的方式来表示图像。此时,在调色板数据段共同拥有四个部分,每一个部分为四个字节,实际表示的是彩色版规范。即:

第一个部分是红色分量的掩模

第二个部分是绿色分量的掩模

第三个部分是蓝色分量的掩模

第四个部分是Alpha分量的掩模(缺省为0)

典型的调色板规范在文件里的顺序为为:

00F8 0000 E007 0000 1F00 0000 0000 0000

当中

00F8 0000为FB00h=1111100000000000(二进制)。是蓝红分量的掩码。 
  E007 0000为 07E0h=0000011111100000(二进制)。是绿色分量的掩码。 
   1F00 0000为001Fh=0000000000011111(二进制)。是蓝色分量的掩码。 
    0000 0000设置为0。

将掩码跟像素值进行“与”运算再进行移位操作就能够得到各色分量值。看看掩码。就能够明确事实上在每一个像素值的两个字节16位中。按从高到低取5、6、5位分别就是r、g、b分量值。

取出分量值后把r、g、b值分别乘以8、4、8就能够补齐每一个分量为一个字节,再把这三个字节按BGR组合,放入存储器,就能够转换为24位标准BMP格式了。

这样我们假设在位图数据区有一个像素的数据在文件里表示为02 F1。这个数据实际上应为F102:

r = (F102 AND F800) >> 8 = F0h = 240

g= (F102 AND 07E0)>> 3 = 20h = 32 
  b=(F102 AND 001F) << 3 = 10h =16

至此我们就能够显示了。(本文结束)

參考资源:

1.      wiki百科 bmp file format

http://en.wikipedia.org/wiki/BMP_file_format

2.      gwwgle的专栏 BMP格式具体解释 http://blog.csdn.net/gwwgle/archive/2009/11/06/4775396.aspx

3.      匿名 BMP格式图像文件详析http://www.thethirdmedia.com/pc/200407/20040722117029.shtm

4.      Singler的专栏位图文件(BMP)格式分析以及程序实现http://blog.csdn.net/yyfzy/archive/2006/06/10/785945.aspx

转自:http://www.cnblogs.com/Matrix_Yao/archive/2009/12/02/1615295.html

FILE HEADER 实例图解14 bytes

typedef struct { 
/* type : Magic identifier,一般为BM(0x42,0x4d) */ 
unsigned short int type; 
unsigned int size;/* File size in bytes,所有的档案大小 */ 
unsigned short int reserved1, reserved2; /* 保留位 */ 
unsigned int offset;/* Offset to image data, bytes */ 
} FILEHEADER;

  1. type:2 bytes。一般都是‘B‘ (0x42)、‘M‘ (0x4D)
  2. size:4 bytes,记录该BMP档的大小。0x436 = 1078 bytes
  3. reserved1:保留位,2 bytes
  4. reserved2:保留位,2 bytes
  5. offset:4 bytes。0x36 = 54 bytes

INFO HEADER 实例图解40 bytes

typedef struct { 
unsigned int size;/* Info Header size in bytes */ 
int width,height;/* Width and height of image */ 
unsigned short int planes;/* Number of colour planes */ 
unsigned short int bits; /* Bits per pixel */ 
unsigned int compression; /* Compression type */ 
unsigned int imagesize; /* Image size in bytes */ 
int xresolution,yresolution; /* Pixels per meter */ 
unsigned int ncolours; /* Number of colours */ 
unsigned int importantcolours; /* Important colours */ 
} INFOHEADER;

  1. size:4 bytes,0x28 = 40 bytes。表示Info Header的大长度总共 40 bytes
  2. width:4 bytes。0x10 = 16,图像宽度为16 pixel
  3. height:4 bytes。0x10 = 16,图像高度为16 pixel
  4. planes:2 bytes,0x01 = 1。位元面数为1
  5. bits:2 bytes,0x20 = 32。每個pixel须要32bits
  6. compression:4 bytes。0代表不压缩
  7. imagesize:4 bytes。0x400 = 1024 bytes。点阵图资料大小为1024 bytes
  8. xresolution:4 bytes。水平解析度
  9. yresolution:4 bytes。垂直解析度
  10. ncolours:4 bytes,点阵图使用的调色板颜色数
  11. importantcolours:4 bytes,重要的颜色数

RAW DATA 实例图解

刚刚的File Header共14bytes,Info Header为40bytes,「imagesize」 = 1024 bytes,所以「14 + 40 + 1024 = 1078」, 即等于File Header中「size」的大小。

以下我仅仅提取部分的资料。反正所有的档案,減去Header档54位元组。剩下的就是点阵图的资料。

在Info Header中的「bits」为32 bits,故四个位元组一组。若24 bits。则三个位元组一组,样例中的长宽各为16。以「Z」字型来看。一列则为16组,即16 X 4 = 64 bytes。注意的是。图中是以A、B、C ~ …的读取顺序来讲解,但实际上程序所读取到的通常回是反过来的,即… ~ C、B、A。另外。下图是以「BGRA」排列。

时间: 2024-10-12 16:11:21

BMP文件格式具体解释的相关文章

BMP文件格式及读写

转 http://blog.csdn.net/pkueecser/article/details/5579604 http://blog.csdn.net/pkueecser/article/details/5573395 http://blog.csdn.net/holybin/article/details/25792741 ####################################################################################

bmp文件格式中rgb555与rgb888之间的转换,24位与16位位图的转换

今日,有同事问我,rgb555模式下的位图文件的格式问题,于是花了一下午的时间通过猜测与测试,分析出了如下bmp文件在rgb555模式下的文件存储规律: 1:bmp文件的文件信息头中的biBitCount数据应该为16 在rgb555模式下,一个像素占用2字节,rgb分别占用5位,另外有一位是填充位. 2:16位数据的组成如下 第一个字节:g5g4g3b7b6b5b4b3 第二个字节:0r7r6r5r4r3g7g6 其中第二个字节的左边第一位为填充位,我在实验中用0填充. 3:该16位bmp图像

PNG文件格式具体解释

PNG文件结构分析(上:了解PNG文件存储格式) 前言 我们都知道,在进行J2ME的手机应用程序开发的时候,在图片的使用上,我们能够使用PNG格式的图片(甚至于在有的手机上,我们仅仅能够使用PNG格式的图片),虽然使用图片能够为我们的应用程序添加不少亮点,然而,仅仅支持PNG格式的图片却又限制了我们进一步发挥的可能性(事实上,应该说是因为手机平台上的处理能力有限). 在MIDP2中,或者某些厂商(如NOKIA)提供的API中,提供了drawPixels/getPixels的方法,这些方法进一步提

BMP文件格式

BMP文件由文件头.位图信息头.颜色信息和图像数据4部分组成: 位图文件头结构BITMAPFILEHEADER 位图信息头结构BITMAPINFOHEADER 位图颜色表RGBQUAD 位图像素数据 1.位图文件头 位图文件头结构含有BMP文件的类型.文件大小和位图起始位置等信息.其结构定义如下: typedef struct tagBITMAPFILEHEADER { WORD bfType; //位图文件的类型,必须为BMP DWORD bfSize; //位图文件的大小,以字节为单位 WO

MP4文件格式具体解释——结构概述

MP4文件格式具体解释(ISO-14496-12/14) Author:Pirate Leo Email:[email protected] 一.基本概念 1. 文件,由很多Box和FullBox组成. 2. Box,每一个Box由Header和Data组成. 3. FullBox,是Box的扩展,Box结构的基础上在Header中添加8bits version和24bits flags. 4. Header,包括了整个Box的长度size和类型type.当size==0时,代表这是文件里最后一

北亚工程师详细解说BMP文件格式

BMP是一种与硬件设备无关的图像文件格式,使用非常广.它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BblP文件所占用的空间很大.BMP文件的图像深度可选lbit.4bit.8bit及24bit.BMP文件存储数据时,图像的扫描方式是按从左到右.从下到上的顺序. 由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式. 典型的BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件

BMP文件格式,RGB之间格式转换 碰到坑,MARK

很多人在转储bmp文件的时候,会出现各种各样的问题,特别是抓屏的时候,经常保存下来的图片 怪怪的,偏差很大!比如下面: 有时候,明明感觉自己是对的,但往往结果很让人抓狂. 这种情况一般是对bmp文件格式理解不对,或者没有透彻导致,当然至少是显示出来,所以大部分是对的,只是某些地方出错! 网上也有很多bmp文件格式,但都说得不够透彻,导致实际总要走些弯路. bmp是常见图片格式,使用非常广泛.近期在处理ui库的时候,了解下bmp格式,也发现其中一些坑,记录下. bmp格式很简单,网上搜索一堆,百科

【数字图像】BMP文件格式详解

BMP文件格式详解 ------------------------------------------------------------------------------------------------------- Lena 摘录百科:BMP是英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式,能够被多种Windows应用程序所支持. BMP文件存储的是原始的BGR数据,格式非常简单,研究数字图入门必备.因为数据没有经过任何压缩,所以BMP文件都比较大.

bmp文件格式详细解析

先区分几个概念:16色和16位色一样吗? 不一样! 颜色位数,即是用多少位字节表示的值,每一位可以表示0和1两值.通常图片的颜色深度,简称色深,就是用位数来表示的,所以,我通常会看到8位色,16位色,24位色和32位色.而我们在其它地方看到的又是16色,256色,16777216色等等,这些怎么一回事呢? 16色即代表16种颜色,256色即256种颜色,8位色就是用8个位来表示的颜色,即2的8次方,就是256色,16位色2的16次方,就是65536色,24位即16777216色,32位即4294