当前位置:文档之家› bmp位图调色板

bmp位图调色板

调色板调色板概述每个应用程序都有自己的调色板,使用调色板时要先向系统申请,调色板分为前台调色板和后台调色板,windows为优先级高的程序分配前台调色板.我们经常会发现当启动一个大一点的程序时,桌面和其他应用程序的颜色变得粗糙起来,就是因为其他应用程序的调色板正在转为后台调色板.Windows系统内部保留了一个20种颜色的调色板,用来显示窗口,菜单等通用界面每个设备上下文都拥有一个逻辑调色板,如果要使用内部系统调色板(20种颜色)之外的颜色,则应该创建一个新的逻辑调色板并将其选入到设备上下文中.再把设备上下文中的逻辑调色板实现到系统调色板中,新的颜色才能实现.在逻辑调色板被实现到系统调色板时,Windows会建立一个调色板映射表,当设备上下文用逻辑调色板中的颜色绘图时,GDI绘图函数会查询调色板映射表以把像素值从逻辑调色板的索引转换成系统调色板的索引.创建调色板BOOL CreatePalette(LPLOGPALETTE lpLogPalette );其中lpLogPalette是一个指向LOGPALETTE 结构的指针typedef struct tagLOGPALETTE { WORD palVersion; //windows版本号,一般是0x300WORD palNumEntries; //调色板中颜色表项的数目PALETTEENTRY palPalEntry[1]; //每个表项的颜色和使用方法} LOGPALETTE;typedef struct tagPALETTEENTRY {BYTE peRed; //红(0-255)BYTE peGreen;// 绿BYTE peBlue; //蓝BYTE peFlags; //一般为0} PALETTEENTRY;上面只是建立了一个逻辑调色板,而逻辑调色板只是一张孤立的颜色表,并不能对系统产生影响,所以要使用调色板还需要下面这些函数CPalette* SelectPalette(CPalette* pPalette,BOOL bForceBackground );这个函数用来将一个调色板载入设备上下文,第一个参数是一个调色板指针,第二个参数用来指定调色板作为前景色还是背景色使用,为TURE时,作为背景色使用,为FALSE时,当窗口是活动窗口或活动窗口的子窗口是,调色板将做为前景色使用,否则做为背景色来使用.如果使用调色板的是一个内存设备上下文,则该参数被忽略.UINT RealizePalette( );该函数把设备上下文中的逻辑调色板实现到系统调色板中, 函数的返回值表明调色板映射表中有多少项被改变了这两个函数的使用如下:CPalette *pOldPalette ;CWindowDC dc(this) ;pOldPalette=dc.SelectPalette(&pal, FALSE) ;dc.RealizePalette() ;dc.SelectPalette(pOldPalette, FALSE) ;如果某一个窗口要显示特殊的颜色,那么一般应该在处理WM_PAINT消息时实现自己的逻辑调色板,也就是说,在OnPaint或OnDraw函数中重绘以前,要调用SelectPalette和RealizePalette,如果窗口显示的颜色比较重要,则要在调用SelectPalette时指定bForceBackground参数为FALSE.创建调色板的一般步骤:1 建立一个LOGPALETTE结构和PALETTEENTRY数组2 对PALETTEENTRY数组进行赋值,即创建调色板颜色表3 建立CPalette对象并使用CreatePalette函数初始化调色板对象4 使用SelectPalette函数将设备描述表和调色板联系起来5 使用CDC中的RealizePalette函数使调色板生效为了协调各个窗口对系统调色板的使用,Windows在必要的时候会向顶层窗口和重绘窗口发送消息WM_QUERYNEWPALETTE和WM_PALETTECHANGED.当某一顶层或重叠窗口被激活时,会收到WM_QUERYNEWPALETTE消息,在窗口的创建之处也会收到该消息,该消息先于WM_PAINT消息到达窗口,如果活动窗口要使用特殊的颜色,则在收到该消息时应该实现自己的逻辑调色板并重绘窗口.11.1.1 调色板的原理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使用逻辑调色板来作为使用颜色的应用程序和系统调色板(物理调色板)之间的缓冲。

图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),顶层窗口是指没有父窗口或父窗口是桌面窗口的窗口,这种窗口一般都有标题和边框,主要包括框架窗口和对话框。

术语重叠窗口是指作为应用程序主窗口的窗口,我们可以把对话框看成是一种特殊的重叠式窗口。

图11.2 调色板的映射关系11.1.2 调色板的创建和实现MFC的CPalette类对逻辑调色板进行了封装。

该类的成员函数CreatePalette负责创建逻辑调色板,该函数的声明为:BOOL CreatePalette( LPLOGPALETTE lpLogPalette ); //成功则返回TRUE。

参数lpLogPalette是一个指向LPLOGPALETTE结构的指针,LPLOGPALETTE结构描述了逻辑调色板的内容,该结构的定义为:typedef struct tagLOGPALETTE {WORD palVersion; //Windows版本号,一般是0x300WORD palNumEntries; //调色板中颜色表项的数目PALETTEENTRY palPalEntry[1]; //每个表项的颜色和使用方法} LOGPALETTE;结构中最重要的成员是PALETTEENTRY数组,数组项的数目由palNumEntries成员指定。

PALETTEENTRY结构对调色板的某一个颜色表项进行了描述,该结构的定义为:typedef struct tagPALETTEENTRY {BYTE peRed; //红色的强度(0~255,下同)BYTE peGreen; //绿色的强度BYTE peBlue; //蓝色的强度BYTE peFlags;} PALETTEENTRY;成员peFlags说明了颜色表项的使用方法,在一般应用时为NULL,若读者对peFlags的详细说明感兴趣,可以查看Visual C++的联机帮助。

相关主题