Windows调色板是256色显卡时期的产物,如今显卡最少也是16bit的了。所以调色板基本上是用不到了的。

可是以下几种情况还是须要去使用和了解调色板:

1.在新显卡上保证256色兼容模式的正常执行

2.在256色显卡或低于256色显卡老机器上执行程序或在一些工业控制场合(为了节约成本可能採用256色显卡或低于256色显卡)执行程序

3.操作DIB的指定像素点数据

1.调色板是什么

相同採用以下一张图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VuemhvdTEyMTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

如上图,我们能够调色板分为例如以下几种:

1.DIB文件里的调色板

2.内存中创建的逻辑调色板对象

3.显卡中硬件调色板

调色板顾名思义就是类似画家的调色板一样,以256色显卡来说,如今有256个小格子,每一个格子中有一种颜色,每次画图你能够用这256种颜色来画图,假设你对当前的256种颜色不惬意,能够更换当中的调色板颜色,可是每画一幅图仅仅能用确认的256中颜色来。相应到电脑的调色板来说,显卡支持显示的颜色仅仅有256种,存储在显卡硬件调色板中,你能够设置要採用的256种颜色。然后你要显示的全部颜色都会近似用256中颜色中的一种来显示,这就是所谓的调色板查表以取得近期似颜色。

能够看到。一幅图在电脑上显示的效果是什么样和当前显卡硬件调色板中的颜色是密不可分的,所以对于採用硬件调色板的的位图,保存它的最好做法就是保存位图数据的同一时候保存位图调色板

为了改变硬件调色板中的颜色我们须要先创建逻辑调色板对象,然后再将逻辑调色板映射到硬件调色板上。

2.调色板的使用

对于带有调色板的DIB来说。显示DIB的一般过程例如以下:

1.读入DIB分别为File Header、Info Header、Mask、Color Table、Bits各个区

2.利用DIB的调色板数据(Color Table区)创建逻辑调色板对象(CreatePalette)。一般在WM_CREATE中

3.在WM_PAINT显示DIB之前,将基于DIB创建的逻辑调色板对象选进当前设备描写叙述表(SelectPalette)并映射到硬件调色板上(RealizePalette)。

4.假设仅仅是想保证指定窗体为活动窗体时显示的颜色,那么做完这三歩即可了。假设想保证指定窗体不是活动窗体时的颜色,那么还要处理WM_QUERYPALETTE和WM_PALETTECHANGED消息。

这两个消息是为了帮助Windows组织系统调色板用的。这里不详述。直接依照固定模式使用,详细能够查看MSDN。

3.代码演示

演示程序为一个典型的Windows 带调色板DIB的显示过程。以下为部分代码,完整源码最后会给出下载链接。

依据DIB Color Table创建逻辑调色板

//创建数据显示调色板
HPALETTE PackedDibCreatePalette(BITMAPINFO *pPackedDib, HWND hwnd)
{
HPALETTE hPalete;
HDC hdc;
int i, iNumColors;
LOGPALETTE *plp = NULL;
RGBQUAD *prgb = NULL; if (0 == PackedDibGetColorTableSize(pPackedDib) &&
PackedDibGetBitCount(pPackedDib) > 8)//没有调色板区且位深大于8,则没有必要创建调色板
{
return NULL;
}
else if (0 == PackedDibGetColorTableSize(pPackedDib))//没有调色板区且位深小于等于8,则创建通用调色板
{
hdc = GetDC(hwnd);
hPalete = CreateHalftonePalette(hdc);
ReleaseDC(hwnd, hdc); return hPalete;
}
else//使用位图自带的调色板区
{
iNumColors = PackedDibGetNumColors(pPackedDib); plp = malloc(sizeof(LOGPALETTE) + (iNumColors-1)*sizeof(PALETTEENTRY));
if (NULL == plp)
{
return NULL;
} plp->palVersion = 0x0300;
plp->palNumEntries = iNumColors; for (i = 0; i < iNumColors; i++)
{
prgb = PackedDibGetColorTableEntry(pPackedDib, i); plp->palPalEntry[i].peRed = prgb->rgbRed;
plp->palPalEntry[i].peGreen = prgb->rgbGreen;
plp->palPalEntry[i].peBlue = prgb->rgbBlue;
plp->palPalEntry[i].peFlags = 0;
} hPalete = CreatePalette(plp);
if (INVALID_HANDLE_VALUE == hPalete)
{
return NULL;
} return hPalete;
}
}

WM_PAINT中显示DIB及WM_QUERYPALETTE和WM_PALETTECHANGED消息的处理

    case WM_PAINT:
hdc = BeginPaint (hwnd, &ps); if (hPalette)
{
SelectPalette(hdc, hPalette, FALSE);
RealizePalette(hdc);
} if (pPackedDib)
{
SetDIBitsToDevice( hdc,
0, 0, PackedDibGetWidth(pPackedDib), PackedDibGetHeight(pPackedDib),
0, 0,
0, PackedDibGetHeight(pPackedDib),
PackedDibGetBitsPtr(pPackedDib),
pPackedDib,
DIB_RGB_COLORS);
} EndPaint (hwnd, &ps);
return (0); case WM_QUERYNEWPALETTE:
if(!hPalette)
{
return FALSE;
} hdc = GetDC(hwnd); SelectPalette(hdc, hPalette, FALSE);
RealizePalette(hdc);
InvalidateRect(hwnd, NULL, FALSE); ReleaseDC(hwnd, hdc);
return TRUE; case WM_PALETTECHANGED:
if(!hPalette || (HWND)wParam==hwnd)
{
break;
} hdc = GetDC(hwnd); SelectPalette(hdc, hPalette, FALSE);
RealizePalette(hdc);
UpdateColors(hdc); ReleaseDC(hwnd, hdc);
break;

