标题:调色板 palette 详解
只看楼主
zhulei1978
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
结帖率:100%
 问题点数:0 回复次数:1 
调色板 palette 详解
调色板只有图片的颜色小于等于256色的时候才有,16位高彩和24位32位真彩是没有调色板的.
调色板的存在的意义只是在当初486以前为了节省空间的一种采用索引的压缩算法,现在没有人这种东西。

调色板是为了节约空简所用的,相当于一个索引。只有16位以下的才用调色板,真彩色不用调色板。

让我们来看看下面的例子。
有一个长宽各为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位色图。
////////////////////////////////////////////
调色板一般是为了显示256色图象时使用的。图象(BMP图象)按颜色种类分类可以分为:

1、黑白图象。不使用调色板;

2、256色图象(包括256级灰度图象),使用调色板。调色板中记录的是图象中使用的256种颜色,图象数据中记录的是颜色索引,通过这个索引值就可以找到对应的颜色。

3、24bit真彩色图象,不使用调色板。图象数据中保留RGB三种颜色组合,可以直接显示。

调色板的原理

  PC机上显示的图象是由一个个像素组成的,每个像素都有自己的颜色属性。在PC的显示系统中,像素的颜色是基于RGB模型的,每一个像素的颜色由红(B)、绿(G)、蓝(B)三原色组合而成。每种原色用8位表示,这样一个的颜色就是24位的。以此推算,PC的SVGA适配器可以同时显示224约一千六百多万种颜色。24位的颜色通常被称作真彩色,用真彩色显示的图象可达到十分逼真的效果。

  但是,真彩色的显示需要大量的视频内存,一幅640×480的真彩色图象需要约1MB的视频内存。由于数据量大增,显示真彩色会使系统的整体性能迅速下降。为了解决这个问题,计算机使用调色板来限制颜色的数目。调色板实际上是一个有256个表项的RGB颜色表,颜色表的每项是一个24位的RGB颜色值。使用调色板时,在视频内存中存储的不是的24位颜色值,而是调色板的4位或8位的索引。这样一来,显示器可同时显示的颜色被限制在256色以内,对系统资源的耗费大大降低了。

  显示器可以被设置成16、256、64K、真彩色等显示模式,前两种模式需要调色板。在16或256色模式下,程序必须将想要显示的颜色正确地设置到调色板中,这样才能显示出预期的颜色。图11.1显示了调色板的工作原理。使用调色板的一个好处是不必改变视频内存中的值,只需改变调色板的颜色项就可快速地改变一幅图象的颜色或灰度。

  在DOS中,调色板的使用不会有什么问题。由于DOS是一个单任务操作系统,一次只能运行一个程序,因此程序可以独占调色板。在Windows环境下,情况就不那么简单了。Windows是一个多任务操作系统,可以同时运行多个程序。如果有几个程序都要设置调色板,就有可能产生冲突。为了避免这种冲突,Windows使用逻辑调色板来作为使用颜色的应用程序和系统调色板(物理调色板)之间的缓冲。

T11_1.tif (194188 bytes)

图11.1 调色板工作原理

 

  在Windows中,应用程序是通过一个或多个逻辑调色板来使用系统调色板(物理调色板)。在256色系统调色板中,Windows保留了20种颜色作为静态颜色,这些颜色用作显示Windows界面,应用程序一般不能改变。缺省的系统调色板只包含这20种静态颜色,调色板的其它项为空。应用程序要想使用新的颜色,必须将包含有所需颜色的逻辑调色板实现到系统调色板中。在实现过程中,Windows首先将逻辑调色板中的项与系统调色板中的项作完全匹配,对于逻辑调色板中不能完全匹配的项,Windows将其加入到系统调色板的空白项中,系统调色板总共有236个空白项可供使用,若系统调色板已满,则Windows将逻辑调色板的剩余项匹配到系统调色板中尽可能接近的颜色上。

  每个设备上下文都拥有一个逻辑调色板,缺省的逻辑调色板只有20种保留颜色,如果要使用新的颜色,则应该创建一个新的逻辑调色板并将其选入到设备上下文中。但光这样还不能使用新颜色,程序只有把设备上下文中的逻辑调色板实现到系统调色板中,新的颜色才能实现。在逻辑调色板被实现到系统调色板时,Windows会建立一个调色板映射表。当设备上下文用逻辑调色板中的颜色绘图时,GDI绘图函数会查询调色板映射表以把像素值从逻辑调色板的索引转换成系统调色板的索引,这样当像素被输出到视频内存中时就具有了正确的颜色值。图11.2说明了这种映射关系,从图中读者可以体会到逻辑调色板的缓冲作用。在该图中,GDI绘图函数使用逻辑调色板的索引1中的颜色来绘图,通过查询调色板映射表,得知系统调色板中的第23号索引与其完全匹配,这样实际输出到视频内存中的像素值是23。注意图中还演示了颜色的不完全匹配,即逻辑调色板中的索引15和系统调色板中的索引46。

  每个要使用额外颜色的窗口都会实现自己的逻辑调色板,逻辑调色板中的每种颜色在系统调色板中都有相同或相近的匹配。调色板的实现优先权越高,匹配的精度也就越高。Windows规定,活动窗口的逻辑调色板(如果有的话)具有最高的实现优先权。这是因为活动窗口是当前与用户交互的窗口,应该保证其有最佳的颜色显示。非活动窗口的优先权是按Z顺序自上到下确定的(Z顺序就是重叠窗口的重叠顺序)。活动窗口有权将其逻辑调色板作为前景调色板实现,非活动窗口则只能实现背景调色板。

