易码技术论坛

 找回密码
 加入易码
搜索
查看: 512367|回复: 22

[求助]谁能告诉我单色位图的结构

[复制链接]
发表于 2004-10-5 10:33:00 | 显示全部楼层
高手们告诉我一下嘛
发表于 2004-10-5 13:07:00 | 显示全部楼层
单色位图的结构你可以不要理会的……用VB的PictureBox控件读取位图之后,用Point方法逐点处理就可以了。
不过,如果你想在Lava里面直接读取,那么就得看了,好像比较复杂的说~有文件头的。
前62字节是文件头,偏移量18字节开始是宽度4字节,长度4字节。
后面的是图像数据,不过和WQX上面的是正好相反的。每字节各位数据用0表示黑,用1表示白。
 楼主| 发表于 2004-10-5 23:57:00 | 显示全部楼层
从偏移62字节后面的是图象数据
在WQX上只要按一定顺序发到图形缓冲区就可以看图了
我想知道的是头文件的具体意思
能告诉我吗?
谢谢~
发表于 2004-11-10 14:26:00 | 显示全部楼层
[转]BMP位图结构与操作
---- 一、BMP文件结构
---- 1. BMP文件组成
---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
---- 2. BMP文件头
---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。
---- 其结构定义如下:
typedef struct tagBITMAPFILEHEADER
{
WORDbfType;   // 位图文件的类型,必须为BM
DWORD   bfSize;   // 位图文件的大小,以字节为单位
WORDbfReserved1;  // 位图文件保留字,必须为0
WORDbfReserved2;  // 位图文件保留字,必须为0
DWORD   bfOffBits; // 位图数据的起始位置,以相对于位图
// 文件头的偏移量表示,以字节为单位
} BITMAPFILEHEADER;
---- 3. 位图信息头
BMP位图信息头数据用于说明位图的尺寸等信息。
typedef struct tagBITMAPINFOHEADER{
   DWORD  biSize;   // 本结构所占用字节数
   LONGbiWidth;  // 位图的宽度,以像素为单位
   LONGbiHeight; // 位图的高度,以像素为单位
   WORD   biPlanes; // 目标设备的级别,必须为1
   WORD   biBitCount// 每个像素所需的位数,必须是1(双色),
  // 4(16色),8(256色)或24(真彩色)之一
   DWORD  biCompression;   // 位图压缩类型,必须是 0(不压缩),
  // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
   DWORD  biSizeImage; // 位图的大小,以字节为单位
   LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
   LONGbiYPelsPerMeter;  // 位图垂直分辨率,每米像素数
   DWORD  biClrUsed;// 位图实际使用的颜色表中的颜色数
   DWORD  biClrImportant;// 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;
---- 4. 颜色表
---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
BYTErgbGreen;   // 绿色的亮度(值范围为0-255)
BYTErgbRed; // 红色的亮度(值范围为0-255)
BYTErgbReserved;// 保留,必须为0
} RGBQUAD;
颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
当biBitCount=1,4,8时,分别有2,16,256个表项;
当biBitCount=24时,没有颜色表项。
   位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedef struct tagBITMAPINFO {
   BITMAPINFOHEADER bmiHeader;   // 位图信息头
   RGBQUAD  bmiColors[1];  // 颜色表
} BITMAPINFO;
---- 5. 位图数据
---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是 4的倍数(即以long为单位),不足的以0填充,
一个扫描行所占的字节数计算方法: DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节数 DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
位图数据的大小(不压缩情况下): DataSize= DataSizePerLine* biHeight;
 楼主| 发表于 2004-11-27 17:54:00 | 显示全部楼层
谢谢楼上的


[此贴子已经被作者于2004-11-27 17:56:10编辑过]

发表于 2004-12-10 14:39:00 | 显示全部楼层
以下是引用QIQI在2004-10-9 22:49:50的发言:
头文件意义不大,

不过和WQX上面的是正好相反的。每字节各位数据用0表示黑,用1表示白。

这句不对,只是顺序是反的而已,参看我在BBSERS上发的SHOW BMO FILE的宏


啊……好久好久才看到这个帖子-_-b

顺序反么?意思是0表示的是白,1表示是黑?

我看看再……


看过了,BMP文件里面确实是按照0表示黑1表示白来储存的呀~可是在文曲星上面的显存里面,1表示的是黑0表示的是白。^_^bbb

难道我的Bmp文件有问题么……

[此贴子已经被作者于2004-12-10 14:55:21编辑过]

发表于 2004-12-10 18:21:00 | 显示全部楼层
http://www.emsky.net/bbs/dispbbs ... p;ID=619&page=1

我用lava写的一个直接绘制bmp图像的程序……倒过来是倒过来的,这个没错。

2色Bmp的数据究竟如何表示,建立一个全部涂黑的2色bmp看看就可以了。WinHEX打开之后,后面全部是0……

