我是靠谱客的博主 老迟到楼房,最近开发中收集的这篇文章主要介绍位图BITMAP结构,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

数字媒体对于图像的处理肯定离不开对于位图的有关处理,首先要弄清楚位图的结构才能进行下面的工作。位图(Bitmap)图像又称点阵图或光栅图,它使用我们称为像素(象素,Pixel)的一格一格的小点来描述图像.

常见的图像文件格式有:BMP、JPG(JPE,JPEG)、GIF等等。

BMP文件结构

BMP文件由4部分组成:

1.位图文件头(bitmap-file header

2.位图信息头(bitmap-information header)

3.颜色表(color table)

4.颜色点阵数据(bits data)

24位真彩色位图没有颜色表,所以只有1、2、4这三部分


位图文件头的结构定义如下:

typedef struct tagBITMAPFILEHEADER{

WORD bfType; // 位图文件的类型,必须为BM
DWORD bfSize; // 位图文件的大小,以字节为单位
WORD bfReserved1; // 位图文件保留字,必须为0
WORD bfReserved2; // 位图文件保留字,必须为0
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图
// 文件头的偏移量表示,以字节为单位
} BITMAPFILEHEADER;

位图文件头分4部分,共14字节:

名称占用空间内容实际数据
bfType2字节标识,就是“BM”二字BM
bfSize4字节整个BMP文件的大小0x50(80)
bfReserved1/24字节保留字,没用0
bfOffBits4字节偏移数,即位图文件头+位图信息头+调色板的大小0x36(54)

注意,Windows的数据是倒着念的,这是PC电脑的特色。如果一段数据为501A25 3C,倒着念就是3C 25 1A 50,即0x3C251A50。因此,如果bfSize的数据为50 00 00 00,实际上就成了0x00000050,也就是0x50。


位图信息头:

BMP位图信息头数据用于说明位图的尺寸等信息。其结构如下:

typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本结构所占用字节数
LONG biWidth; // 位图的宽度,以像素为单位
LONG biHeight; // 位图的高度,以像素为单位
WORD biPlanes; // 目标设备的级别,必须为1
WORD biBitCount// 每个像素所需的位数,必须是1(双色),
// 4(16色),8(256色)或24(真彩色)之一
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
DWORD biSizeImage; // 位图的大小,以字节为单位
LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数
LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
DWORD biClrImportant;// 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;

位图信息头共40字节:

名称占用空间内容实际数据
biSize4字节位图信息头的大小,为400x28(40)
biWidth4字节位图的宽度,单位是像素2
biHeight4字节位图的高度,单位是像素3
biPlanes2字节固定值11
biBitCount2字节每个像素的位数
1-黑白图,4-16色,8-256色,24-真彩色
0x18(24)
biCompression4字节压缩方式,BI_RGB(0)为不压缩0
biSizeImage4字节位图全部像素占用的字节数,BI_RGB时可设为00x1A
biXPelsPerMeter4字节水平分辨率(像素/米)0xB12(2834)
biYPelsPerMeter4字节垂直分辨率(像素/米)0xB12(2834)
biClrUsed4字节位图使用的颜色数
如果为0,则颜色数为2的biBitCount次方
0
biClrImportant4字节重要的颜色数,0代表所有颜色都重要0

作为真彩色位图,我们主要关心的是biWidth和biHeight这两个数值,两个数值告诉我们图像的尺寸。biSize,biPlanes,biBitCount这几个数值是固定的。想偷懒的话,其它的数值可以一律用0来填充。


颜色表

也叫做调色板,当然这里是对那些需要调色板的位图文件而言的。有些位图,如真彩色图,是不需要调色板的,BITMAPINFOHEADER后直接是位图数据。

调色板实际上是一个数组,共有biClrUsed个元素(如果该值为零,则有2biBitCount个元素)

typedef struct tagRGBQUAD {

BYTE rgbBlue;// 蓝色的亮度(值范围为0-255)
BYTE rgbGreen; // 绿色的亮度(值范围为0-255)
BYTE rgbRed; // 红色的亮度(值范围为0-255)
BYTE rgbReserved;// 保留,必须为0
} RGBQUAD;
颜色表中RGBQUAD结构数据的个数由biBitCount来确定:
当biBitCount=1,4,8时,分别有2,16,256个表项;
当biBitCount=24时,没有颜色表项。


位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息头
RGBQUAD bmiColors[1]; // 颜色表
} BITMAPINFO;