提示:术语活动窗口(Active window)或前台窗口(Foreground window)是指当前与用户交互的窗口,活动窗口的顶端的标题条呈高亮显示,而非活动窗口的标题条则是灰色的。活动窗口肯定是一个顶层窗口(Top-level window),顶层窗口是指没有父窗口或父窗口是桌面窗口的窗口,这种窗口一般都有标题和边框,主要包括框架窗口和对话框。术语重叠窗口是指作为应用程序主窗口的窗口,我们可以把对话框看成是一种特殊的重叠式窗口。
 

T11_2.tif (192888 bytes)

图11.2 调色板的映射关系

其实很简单,可以举个简单的例子,调试板是指一块区域,一个大的结构数组
数组中每个元素由 RGBQ 构成,R存放红色值,类推,Q是保留位,一般不用。

比如有一副真彩24位图象数据(无调色板) 一组RGB(就是一个象素)总共占3个字节
(R1G1B1) (R2G2B2)(R3G3B3) (R1G1B1) (R1G1B1)(R1G1B1)(R1G1B1)
7个象素 有5个颜色重复的象素的,总共21字节

转成8位(256色) 有调色板
就变成了
n0 n1 n2 n0 n0 n0 n0(n1...nX 是一个字节,只存放索引号,对应调色板数组的序号)

-----调色板------
0-----R1G1B1Q
1-----R2G2B2Q
2-----R3G3B3Q
加起来才19字节
重复的象素值越多,越省空间,这就是调色板的作用,但是如果重复的次数不多的话,你看到调色板里有很多Q,这样反而不省空间,不如用24位直接显示了   

调色板
VGA/EGA是当前最流行的图形显示卡,它比CGA有了效大的改进,不仅提高了屏幕的分辨率,也扶加了色彩,EGA所能提供的颜色为64种,但最多只能同时在屏幕上显示出其中任意16种,这是因为EGA上有一组16个颜色寄存器,被称为调色板。由系统或用户从这64种颜色中先以最多16种填入这16个寄存器中,16个颜色寄存器分别用0~15来表示,在显示只读存储器RAM中存放的是颜色寄存器代号。显示时先从显示RAM中取出颜色值,即寄存器代号,再由寄存器代号查到相应的寄存器,并取出其中颜色值加以显示。虽然显示RAM中使用同一个寄存器号(或叫颜色值),但在这个寄存器中存储不同的值,那么在屏幕上显示出不同的颜色,因此,这16个颜色寄存器起到了调色的作用。
颜色寄存器表示的是一种逻辑颜色,可以从64种物理颜色中随意取出16种放入颜色寄存器中,通过调用这些寄存器来显示所选中的颜色,中外需要说明一点,0号寄存器存放的颜色值为背景色,改变了0号寄存器中的值,则背景色随之改变
搜索更多相关主题的帖子: 调色板 图片 空间 
2016-07-13 12:00
Valenciax
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:11
帖 子:337
专家分:2462
注 册:2016-5-15
得分:0 
回复 楼主 zhulei1978
很详细的讲解。

补充一下,在windows下的16万色真彩,仍有调色板的使用,比如
invoke CreateBrushIndirect,ADDR lb
其中的lb就是一个红绿蓝比例的调色板dword。又,比如要构建一支笔刷,用到CreatePen
c++
程序代码:
HPEN CreatePen(
  _In_ int      fnPenStyle,
  _In_ int      nWidth,
  _In_ COLORREF crColor
);

win32汇编是
invoke CreatePen,fnPenStyle,nWidth,crColor
这里面 crColor,也是一个RGB的dword,红色占用0-15bit,绿色是16-31bit,蓝色是32-47bit
比如要全红,crColor=000000FFh,全黑:crColor=00000000h
因为每个色是0-255,256*256*256=16777216,就是16万色

假若要设定红色占一点阔的笔刷,代码是
invoke CreatePen,0,1,000000FFh
然后就可以使用画圆画方等指令绘制线条


[此贴子已经被作者于2016-7-14 07:26编辑过]

2016-07-14 07:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-466887-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.209775 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved