(一)调色板的使用

来源:互联网 发布:房地产网络推广方案 编辑:程序博客网 时间:2024/06/05 10:15

调色板又称颜色查找表(Look-Up Table,LUT),它是早期为解决显示设备不能同时显示丰富的颜色而提出的。通过为需要显示的颜色建立一个查找表(即调色板),就可以只存储像素颜色所对应的索引值。这样不仅可以节约图像的存储空间,而且还可以通过修改调色板中索引值所对应的颜色来显示其它颜色。

对于低于16位的BMP图像,需要用调色板来实现图像的显示。“逻辑调色板”是一个RGB颜色值的列表,它告诉Windows应用程序想要显示的颜色,而“系统调色板”是指显示适配器的硬件调色板。在256色显示适配器中,Windows在系统调色板中编制了20种标准的颜色,称为“静态颜色”。在MS-DOS中,运行在256色适配器上的程序可以编制自己的硬件调色板,任意使用256种颜色。但是在Windows中,不允许应用程序直接编写硬件调色板,因为显示适配器是共享资源,这就需要用到逻辑调色板
将逻辑调色板中的颜色传送给系统调色板中未使用的输入项的过程称为实现调色板。如果两个以上的应用程序要实现逻辑调色板,则调色板管理器基于每个窗口的前后顺序来分配颜色优先级别,最顶端的窗口优先级最高,第二个窗口次之,依此类推。如果最前端窗口实现了一个具有200种颜色的调色板,则这200种颜色就都会映射到系统调色板上。如果后来次前端窗口要实现100种颜色的调色板,则36种会被映射到系统调色板中剩下未使用的颜色项,其余64种映射为与已经实现的256种颜色最接近的颜色。
MFC把对调色板的处理封装在CPalette类中。MFC应用程序中使用调色板一般遵循如下步骤:
    (1)构造一个CPalette对象
      CPalette m_nPalette;
    (2)根据需要实现的调色板颜色数创建一个LOGPALETTE对象,用需要实现的颜色填充该结构的颜色输入项。

/////////////////////////////////////////////////////////////////////////////////////////////////
LOGPALETTE结构如下:
typedef struct tagLOGPALETTE {
//版本号,目前取0x300
WORD         palVersion;
//调色板中的输入项数,即颜色数
WORD         palNumEntries;
  //定义颜色的输入项数组
PALETTEENTRY palPalEntry[1];
} LOGPALETTE;
////////////////////////////////////////////////////////////////////////////////////////////////////
LOGPALETTE结构中只声明一个PALETTEENTRY数组元素,因此如果需要创建一个包含m_nColorTableLength种颜色的逻辑调色板,则可以按如下方式定义:
LOGPALETTE *pLogPal; //逻辑调色板指针
//申请空间,根据颜色表生成LOGPALETTE结构LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +m_nColorTableLength * sizeof(PALETTEENTRY)];pLogPal->palVersion = 0x300;pLogPal->palNumEntries = m_nColorTableLength;LPRGBQUAD m_lpDibQuad = (LPRGBQUAD) m_lpColorTable;for(int i = 0; i < m_nColorTableLength; i++) {pLogPal->palPalEntry[i].peRed = m_lpDibQuad->rgbRed;pLogPal->palPalEntry[i].peGreen = m_lpDibQuad->rgbGreen;pLogPal->palPalEntry[i].peBlue = m_lpDibQuad->rgbBlue;pLogPal->palPalEntry[i].peFlags = 0;m_lpDibQuad++;}//创建逻辑调色板m_hPalette = ::CreatePalette(pLogPal);//释放空间delete pLogPal;}
(3)用CPalette的成员函数CreatePalette创建逻辑调色板
m_nPalette.CreatePalette(pLogPal);
    (4)用CDC类的成员函数SelectPalette把逻辑调色板选入设备环境,并用CDC类的成员函数RealizePalette实现逻辑调色板
//将调色板选进设备环境中hOldPal=::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);pDC->RealizePalette();
实现逻辑调色板之后,就可以基于调色板进行绘制工作了。当不需要调色板时,就可以用SelectPalette把逻辑调色板选出设备环境。
pDC->SelectPalette(pOldPalette,FALSE);
       在使用逻辑调色板时,最好按重要性顺序安排颜色,因为调色板管理器按数组顺序映射调色板颜色,这样位于前面的颜色就有更多的显示机会。
PS:
常用的DIB函数有:SetDIBitsToDeviceStretchDIBitsGetDIBitsSetDIBitsCreateDIBitmapCreateDIBSectionDrawDibDraw
SetDIBitsToDevice用于直接显示DIB,不进行缩放处理。
    StretchDIBits类似于StretchBlt,显示时可以缩放,是最常用的函数。
    GetDIBits用来从GDI位图按指定格式构造DIB。如果采用了压缩格式,则须两次调用该函数,第一次调用时为第五个参数lpvBits传递NULL,用于计算所需要的内存,第二次调用时使lpvBits指向用于存储DIB数据的内存指针,用于产生DIB数据。
SetDIBits使用DIB中的颜色数据填充GDI位图。
CreateDIBitmap从DIB中创建GDI位图。
CreateDIBSection创建一种特殊的DIB,称为DIB项,然后返回一个GDI位图句柄。这样就可以直接访问DIB的内存,利用位图句柄和内存设备环境,还可以在DIB中调用GDI函数绘图。
DrawDibDraw在屏幕上显示DIB,主要优点是可以使用抖动颜色。


原创粉丝点击