另外,不仅仅是倒过来这么简单,还比较古怪的。
这是一个全黑的2色Bmp图像,不知道QIQI说的是不是这种:

[此贴子已经被作者于2004-12-10 18:26:11编辑过]

315_5184_291.bmp
发表于 2004-12-10 21:31:00 | 显示全部楼层
记得BMP在PC中是:0是黑,1是白,而且行数据颠倒!就是第一行的数据储存在文件的最后一行!
发表于 2004-12-10 21:55:00 | 显示全部楼层
BMP在PC中是:0是黑,1是白?
不是绝对的。
如果bmp的0x36偏移处是三个0,那么0是黑,1是白。
如果bmp的0x36偏移处是三个0xff,那么1是黑,0是白。
7284_5217_2915.jpg
7284_5217_2916.jpg
7284_5217_2917.jpg
发表于 2004-12-10 22:14:00 | 显示全部楼层
哦!谢谢纠正! A   LI   A   DO
发表于 2004-12-10 22:34:00 | 显示全部楼层
那个是颜色对应表。
但是2色和24bit色,好像是不变的。
啊啊,我也没有搞清楚这部分~~再研究的说……
发表于 2004-12-10 22:38:00 | 显示全部楼层
把0x36-0x39与0x3a-0x3d的内容对调,图象就黑白颠倒了。
16bits与24bits色没有调色板。
1,4,8bits色要看调色板。
发表于 2004-12-10 22:43:00 | 显示全部楼层
哦。原来是这样的啊~~

但是,不一定是3个0x00或者3个0xff的。

二色的图像,我手头的这个,从0x36开始是04 02 04 00 FC FE FC 00

[此贴子已经被作者于2004-12-10 22:48:17编辑过]

发表于 2004-12-10 22:50:00 | 显示全部楼层
补充:
2色图不一定就是黑白。
修改0x36-0x39与0x3a-0x3d还可以做红白图,兰白图,红绿图。总之,2色图可以是任意两种颜色的组合。
如果你把0x36-0x39与0x3a-0x3d都改为0,整张图就是全黑的,这样就隐藏了图象的真实内容。
发表于 2004-12-10 22:54:00 | 显示全部楼层
理解了。
嗯,爽……
发表于 2004-12-12 11:22:00 | 显示全部楼层
实际上,BMP图像数据也不绝对是倒过来的...

当BMP文件的第0x16-0x19个字节(图像高度)为正数时,图像数据就是倒过来的。

而当图像高度为负数时,图像数据则是正常顺序。

比如0x16-0x19 = 50 00 00 00(即十进制80),这时图像数据是倒过来的。

如果改成B0 FF FF FF(即十进制-80),这时图像数据就是正常顺序,改后打开图像可以发现图像垂直翻转了。

[此贴子已经被作者于2004-12-12 11:47:22编辑过]

发表于 2004-12-12 14:19:00 | 显示全部楼层
不知道BMP的标准读取方法是怎么弄的……这么诡异。
发表于 2004-12-12 16:31:00 | 显示全部楼层
以下是引用FantasyDR在2004-12-12 14:19:24的发言:

不知道BMP的标准读取方法是怎么弄的……这么诡异。

引用《情怨》中林寒的话:老F啊,这的确异,但并非诡也!
呵呵!
发表于 2005-2-17 16:39:00 | 显示全部楼层
关于你的问题23楼最后部分有详细地说明
发表于 2005-1-7 18:58:00 | 显示全部楼层
简介
BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependent bitmap)文件格式。Windows 3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。
6.1.2 文件结构
位图文件可看成由4个部分组成:位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列,它具有如下所示的形式。
位图文件的组成
结构名称
符号

位图文件头(bitmap-file header) BITMAPFILEHEADER bmfh
位图信息头(bitmap-information header) BITMAPINFOHEADER bmih
彩色表(color table) RGBQUAD aColors[]
图象数据阵列字节 BYTE aBitmapBits[]
位图文件结构可综合在表6-01中。
表01 位图文件结构内容摘要
  偏移量    域的名称    大小    内容

 图象文件   头
0000h       文件标识    2 bytes 两字节的内容用来识别位图的类型:
‘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 Colors 1 dword 指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
调色板数据 根据BMP版本的不同而不同 Palette N * 4 byte 调色板规范。对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:  1字节用于蓝色分量
1字节用于绿色分量
1字节用于红色分量
1字节用于填充符(设置为0)

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

