位图和调色板的概念

来源:互联网 发布:淘宝金冠店铺值多少钱 编辑:程序博客网 时间:2024/06/05 09:28

1.1 位图和调色板的概念
如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个重要因素是它可视化的漂亮界面。那么Windows是如何显示图象的呢?这就要谈到位图(bitmap)。
我们知道,普通的显示器屏幕是由许许多多点构成的,我们称之为象素。显示时采用扫描的方法:电子枪每次从左到右扫描一行,为每个象素着色,然后从上到下这样扫描若干行,就扫过了一屏。为了防止闪烁,每秒要重复上述过程几十次。例如我们常说的屏幕分辨率为640×480,刷新频率为70Hz,意思是说每行要扫描640个象素,一共有480行,每秒重复扫描屏幕70次。
我们称这种显示器为位映象设备。所谓位映象,就是指一个二维的象素矩阵,而位图就是采用位映象方法显示和存储的图象。
那么,彩色图是怎么回事呢?
我们先来说说三元色RGB概念。
我们知道,自然界中的所有颜色都可以由红、绿、蓝(R,G,B)组合而成。有的颜色含有红色成分多一些,如深红;有的含有红色成分少一些,如浅红。针对含有红色成分的多少,可以分成0到255共256个等级,0级表示不含红色成分;255级表示含有100%的红色成分。同样,绿色和蓝色也被分成256级。这种分级概念称为量化。
这样,根据红、绿、蓝各种不同的组合我们就能表示出256×256×256,约1600万种颜色。这么多颜色对于我们人眼来说已经足够丰富了。
表1.1 常见颜色的RGB组合值
颜色 R G B
红 255 0 0

绿 0 255 0
蓝 0 0 255
黄 255 255 0
紫 255 0 255
青 0 255 255
白 255 255 255
黑 0 0 0
灰 128 128 128
你大概已经明白了,当一幅图中每个象素赋予不同的RGB值时,能呈现出五彩缤纷的颜色了,这样就形成了彩色图。的确是这样的,但实际上的做法还有些差别。
让我们来看看下面的例子。
有一个长宽各为200个象素,颜色数为16色的彩色图,每一个象素都用R、G、B三个分量表示。因为每个分量有256个级别,要用8位(bit),即一个字节(byte)来表示,所以每个象素需要用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位图中便用到了调色板技术。其实不光是Windows位图,许多图象文件格式如pcx、tif、gif等都用到了。所以很好地掌握调色板的概念是十分有用的。
有一种图,它的颜色数高达256×256×256种,也就是说包含我们上述提到的R、G、B颜色表示方法中所有的颜色,这种图叫做真彩色图(true color)。真彩色图并不是说一幅图包含了所有的颜色,而是说它具有显示所有颜色的能力,即最多可以包含所有的颜色。表示真彩色图时,每个象素直接用R、G、B三个分量字节表示,而不采用调色板技术。原因很明显:如果用调色板,表示一个象素也要用24位,这是因为每种颜色的索引要用24位(因为总共有224种颜色,即调色板有224行),和直接用R,G,B三个分量表示用的字节数一样,不但没有任何便宜,还要加上一个256×256×256×3个字节的大调色板。所以真彩色图直接用R、G、B三个分量表示,它又叫做24位色图。


1.2 BMP(bit map)文件格式


  BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。文件头主要包含文件的大小、文件类型、图像数据偏离文件头的长度等信息;位图信息头包含图象的尺寸信息、图像用几个比特数值来表示一个像素、图像是否压缩、图像所用的颜色数等信息。颜色信息包含图像所用到的颜色表,显示图像时需用到这个颜色表来生成调色板,但如果图像为真彩色,既图像的每个像素用24个比特来表示,文件中就没有这一块信息,也就不需要操作调色板。文件中的数据块表示图像的相应的像素值,需要注意的是:图像的像素值在文件中的存放顺序为从左到右,从下到上,也就是说,在BMP文件中首先存放的是图像的最后一行像素,最后才存储图像的第一行像素,但对与同一行的像素,则是按照先左边后右边的的顺序存储的;另外一个需要读者朋友关注的细节是:文件存储图像的每一行像素值时,如果存储该行像素值所占的字节数为4的倍数,则正常存储,否则,需要在后端补0,凑足4的倍数。

1.3. BMP文件头

    BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。其结构定义如下:
typedef struct tagBITMAPFILEHEADER
{
WORD bfType; // 位图文件的类型,在window中总为“BM”
DWORD bfSize; // 位图文件的大小,以字节为单位
WORD bfReserved1; // 位图文件保留字,必须为0
WORD bfReserved2; // 位图文件保留字,必须为0
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位
} BITMAPFILEHEADER;该结构占据14个字节。

1.4. 位图信息头

    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; // 位图数据的大小,以字节为单位,必须是4的位数。
LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数
LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
DWORD biClrImportant;// 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;该结构占据40个字节。

  注意:对于BMP文件格式,在处理单色图像和真彩色图像的时候,无论图象数据多么庞大,都不对图象数据进行任何压缩处理,一般情况下,如果位图采用压缩格式,那么16色图像采用RLE4压缩算法,256色图像采用RLE8压缩算法。

1.5. 颜色表

  颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:
typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
BYTErgbRed; // 红色的亮度(值范围为0-255)
BYTErgbReserved;// 保留,必须为0
} RGBQUAD;

  颜色表中RGBQUAD结构数据的个数由BITMAPINFOHEADER 中的biBitCount项来确定,当biBitCount=1,4,8时,分别有2,16,256个颜色表项,当biBitCount=24时,图像为真彩色,图像中每个像素的颜色用三个字节表示,分别对应R、G、B值,图像文件没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息头
RGBQUAD bmiColors[1]; // 颜色表
} BITMAPINFO;

  注意:RGBQUAD数据结构中,增加了一个保留字段rgbReserved,它不代表任何颜色,必须取固定的值为“0”,同时,RGBQUAD结构中定义的颜色值中,红色、绿色和蓝色的排列顺序与一般真彩色图像文件的颜色数据排列顺序恰好相反,既:若某个位图中的一个像素点的颜色的描述为“00,00,ff,00”,则表示该点为红色,而不是蓝色。

1.6. 位图数据

  位图数据记录了位图的每一个像素值或该对应像素的颜色表的索引值,图像记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。这种格式我们又称为Bottom_Up位图,当然与之相对的还有Up_Down形式的位图,它的记录顺序是从上到下的,对于这种形式的位图,也不存在压缩形式。位图的一个像素值所占的字节数:当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当biBitCount=8时,1个像素占1个字节;当biBitCount=24时,1个像素占3个字节,此时图像为真彩色图像。当图像不是为真彩色时,图像文件中包含颜色表,位图的数据表示对应像素点在颜色表中相应的索引值,当为真彩色时,每一个像素用三个字节表示图像相应像素点彩色值,每个字节分别对应R、G、B分量的值,这时候图像文件中没有颜色表。上面我已经讲过了,Windows规定图像文件中一个扫描行所占的字节数必须是4的倍数(即以字为单位),不足的以0填充,图像文件中一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;// 一个扫描行所占的字节数

  位图数据的大小按下式计算(不压缩情况下):
  DataSize= DataSizePerLine* biHeight。

转自:http://hi.baidu.com/%CD%F5%BD%E0%C3%B72009/blog/item/1d0797f64ae352e57709d765.html

原创粉丝点击