Windows DIB文件操作具体解释-5.DIB和调色板
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和调色板的更多相关文章
- Windows DIB文件操作具体解释-4.使用DIB Section
前面讲了为了提高DIB的显示性能和效率,我们将DIB转换成DDB.可是这又遇到一个问题.假设我想操作DIB的数据的话,显然是不能使用DDB:一是由于DIB转DDB时发生了颜色转换.再就是DDB无法直接 ...
- Unix/Linux环境C编程新手教程(41) C语言库函数的文件操作具体解释
上一篇博客我们解说了怎样使用Linux提供的文件操作函数,本文主要解说使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #in ...
- sed命令针对文件操作具体解释
Linux的简单shell脚本中改动文件操作 1.Sed简单介绍 sed 是一种在线编辑器,它一次处理一行内容.处理时.把当前处理的行存储在暂时缓冲区中,称为"模式空间"(patt ...
- C# Xml文件操作,解释见注释
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 记录Windows下文件操作记录
https://blog.csdn.net/huashuolin001/article/details/73863324
- Java路径操作具体解释
1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或文件夹在硬盘上真正的路径.(URL和物理路径)比如: C:\xyz\test.txt 代表了test.txt文件的绝对路径.http://w ...
- Windows与Linux下文件操作监控的实现
一.需求分析: 随着渲染业务的不断进行,数据传输渐渐成为影响业务时间最大的因素.究其原因就是因为数据传输耗费较长的时间.于是,依托于渲染业务的网盘开发逐渐成为迫切需要解决的需求.该网盘的实现和当前市场 ...
- Windows phone 8 学习笔记(2) 数据文件操作(转)
Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方.本节主要讲解它们的用法以及相关限制性.另外包括本地数据库的使用方式 ...
- Windows文件操作的API函数[转载]
在VC中,大多数情况对文件的操作都使用系统提供的 API 函数,但有的函数我们不是很熟悉,以下提供一些文件操作 API 函数介绍: 一般文件操作 API CreateFile 打开文件 要对文件进行读 ...
随机推荐
- H5前端面试题及答案(2)
最近想着跳槽,但面试的邀约不多,内心有点烦躁.梳理梳理心情,跳槽季竞争也大,努力做好自己... 21.请设计一套方案,用于确保页面中js加载完全. <!doctype html> < ...
- grunt 前端开发环境搭建
1.找管理员开通gitlab权限 2.下载并安装git工具 3.下载并安装nodejs 4.安装cnpm 5.安装kulor-cli cnpm install -g kulor-cli cnpm in ...
- Hbiernate关联排序问题
使用场景: 假设有两张表请求信息.账户表,它们之间是一对多的关系.对应的java类分别为Sfcx_RequestInfo和Sfcx_Zhxx.Sfcx_RequestInfo有一个Set属性 sfcx ...
- 基于visual Studio2013解决C语言竞赛题之1011对称
题目 解决代码及点评 /* 11. 判断一个给定的5×5方阵是否以第3列为轴线对称? */ #include <stdio.h> #include <s ...
- Principle of Computing (Python)学习笔记(5) BFS Searching + Zombie Apocalypse
1 Generators Generator和list comprehension非常类似 Generators are a kind of iterator that are defined l ...
- 用SignalR做类似QQ登录的应用
原文:用SignalR做类似QQ登录的应用 首先通过NuGet下载signalr包 在工程下新建一个类,继承Hub public class DemoHub:Hub { public class Us ...
- C#开发中遇到问题常问题
1.C# decimal 赋值null decimal?是可空类型就是可以将值设置为Null,decimal 不能设置为null 2.var 定义变量 VAR 是3.5新出的一个定义变量的类型其实也就 ...
- perl 循环类选择器 ,爬取内容
jrhmpt01:/root/lwp/0526# cat 0526.txt <div class="TXD_sy_title"><span class=" ...
- 基于visual Studio2013解决C语言竞赛题之1062高与矮
题目 解决代码及点评 /************************************************************************/ /* 62 ...
- html5的自定义data-*属性和jquery的data()方法的使用
人们总喜欢往HTML标签上添加自定义属性来存储和操作数据.但这样做的问题是,你不知道将来会不会有其它脚本把你的自定义属性给重置掉,此外,你这样做也会导致html语法上不符合Html规范,以及一些其它副 ...