构件详解
1. 位图文件头
位图文件头包含有关于文件类型、文件大小、存放位置等信息,在Windows 3.0以上版本的位图文件中用BITMAPFILEHEADER结构来定义:
typedef struct tagBITMAPFILEHEADER { /* bmfh */
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
其中:
  
bfType
说明文件的类型.(该值必需是0x4D42,也就是字符'BM'。我们不需要判断OS/2的位图标识,这么做现在来看似乎已经没有什么意义了,而且如果要支持OS/2的位图,程序将变得很繁琐。所以,在此只建议你检察'BM'标识)

bfSize
说明文件的大小,用字节为单位

bfReserved1
保留,必须设置为0

bfReserved2
保留,必须设置为0

bfOffBits
说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。

2. 位图信息头
位图信息用BITMAPINFO结构来定义,它由位图信息头(bitmap-information header)和彩色表(color table)组成,前者用BITMAPINFOHEADER结构定义,后者用RGBQUAD结构定义。BITMAPINFO结构具有如下形式:
typedef struct tagBITMAPINFO { /* bmi */
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
其中:
  
bmiHeader
说明BITMAPINFOHEADER结构,其中包含了有关位图的尺寸及位格式等信息

bmiColors
说明彩色表RGBQUAD结构的阵列,其中包含索引图像的真实RGB值。

BITMAPINFOHEADER结构包含有位图文件的大小、压缩类型和颜色格式,其结构定义为:
typedef struct tagBITMAPINFOHEADER { /* bmih */
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
其中:
  
biSize
说明BITMAPINFOHEADER结构所需要的字数。注:这个值并不一定是BITMAPINFOHEADER结构的尺寸,它也可能是sizeof(BITMAPV4HEADER)的值,或是sizeof(BITMAPV5HEADER)的值。这要根据该位图文件的格式版本来决定,不过,就现在的情况来看,绝大多数的BMP图像都是BITMAPINFOHEADER结构的(可能是后两者太新的缘故吧:-)。

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

biHeight
说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是时,高度值是一个正数。(注:当高度值是一个负数时(正向图像),图像将不能被压缩(也就是说biCompression成员将不能是BI_RLE8或BI_RLE4)。

biPlanes
为目标设备说明位面数,其值将总是被设为1

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

biCompression
说明图象数据压缩的类型。其值可以是下述值之一:
BI_RGB:没有压缩;

BI_RLE8:每个象素8比特的RLE压缩编码,压缩格式由2字节组成(重复象素计数和颜色索引);

BI_RLE4:每个象素4比特的RLE压缩编码,压缩格式由2字节组成

BI_BITFIELDS:每个象素的比特由指定的掩码决定。


biSizeImage
说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0
biXPelsPerMeter
说明水平分辨率,用象素/米表示
biYPelsPerMeter
说明垂直分辨率,用象素/米表示
biClrUsed
说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)
biClrImportant
说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

现就BITMAPINFOHEADER结构作如下说明:
(1) 彩色表的定位
应用程序可使用存储在biSize成员中的信息来查找在BITMAPINFO结构中的彩色表,如下所示:
pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo->bmiHeader.biSize))
(2) biBitCount
biBitCount=1 表示位图最多有两种颜色,缺省情况下是黑色和白色,你也可以自己定义这两种颜色。图像信息头装调色板中将有两个调色板项,称为索引0和索引1。图象数据阵列中的每一位表示一个象素。如果一个位是0,显示时就使用索引0的RGB值,如果位是1,则使用索引1的RGB值。
biBitCount=4 表示位图最多有16种颜色。每个象素用4位表示,并用这4位作为彩色表的表项来查找该象素的颜色。例如,如果位图中的第一个字节为0x1F,它表示有两个象素,第一象素的颜色就在彩色表的第2表项中查找,而第二个象素的颜色就在彩色表的第16表项中查找。此时,调色板中缺省情况下会有16个RGB项。对应于索引0到索引15。
biBitCount=8 表示位图最多有256种颜色。每个象素用8位表示,并用这8位作为彩色表的表项来查找该象素的颜色。例如,如果位图中的第一个字节为0x1F,这个象素的颜色就在彩色表的第32表项中查找。此时,缺省情况下,调色板中会有256个RGB项,对应于索引0到索引255。
biBitCount=16 表示位图最多有216种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。它的情况比较复杂,当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。这种格式也被称作555 16位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码“与”上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。
biBitCount=24 表示位图最多有224种颜色。这种位图没有调色板(bmiColors成员尺寸为0),在位数组中,每3个字节代表一个象素,分别对应于颜色R、G、B。
biBitCount=32 表示位图最多有232种颜色。这种位图的结构与16位位图结构非常类似,当biCompression成员的值是BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,顺序是:最高位—保留,红8位、绿8位、蓝8位。这种格式也被成为888 32位图。如果 biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在Windows 95(or 98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF0000、0xFF00、0xFF。而在NT系统中,你只要注意使掩码之间不产生重叠就行。(注:这种图像格式比较规整,因为它是DWORD对齐的,所以在内存中进行图像处理时可进行汇编级的代码优化(简单))。
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-4-20 06:37 , Processed in 0.020559 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表