摘录于《Windows程序(第5版,珍藏版).CHarles.Petzold 著》P506
位图是矩形的,有空间尺寸,也就是图像的宽和高,用像素表示。例如,下面的网格可以表示一个很小的位图,它有 9 个像素宽,6 个像素高,或者更精确地说,9*6。
按惯例,位图尺寸的简写是以宽度开始。这个位图一共有 9 * 6,或者说是 54 像素。我会经常用符号 cx 和 cy 来表示一个位图的宽和高。字母“c”代表数量(count),所以 cx 和 cy 是沿 x(横)和 y(纵)轴的像素数。
我们可以用 x 和 y 坐标来指定位图中特定的一个像素。通常(但也不总是,我们会在后面看到),图像的左上角被考虑为位图的源点,就像我在上面网格中给像素的编号一样。因此,这个位图右下角的像素就在坐标点(8, 5)上。这比位图的宽和高少 1,因为编号从 0 开始。
位图的空间尺寸经常又被称为它的分辨率,但这个词有些问题。我们说我们的视频显示器的分辨率是 640*480,而我们的激光打印机的分辨率是每英寸 300 点。我更倾向于后一种用法——分辨率代表每度量单位里的像素数目。位图也可以有这样意义上的分辨率,也就是说位图中的几个像素对应于一个特定的度量单位。但不管怎样,当我说分辨率时,从上下文应该很清楚我在用哪个定义。
位图是矩形的但计算机内存是线性的。位图在内存里的存储通常(也不总是)是从最上面的一行像素开始,以最底下的行结束。(这个规则的一个主要例外是 DIB。)在每一行中,像素是按最左边的像素直到最右边的像素存储的。这就像存储好几行文字的每个字符一样。
14.2.1 颜色和位图
位图除了有空间尺寸外,还有颜色维度,也就是每个像素所需的位的数目,有时候又叫位图的颜色深度(Color Depth),或位数,或每像素位数(bbp)。位图的每个像素都有同样的颜色位数。
每像素只有一位的位图称为二级(bilevel)或二色(biclor),或单色位图。每个像素不是 0 就是 1。其中 0 可以代表黑色,1 代表白色,但也不一定总是这样。要想有更多的颜色,就需要每个像素有更多的位。总共可能的颜色是 2 位数。有 2 位的话,你得到 4 种颜色,4 位有 16 种颜色,8 位有 256 种颜色,16 位有 65536 种颜色,24 位的话,则有 16777216 种颜色。
而颜色位的组合究竟怎样准备地与真实和熟悉的颜色相对应,则是一个一直占据(和常常困扰)着所有与位图打交道的人的思想的问题。
14.2.2 现实世界的设备
位图可以按它们的颜色位数目来分类;而不同的位图颜色格式则是基于自 Windows 存在以来所常用的视频显示适配器的颜色能力。
实际上,我们可以把视频显示器内存想象成一个大的位图——也就是我们在显示器上看到的位图。
Windows 1.0 最常用的视频适配器是 IBM 彩色图形适配器(CGA)和大力神图形适配器(HGC)。HGC 是单色设备,CGA 在 Windows 下也只能用在单色图形模式下。单色位图还是很常见的(比如,鼠标指针经常是单色的),单色位图除了用来显示图像外也还有其他用途。
随着增强图形适配器(EGA)的出现,Windows 用户可以访问 16 种颜色。每个像素需要 4 个颜色位。(EGA 实际上比这要复杂一些,它有一个 64 种颜色的调色板,应用程序可以从中选择 16 种颜色,但 Windows 用一种简单的方式使用 EGA。)EGA 上用的 16 种颜色是黑、白、两种灰色、还有浅色的和深色的红、绿、蓝(就是三原色),青绿(蓝加上绿),洋红(蓝加上红)和黄(红加上绿)。这 16 种颜色是现在 Windows 所需的最低标准。同样,Windows 里还是有 16 色的位图。大多数图标是 16 色的位图。简单的卡通式的图像也通常用这 16 种颜色就够了。
16 色位图的色彩编码有时被称为 IRGB(强度-红-绿-蓝),它实际上时从 IBM CGA 的字符模式中用到的颜色中衍生出来的。下表显示了每个像素用的四个 IRGB 颜色位是怎样对应到 Windows 十六进制的 RGB 颜色的。
IRGB | RGB 颜色 | 颜色名称 |
---|---|---|
0000 | 00-00-00 | 黑 |
0001 | 00-00-80 | 深蓝 |
0010 | 00-80-00 | 深绿 |
0011 | 00-80-80 | 深青 |
0100 | 80-00-00 | 深红 |
0101 | 80-00-80 | 深洋红 |
0110 | 80-80-00 | 深黄 |
0111 | C0-C0-C0 | 浅灰 |
1000 | 80-80-80 | 深灰 |
1001 | 00-00-FF | 蓝 |
1010 | 00-FF-00 | 绿 |
1011 | 00-FF-FF | 青 |
1100 | FF-00-00 | 红 |
1101 | FF-00-FF | 洋红 |
1110 | FF-FF-00 | 黄 |
1111 | FF-FF-FF | 白 |
Windows 98 和 Windows NT 需要 VGA 或更高分辨率的图形卡。这是 Windows 当前所接受的视频图形板卡的最低标准。
最早的视频图形阵列(VGA)是在 1987 年随着 IBM 的 PS/2 个人计算机推出的。它提供了好几种视频模式,但最好的图形模式(Windows 所使用的)是横向 640 像素、纵向 480 像素,显示 16 种颜色。要显示 256 种颜色,最早 VGA 不得不转成 320 * 240 的图形模式,这对 Windows 来说,像素数目太少了,没法正常工作。
人们常常会忘记最早的 VGA 的色彩限制,因为其他的硬件生产商很快就开发了“超级 VGA”(或 SVGA)适配器,它由更多的显示内存,而且能在 640 * 480 的模式下显示 256 种颜色或更多颜色。这些现在都是标准了,这是一件好事,因为 16 种颜色对显示真实的图像来说根本不够。
显示 256 种颜色的视频适配器模式每个像素要用 8 位。然而,这些 8位值不一定对应到具体的颜色。实际上,显示卡采用“调色板查找表”的方式,让软件来制定这些 8 位值怎样对应到真正的颜色。在 Windows 中,应用程序不能直接访问这个硬件调色板查找表;相反,Windows 保留 256 种颜色中的 20 个,应用程序用 Windows 调色板管理器来配置其他的 236 种颜色。第 16 章将详细地介绍这些。调色板管理器能让应用程序在 256 色的显示器上显示真实的位图。Windows 保留的 20 种颜色如下所示:
颜 色 值 | RGB 颜色 | 颜色名称 |
---|---|---|
00000000 | 00-00-00 | 黑 |
00000001 | 80-00-00 | 深红 |
00000010 | 00-80-00 | 深绿 |
00000011 | 80-80-00 | 深黄 |
00000100 | 00-00-80 | 深蓝 |
00000101 | 80-00-80 | 深洋红 |
00000110 | 00-80-80 | 深青 |
00000111 | C0-C0-C0 | 浅灰 |
00001000 | C0-DC-C0 | 美元绿 |
00001001 | A6-CA-F0 | 天蓝 |
11110110 | FF-FB-F0 | 乳白 |
11110111 | A0-A0-A4 | 中灰 |
11111000 | 80-80-80 | 深灰 |
11111001 | FF-00-00 | 红 |
11111010 | 00-FF-00 | 绿 |
11111011 | FF-FF-00 | 黄 |
11111100 | 00-00-FF | 蓝 |
11111101 | FF-00-FF | 洋红 |
11111110 | 00-FF-FF | 青绿 |
11111111 | FF-FF-FF | 白 |
提高到每像素 24 位的话,我们有 16777216 种颜色(又叫“真彩”或“百万色”)。每个像素用 3 个字节。这个标准很可能未来好多年内都不会变,因为它大致代表人类能够辨别的色彩极限,而且它很方便。
在调用 GetDeviceCaps 时(比如在第 5 章的 DEVCAPS 程序中),可以用 BITSPIXEL 和 PLANES 常数来获得视频适配器的颜色组织。许多年来,它们可能的取值如下表所示。
BITSPIXEL | PLANES | 颜色数 |
---|---|---|
1 | 1 | 2 |
1 | 4 | 16 |
8 | 1 | 256 |
15 或 16 | 1 | 32768 或 65536 |
24 或 32 | 1 | 16777216 |
14.2.3 GDI 中的位图支持
Windows 的图形设备接口(GDI)从 1.0 开始就支持位图了。但是,在 3.0 之前,在 Windows 下唯一的位图支持是 GDI 对象,需要使用位图句柄来使用它们。这些 GDI 对象是单色的,或是跟真正的图形输出设备,如视频显示器,有着一样的颜色组织。例如,一个与 16 色 VGA 兼容的位图有四个颜色平面。问题在于,这些位图不能被保存和用在另一个有着不同颜色组织的图形输出设备上,比如,不能用在一个每像素 8 位,能显示 256 种颜色显示器上。
从 Windows 3.0 开始,定义了一个新的位图格式,称为设备无关位图或 DIB。DIB 包含了它自身的颜色表,显示每个像素位怎样对应到 RGB 颜色。DIB 能被显示在任何点阵输出设备上。唯一的问题是,DIB 的颜色经常必须被转换为设备实际上能够处理的颜色。
随着 DIB 的推出,Windows 3.0 还引进了 Windows 调色板管理器,能让程序在 256 色显示器上自定义颜色。应用程序显示 DIB 时经常会同时使用调色板管理器,相关详情可以参见第 16 章。
Microsoft 在 Windows 98(和 Windows NT 4.0)中扩充了 DIB 的定义,在 Windows 98(和 Windows NT 5.0)中又作了进一步扩充。这些改进通常都涉及图像色彩管理(ICM),ICM 能让 DIB 更精确地指定图像所需要的特定的颜色。第 15 章将简单介绍 ICM。
尽管 DIB 很重要,但老的 GDI 位图对象在处理位图时仍然起着很重要的作用,要掌握位图,最好的策略可能还是按时间顺序来找资料,从 GDI 位图对象和位块传输着手。