4.DIB操作库

至此为止,关于DIB显示的所有知识点所有讲完。在给出的代码中实现了一个完整的DIB操作库,主要用于打开、显示和保存DIB。不同于实验DIB显示功能,一个完整性好的DIB操作库必须兼容各种版本号DIB格式、不标准DIB位图

1.DIB版本号的兼容主要包含对OS/2格式位图的兼容(BITMAPCOREHEADER定义带来的各种差异。RGBTRIPLE带来的差异)。

2.不标准DIB位图主要指有的DIB位图不填充ClrUsed、SizeImage项,有的小于8bit的DIB位图没有调色板须要使用通用调色板,有的16bit位图不提供掩码等等。

总之,一个实现完整的DIB库须要考虑种种繁枝末节,假设是在商业程序中使用的话。最好使用已经开源的各种实现。该博文提供的DIB库在Pelzold的实现上改动而来,但仍然有不足,比如对压缩的DIB没有考虑等,仅供技术研究用。

完整源码下载链接

原创。转载请注明来自http://blog.csdn.net/wenzhou1219

Windows DIB文件操作具体解释-5.DIB和调色板的更多相关文章

  1. Windows DIB文件操作具体解释-4.使用DIB Section

    前面讲了为了提高DIB的显示性能和效率,我们将DIB转换成DDB.可是这又遇到一个问题.假设我想操作DIB的数据的话,显然是不能使用DDB:一是由于DIB转DDB时发生了颜色转换.再就是DDB无法直接 ...

  2. Unix/Linux环境C编程新手教程(41) C语言库函数的文件操作具体解释

     上一篇博客我们解说了怎样使用Linux提供的文件操作函数,本文主要解说使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #in ...

  3. sed命令针对文件操作具体解释

    Linux的简单shell脚本中改动文件操作 1.Sed简单介绍 sed 是一种在线编辑器,它一次处理一行内容.处理时.把当前处理的行存储在暂时缓冲区中,称为"模式空间"(patt ...

  4. C# Xml文件操作,解释见注释

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 记录Windows下文件操作记录

    https://blog.csdn.net/huashuolin001/article/details/73863324

  6. Java路径操作具体解释

    1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或文件夹在硬盘上真正的路径.(URL和物理路径)比如: C:\xyz\test.txt 代表了test.txt文件的绝对路径.http://w ...

  7. Windows与Linux下文件操作监控的实现

    一.需求分析: 随着渲染业务的不断进行,数据传输渐渐成为影响业务时间最大的因素.究其原因就是因为数据传输耗费较长的时间.于是,依托于渲染业务的网盘开发逐渐成为迫切需要解决的需求.该网盘的实现和当前市场 ...

  8. Windows phone 8 学习笔记(2) 数据文件操作(转)

    Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方.本节主要讲解它们的用法以及相关限制性.另外包括本地数据库的使用方式 ...

  9. Windows文件操作的API函数[转载]

    在VC中,大多数情况对文件的操作都使用系统提供的 API 函数,但有的函数我们不是很熟悉,以下提供一些文件操作 API 函数介绍: 一般文件操作 API CreateFile 打开文件 要对文件进行读 ...

随机推荐

  1. J2EE的13个规范之(二) JDBC 及其使用

    我想大家都知道ODBC是什么?ODBC(OpenDatabaseConnectivity.开放数据库互连)是微软公司开放服务结构(WOSA,WindowsOpenServicesArchitectur ...

  2. visual studio 2010配置驱动开发环境

    visual studio 2010 配置驱动开发环境 ** 工具/材料 VS2010.WDK开发包 **  配置过程 以下将讲述VS2010驱动开发环境的配置过程,至于必要软件的安装过程这里不再赘述 ...

  3. Java --CountDownLatch简介

    CountDownLatch 1.类介绍 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数 初始化 CountDownLatch.由于调用了 coun ...

  4. 知识点3-6:HTML辅助方法

    顾名思义,HTML辅助方法(HTML Helper)就是用来辅助产生HTML之用,在开发View的时候一定会面对许多HTML标签,处理这些HTML的工作非常繁琐,为了降低View的复杂度,可以使用HT ...

  5. 基于visual Studio2013解决C语言竞赛题之0702函数设计

       题目

  6. Swift - 使用NSURLSession同步获取数据(通过添加信号量)

    过去通过 NSURLConnection.sendSynchronousRequest() 方法能同步请求数据.从iOS9起,苹果建议废除 NSURLConnection,使用 NSURLSessio ...

  7. C#对数字添加逗号,千分位

    /// <summary> /// 对数字添加”,“号,可以处理负数以及带有小数的情况 /// </summary> /// <param name="vers ...

  8. sn9c291 驱动载入成功,mpayer无法播放

    先眼下将一个sn9c291+ov9712的模块驱动在fedora上载入成功,但是在使用mplayer却无法播放,不知道为何? watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  9. Swift - AppDelegate.swift类中默认方法的介绍

    项目创建后,AppDelegate类中默认带有如下几个方法,具体功能如下: 1,应用程序第一次运行时执行 这个方法只有在App第一次运行的时候被执行过一次,每次App从后台激活时都不会再执行该方法. ...

  10. semaphore实现浏览器的读写原理

    在编程范式中的斯坦福大学的老师说了一个例子:好比世界上就只有一台互联网的服务器,当我们浏览网页的时候,就好比服务器进行了写操作,而浏览器则进行了读操作. 我如果用简单的伪代码c++写出来是这个样子的: ...