颜色点阵数据

位图全部的像素,是按照自下向上,自左向右的顺序排列的。也就是说,从文件中最先读到的是图象最下面一行的左边第一个象素,然后是左边第二个象素……接下来是倒数第二行左边第一个象素,左边第二个象素……依次类推 ,最后得到的是最上面一行的最右一个像素。

RGB数据也是倒着念的,原始数据是按B、G、R的顺序排列的。

你应该注意到图中用黑色框起来的00 00了,在每行颜色的末尾添加的两个0字节,是为了行补位。为什么要行补位呢?因为32位的Windows操作系统处理4个字节(32位)的速度比较快,所以BMP的每一行颜色占用的字节数规定为4的整数倍。MyBmp.bmp中一行颜色有两个像素,共占用6字节,如果要补齐4*2=8字节,就要再加两个0字节。

行补位的公式为:widthBytes = (width*biBitCount+31)/32*4

举一个例子,对于2色图,如果图象宽是31,则每一行需要31位存储,合3个字节加7位,因为字节数必须是4的整倍数,所以应该是4,而此时的Width=31,biBitCount=1,widthbytes=4,和我们设想的一样。再举一个256色的例子,如果图象宽是31,则每一行需要31个字节存储,因为字节数必须是4的整倍数,所以应该是32,而此时的Width=31,biBitCount=8,widthbytes=(31*8+31)/32*4=8(取整)*4=32

对于上图的例子中,计算得8,故六个字节后加上两个字节。

位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:

当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;


对于用到调色板的位图,图象数据就是该象素颜色在调色板中的索引值。对于真彩色图,图象数据就是实际的RGB

对于2色位图,1位就可以表示该象素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个象素。

对于16色位图,用4可以表示一个象素的颜色,所以一个字节可以表示2个象素。

对于256色位图,一个字节刚好可以表示1个象素。

对于真彩色图,三个字节才能表示1个象素。


有了头文件信息后,我们就可以找到位图数据。位图数据是以4个字节(32位,对应32位CPU的优化)为一组来处理的。


例1. 我们先来看简单的只有黑白两色的内部存储方式(0:黑,1:白):

原始bmp图(一个方块表示一个象素)

bmp图的二进制代码

红框内表示位图数据信息,以4个字节为一组(7*5像素),位图数据5个字节,图高5像素,所以每行1个字节,分别是:
7E 00 00 00 ;0111 1110 0000 0000 0000 0000 0000 0000
FE 00 00 00 ;1111 1110 0000 0000 0000 0000 0000 0000
7E 00 00 00 ;0111 1110 0000 0000 0000 0000 0000 0000
FE 00 00 00 ;1111 1110 0000 0000 0000 0000 0000 0000
54 00 00 00 ;0101 0100 0000 0000 0000 0000 0000 0000
对比一下原始的bmp图,你就会发现,是以先横向再纵向,先下后上的方式存储。因为横向的像素只有7个,所以4个字节(32位)只用到前面7位,后面用0表示。

例2. 看下24位的位图,分别由RGB三原色组合,每个颜色用一个字节表示


24位bmp原图


24位bmp图二进制码

红框内表示位图数据信息,以4个字节为一组(2*3像素),位图数据24个字节,图高3像素,所以每行8个字节,分别是:
FF FF FF 00 FF 00 00 00 ; FF FF FF 00 FF 00 00 00 表示:白绿
00 FF 00 00 00 FF 00 00 ; 00 FF 00 00 00 FF 00 00 表示:绿红
00 00 00 FF 00 00 00 00 ; 00 00 00 FF 00 00 00 00 表示:黑蓝

因为24位是使用RGB三原色,每种原色都用一个字节。
观察后,发现颜色是由BGR顺序组,可能与字的存储顺序,先高位后低位有关。


最后

以上就是老迟到楼房为你收集整理的位图BITMAP结构的全部内容,希望文章能够帮你解决位图BITMAP结构所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部