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. 关于ActionContext.getContext()的使用方法心得

    这个也是我在另外一位仁兄的博客中看到的,原博客的有点长,我把它精简了一下,算看起来比較方便吧. 为了避免与Servlet API耦合在一起,方便Action类做单元測试,Struts 2对HttpSe ...

  2. WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇]

    原文:WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇] 在[第2篇]中,我们深入剖析了单调(PerCall)模式下WCF对服务实例生命周期的控制,现在我们来 ...

  3. Java 多线程-生产者、消费者

    一.整体代码 ThreadDemo.java public class ThreadDemo { public static void main(String[] args) { Godown god ...

  4. 用Photoshop做圆角图片

    如果图片被锁定,请“双击”图层中“背景”解锁,如果没有图层菜单,在最上面导航栏中:窗口—图层. 选用“圆角矩形工具“ 设置圆角弧度大小,设置“半径” 19 同时按Ctrl+回车(Enter)选区,再C ...

  5. cocos2d-x游戏开发系列教程-坦克大战游戏之虚拟手柄控制坦克移动

    上篇显示了控制手柄,但是还不能用来控制坦克, 这篇将会讲手柄和坦克的移动结合起来. 1.先在CityScene场景中实现场景的虚函数virtual void onEnter(); onEnter在进入 ...

  6. Linux内核源代码解析之——sock's buffer参数

    本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/11539695 关于socket与sock的关系再简单 ...

  7. 真机測试时的错误:No matching provisioning profiles found

    1.出现错误的原因是这种---- 公司接收一个外包项目,原来做真机測试的时候,用的是公司申请的苹果开发人员账号.如今项目结束了,准备上线,但客户要求使用客户自己的苹果开发人员是账号上线,于是就用客户的 ...

  8. hdu1003 最大连续子序和

    Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub ...

  9. 在Ubuntu 12.04下编译qtiplot

    不在windows下,再加上不想用盗版,所以需要一个origin的替代品——qtiplot.虽然我非常抵抗用这种不停点来点去的软件,用R的ggplot2画图多好啊,高效.优雅.漂亮,但是终抵不过老板一 ...

  10. 鼠标进入与离开的消息(使用CM_MOUSEENTER来判断是否进入控件)

    unit Unit1; interface uses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs ...