第2章 图形图像处理基础
2.1 光度学基础知识
光度学是研究光的辐射能量与人眼亮度感受之间关系的一门学科。图形图像是对某种辐射物质的能量分布的记录,人类眼睛产生的视觉图像是由可见光引起的,因此,了解光度学的一些知识是必要的。在这里我们介绍有关的概念及其度量,其中某些量的定义涉及某些生理因素。
2.1.1 电磁波和可见光
电磁波的频率范围很宽,如图2.1所示,而可见光只占其中很小的一部分,波长从380nm到780nm。不同波长的光呈现出不同的颜色,随着波长的减小,可见光的颜色依次为红、橙、黄、绿、青、蓝、紫。只有单一波长成分的光称为单色光,含有两种以上波长成分的光称为复合光。人眼感受到复合光的颜色是组成该复合光的单色光所对应颜色的混合色。所有可见色光按一定比例混合便是白色光。
图2.1 电磁辐射波谱
2.1.2 相对视敏函数
在辐射功率相同的条件下,不同波长的光不仅给人不同的彩色感觉,而且也给人不同的亮度感觉。例如,在辐射能量相同条件下,人眼感到红光最暗,蓝光次之,而黄绿光最亮。要使人眼对各色光有相同的亮度感觉,就必须使红光有比黄或绿光更高的辐射功率。不同的人对不同波长的光的敏感规律也不同,即使同一个人,这种规律也会因年龄、身体情况的变化而改变。
为了定量地描述人眼对不同波长的光敏感程度,可选取若干个正常的观察者对不同波长光刺激的平均亮度反映作为一种度量标准,这便是所谓的视敏函数。
设各单色光均产生相同的亮度感觉而它们的辐射功率为P(λ),则称
为波长为λ的光的视敏度。显然,在获得相同亮度感觉下,K(λ)较大的光的辐射功率较小。实验表明,人眼对波长为555nm的光有最大的敏感度,即
于是,人眼对波长为λ的光的相对视敏函数定义为
由视敏度的定义,上式又可写为
显然,0≤V(λ)≤1。
2.1.3 光度学量
1. 光通量
人眼所感受到的光亮度不仅和光的辐射功率大小有关,而且也和人的视敏度有关。设波长为λ的光的辐射功率为P(λ),相对视敏函数为V(λ),则定义
为该波长λ的光通量。
国际上通用的光通量单位为lm(流明)。在有关规定下,555nm波长的单色光1瓦辐射功率所产生的光通量为680lm。由于可见光的波长范围是380~780nm,故人眼所接受的总光通量为
2. 光能量
设光通量为Φv(t),从时刻t1至t2间的光能量Ev定义为
其单位是lm·s(流明秒)。
3. 光强度
光源在单位立体角内的光通量称为光强度。即光强度Iv等于立体角内的光通量与该立体角之比
其单位是cd(坎德拉)。
4. 光亮度
光亮度等于辐射面在指定方向上的发光强度与辐射面在垂直于指定方向的平面上投影面积之比。若θ表示指定方向与辐射面微元dA之法线的夹角,则
当光亮度用单位面积的光强度表示时,其单位为sb(熙提)或nit(尼特)。它们之间的换算:
1熙提=1坎德拉/平方厘米
1尼特=1坎德拉/平方米
若光亮度用单位面积发出的光通量表示,其单位是朗伯或亚熙提。它们之间的换算:
1朗伯=1流明/平方厘米
1亚熙提=1流明/平方米
5. 光照度
光照度Mv表示入射到物体表面单位面积上的光通量,即
其单位是lx(勒克司)。
1勒克司=1流明/平方米
例如:赤道上中午时刻在太阳照射下地球表面的光照度约为105 lx,而在满月时晚上地表的光照度约为0.2lx;在室外阴天的光照度约为50~500lx,而晴天可达2×104 lx;60W灯泡对一米远处的物体表面的光照度约为50lx;人眼能感觉的最低光照度约为10-5 lx。
2.2 色度学基础知识
2.2.1 色度学基本概念
颜色视觉主要是研究人的色觉现象和产生规律的科学,而色度学是用数学物理的方法研究颜色的科学。
颜色和彩色严格地说并不等同,颜色可分为无彩色和有彩色两大类。无彩色指黑色、白色和深浅不同的灰色,以黑色为一端,通过一系列从深到浅排列的各种灰色,到达另一端的白色,这些可以组成一个黑白系列。彩色则指除去上述黑白系列以外的各种颜色,不过我们通常所说的颜色一般指彩色。
人的色觉的产生是一个复杂的过程。众所周知,白光是由不同颜色的光混合而成的,这些不同颜色的光实际上是不同频率的电磁波,它们通过反射或透射方式传递到眼睛,被视网膜细胞接收引起神经信号,人的视觉系统将不同频率的电磁波感知为不同的色觉。不同频率的可见电磁波称为彩色光或色光,同一频率的可见电磁波称为单色光。
颜色的表示方法大体上有两种,一种是设置一套作为标准的颜色样本,通过被测试的颜色与样本进行比较来表示;另一种方法是建立刺激光的物理性质和色感觉的对应关系,用相应的量来表示光的物理性质,这就是CIE(国际照明委员会)表色系统。在建立光的物理性质和色觉的关系时,条件一般规定如下:
(1)刺激亮度在对视锥细胞起作用又不刺激眼睛的范围内。
(2)观察视野在2°(或10°)范围内且该范围之外是黑暗的。
(3)视野内的光均匀分布且不随时间变化。
在这样单纯化了的条件下观察颜色时,刺激光的物理性质具有一贯性。但是,在这种条件下观察到的颜色与日常在复杂情况下观察到的颜色不一样,为与感觉色相区别,把这种颜色叫做心理物理色。
人对彩色光的感觉通常用(光)亮度(brightness)、色调(hue)和色饱和度(saturation)来表征。
亮度是人眼所感受到的光的明暗程度,是彩色光对视觉刺激强度所引起的,一般来讲,彩色光的能量大则显得亮;反之则显得暗。如果无彩色,那么就只有亮度的一维量的变化,因此,亮度可以理解为彩色光在“量”上的特征。
色调反映了色彩的类别,如红、绿、蓝,其取决于彩色光的光谱成分,可以理解为色调是彩色光在“质”上的特征。
饱和度是指彩色光所呈现的彩色的深浅程度,其取决于彩色光中混入白光的数量,随着白光的加入,饱和度逐渐减少。饱和度是某种色光纯度的反映,对于同一色调的彩色光,饱和度越高,颜色越深,如深红、深绿;饱和度越小,颜色越浅,如淡红、淡绿。
色调和饱和度合称为色度,它既表明颜色类别,又表明颜色深浅。颜色可由亮度和色度共同表示。
2.2.2 三色学说
通过以往在物理学中对光与颜色的研究,人们发现颜色具有恒常性,可以根据物体的固有颜色来感知它们,而不会受外界条件变化的影响。颜色之间的对比效应能够使人区分不同的颜色,同时,颜色还具有混合性。牛顿在17世纪后期用棱镜把太阳光分散成光谱上的颜色光带,用实验证明了白光是由很多颜色的光混合而成的。19世纪初,Yaung提出某一种波长的光可以通过三种不同波长的光混合而复现出来的假设,红、绿、蓝三种单色光可以作为基本的颜色——原色。把这三种光按照不同的比例混合,就能准确复现其他任何波长的光,而将它们等量混合就可以产生白光;后来Maxwell用旋转圆盘所做的颜色混合实验也验证了Yaung的假设。在此基础上,Helmhotz在1862年进一步提出颜色视觉机制学说,即三色学说,也称为三刺激理论。到现在,用三种原色能够产生各种颜色的三色原理已经成为当今颜色科学中最重要的原理和学说。
近代的三色学说研究认为,人眼的视网膜中存在着三种椎体细胞,它们包含不同的色素,对光的吸收和反射特性不同,对于不同的光就有不同的颜色感觉。研究发现,第一种椎体细胞是专门感受红光的红胞;相似地,第二种和第三种椎体细胞则分别感受绿光和蓝光。它们三者共同作用,使人产生了不同的颜色感觉。例如,当黄光刺激眼睛时,将会引起红、绿两种椎体细胞几乎相同的反应,而只引起蓝细胞很小的反应。这三种不同椎体细胞不同程度兴奋的结果就产生了黄色的感觉。这正如颜色混合时,等量的红和绿加上极少量的蓝可以复现黄色,两者原理是相同的。
三色学说是真实感图形学的生理视觉基础,是颜色视觉中最基础、最根本的理论。图形图像处理中所采用的R、G、B颜色模型以及其他的颜色模型都是根据这个学说提出来的。
2.2.3 颜色模型
一个颜色模型指的是三维颜色空间的一个子集,它包含某个颜色域中的所有颜色。例如,RGB颜色模型是三维直角坐标系统中的一个单位立方体。常用的颜色模型一般分为两类:一类适于硬件使用,包括RGB模型、CMY模型和YIQ模型;另一类面向用户,和生理因素相关,如HSV和HSI模型。
1. RGB颜色模型
基于三刺激理论,人的眼睛通过三种可见光对视网膜椎体细胞的刺激来感受颜色。这些光在波长为630nm(红)、500nm(绿)和450nm(蓝)时的刺激达到高峰。这种视觉理论是使用三种颜色基色:红、蓝和绿在视频监视器上显示彩色的基础,称为RGB颜色模型,如图2.2所示。
可以用由R、G和B坐标轴定义的单位立方体来描述这个模型,如图2.2所示。坐标原点代表黑色,而坐标点(1,1,1)代表白色;在坐标轴上的顶点代表三个基色,而余下的顶点则代表每一个基色的补色。
图2.2 RGB颜色模型
RGB颜色模型是一个加色模型。多种基色的强度加在一起生成另一种颜色。立方体边界中的每一个颜色点表示一个三元组(R,G,B),其中R、G和B的值在0~1的范围内赋值,一种颜色F在RGB坐标中表示为:F=rR+gG+bB,r、g、b称为色系数,反映匹配颜色F所需要的三基色量值的大小。
顶点品红通过将红和蓝相加生成三元组(1,0,1)来获得;而白色(1,1,1)则是红、蓝和绿顶点的和:灰色的明暗度由立方体的原点到白色顶点的主对角线上的位置来表示。对角线上每一点是等量的每一种基色的混合,因此,从黑色到白色之间的中等明暗的灰色表示成(0.5,0.5,0.5)。
2. CMY颜色模型
用基色青、品红和黄定义的颜色模型(CMY)用来描述往硬拷贝设备上输出的颜色。与生成屏幕磷粉组合光颜色的视频监视器不同,绘图仪之类的硬拷贝设备通过往纸上涂颜料来生成彩色图片,通过反射光来看见颜色,这是一种减色处理。
青色可由绿色光和蓝色光相加而得。因此,当白色光从青色墨水中反射出来时,反射光中一定没有红色成分。即红色被墨水吸收了或减掉了。同样,品红墨水减掉投射光中的绿色成分,而黄色减去蓝色成分。
图2.3 CMY颜色模型
在如图2.3所示的CMY模型中,点(1,1,1)因为所有的投射光成分都被减掉而表示黑色,原点表示白色。沿着立方体对角线每种基色量均相等而生成灰色。青色和品红墨水的混合生成蓝色,因为投射光的红色和绿色成分都被吸收了。其他颜色也由类似的减色处理产生。
使用CMY的打印处理通过4个墨点的集合来产生颜色点,在某种程度上与RGB监视器使用三个磷粉点集合是一样的。三种基色(青、品红和黄)各使用一点,黑色也使用一点。由于青色、品红色和黄色的混合通常生成深灰色而不是黑色,所以黑色单独包括在其中。有些绘图仪通过重叠喷上三种基色的墨水并让它们在干之前混合来生成各种颜色。
3. YIQ颜色模型
在RGB监视器中要求图像由独立的红、蓝和绿信号组成,而在电视信号中,颜色信息存在于复合电视信号中,复合视频信号中的颜色模型采用的是YIQ模型。
YIQ颜色模型中的亮度信息包含在Y参数中,而色度信息(色彩和纯度)则结合在I和Q参数中。Y参数由红蓝绿信号组合而成,形成了标准的亮度曲线。由于Y包含亮度信息,所以黑白电视监视器只使用Y信号。视频信号最大带宽赋给Y信息,参数I包含有橙—青色彩信息,占有大约1.5MHz的带宽。参数Q给出绿—品红色彩信息,带宽约为0.6MHz。
4. HSV颜色模型
HSV模型是对用户更直观的颜色描述方法,这个模型中的颜色参数是色彩(H)、饱和度(S)和明度值(V)。
HSV模型是定义在圆柱颜色坐标系中的六棱锥,如图2.4(a)所示。六棱锥中,色饱和度沿水平轴测量而明度值沿通过六棱锥中心的垂直轴测量。色彩用与水平轴间的角度来表示,范围从0°~360°。六边形顶点以60°为间隔:黄色位于60°处,绿色在120°处,青色在180°处,与红色相对,相补的颜色互成180°。
图2.4 HSV颜色模型
色饱和度S从0到1变化,在模型中它表示所选色彩的纯度与该色彩最大纯度(S=1)的比率。当S=0.25时所选色彩的纯度为四分之一;当S=0时,只有灰度。
明度值V从六边形顶点的0变化到顶部的1。顶点表示黑色。在六边形顶部的颜色强度最大。当V=1,S=1时,得纯色彩。白色是V=1且S=0的点。
HSV模型对多数用户是一个较直观的模型。从指定一种纯色彩开始,即指定色彩角H且让V=S=1,可通过将白色或黑色加入到纯色彩中来描述所要的颜色,增加黑色减小V,而S保持不变:要得到深蓝色,V=0.4,S=1且H=240°;同样,将白色加进所选色彩中时,参数S减小而V不变:浅蓝色用S=0.3,V=1且H=240°来设定;添加一些黑色和白色,则同时减小V和S。通常要有一个模型的接口给出颜色板中HSV参数选择。
结合明暗、色泽和色调等术语的颜色概念反映在HSV六边形的剖切平面中,如图2.4(b)所示。往纯色彩中添加黑色时,把V减小到六边形的下方。因此,各种明暗用S=I且0≤V≤1来表示。往纯色调中添加白色生成六边形顶部平面的各种色泽,该平面上V=1,0≤S≤1。同时添加白色和黑色可指定各种色调,生成六棱锥体三角形剖切面范围内的颜色点。
人眼大概能区分128种不同色彩和130种不同色泽(色饱和度级)。依赖于所选的色彩进一步还可区分若干种明暗。对黄色能分辨出23种明暗度,对光谱的蓝端能分辨16种,共约128×130×23=382720种不同的颜色。对多数图形应用来说128种色彩,8种色饱和度级别以及15种明度值就足够了。按HSV的这一参数范围,用户可使用16384种颜色,系统需使用14位存放每一像素的颜色。使用颜色查找表可减少存储器需求及增加可用颜色的数量。
5. HSI颜色模型
另一个基于直观颜色参数的模型是HSI系统。该模型表示为如图2.5所示的双圆锥体。该模型中的三个参数称为色彩(H),亮度(I)和色饱和度(S)。
图2.5 HSI颜色模型
色彩含义与HSV模型中相同。它指明所选色彩位置与水平轴之间的夹角。此模型中,H=0°与红色相对应。其余颜色按与HSV模型中同样次序围绕锥体逐一指定。
该模型的垂直轴称为亮度I。在I=0处为黑色,I=1处为白色。灰度则沿着I轴分布,且“纯色彩”位于I=0.5的平面上。
饱和度参数S也是说明颜色的相对纯度。该参数变化范围为从0到1,对纯色彩来说,S=1且I=0.5。当S减少时,色彩的纯度也减少。当S=0时,仅有灰度。
与HSV模型一样,HSI系统允许用户按选择色彩更暗些或更亮些的概念来思考。一种色彩通过色彩角H来选择,而所需的明暗,色泽及色调则通过调节I和S来获得。增加I使颜色更亮,减少I则使其更暗些。当S减少时,颜色向灰色变化。
2.3 视觉基础知识
2.3.1 视觉适应性
当我们从较明亮的地方进入光线较暗的场所时,就会看不清眼前的东西,但过一段时间后,视觉便慢慢恢复。人眼这种适应暗环境的能力称为暗适应性。通常这个适应过程约需30min。人眼所以有暗适应性,一方面是由于瞳孔放大的作用,更重要的是进行了视细胞的转换,此时由视杆细胞代替了视锥细胞,前者的视敏度比后者要大得多,从而对微弱的光刺激也有感觉。
人眼也有亮适应性。其过程通常只需要几秒,这是因为视锥细胞恢复工作所需的时间要比视杆细胞短得多。
2.3.2 视觉范围
视觉范围是指人眼所能感觉的亮度范围。这个范围非常宽,大约百分之几尼特到几百万尼特。但是人眼并不能同时感受这样宽的亮度范围,在人眼适应了某一平均亮度的环境之后所能感受的亮度范围要小得多。当平均亮度适中时,能感受的亮度上、下限之比为1000∶1;而当平均亮度较低时,该比值只有10∶1。
2.3.3 分辨力
人眼的分辨力是指在一定的距离上能区分相邻两点的能力,可用能区分最近两点之视角的倒数来描述。设d表示能区分的两点间的最小距离,L表示眼睛与上述两点连线的垂直距离,则
人眼的分辨力和环境照度有关,还和被观察对象的相对对比度有关,彩色也会影响人眼的分辨力。
2.3.4 同时对比效应
大小一样且具有相同亮度的四个小方块处于不同亮度背景之中,如图2.6所示。当人们同时观察小方块和背景时,会感到背景较暗的小方块较亮。这个事实反映了人眼对目标亮度的主观感觉不完全取决于目标本身的亮度,还和背景亮度有关。这种特性称为同时对比效应。
图2.6 同时对比效应
2.3.5 马赫带效应
图2.7是一张条状灰阶照片,每条内的亮度是均匀分布的,而相邻两条的亮度则相差一个固定值。但是人的亮度感觉却认为各窄条内的亮度不是均匀分布的,感到所有窄条内靠近更暗窄条的一侧有一较亮的条纹,而靠近更亮窄条的一侧有一较暗的条纹,这种在亮度出现变化的地方出现亮条纹和暗条纹的感觉现象称为马赫带效应。
图2.7 马赫带效应
上述现象说明视觉系统对亮度的突变有“过调”的响应,产生上冲和下冲,这意味着视觉系统有一高通滤波环节。从数学角度看,表明人类的视觉信号处理过程中存在微分运算。
2.3.6 视觉错觉现象
视觉系统所感觉到的物体的形状并不是简单地投影到视网膜上的原封不动的形状。对形状的感觉受到物体自身形状及周围背景的影响。这类影响是多种多样的,有神经系统引起的错觉现象也有心理因素的作用引起的视觉错觉。在错觉中,眼睛填充了不存在的信息或者错误地感知了物体的几何特点。视觉错觉是人类视觉系统的一个特性,其机理涉及复杂的生理、心理、医学、光学等多种因素,至今尚未完全了解。
图2.8是几张典型的视觉错觉图片。左上方的图中一个正方形的轮廓看得很清楚,尽管在图像中这些部分并没有线。相同的效果在右上方的图中也可以看到,此时可以看到一个圆,注意到仅仅是几根线就足以给出一个完整圆的错觉。这种现象被称为“知觉轮廓”,即图像本身没有,而是由人的视知觉产生的轮廓现象。在左下方图中两条水平线段实际长度是相同的,但是看起来明显上面的线段显得比下方的短。右下方的图中所有斜线都是等距离的平行线,然而画上交叉影线后就产生了错觉,觉得这些线不再平行。
图2.8 典型的视觉错觉
2.4 硬件基础知识
如1.4节所述,组成一个图形图像处理系统的硬件部分包含了输入设备、输出设备、交互设备、存储设备以及处理机,存储设备和图形图像处理机所涉及的学科更多的在于计算机硬件领域,而交互设备的实质也是一种输入设备,因此,在图形图像处理领域而言,我们关注的硬件更多在于输入设备和输出设备。
图形图像系统配置有多种图形输入设备,用以输入数据或操作命令。多数系统配有一个键盘和一种或几种专门用于交互输入的其他输入设备,如鼠标、轨迹球、游戏棒、数字化仪和光笔等。这些常用的图形输入设备归入一般应用输入设备类,另外还有一些适合特殊用途的输入设备,如数据手套、触摸板、图像扫描仪、数码相机等,将它们归入特殊应用输入设备类。
输出设备一般分为印刷输出设备和显示输出设备,印刷输出设备主要包括打印机、绘图仪等,用于将图形图像输出成为平面媒介,通常是纸质媒介;而显示输出设备包括阴极射线管(Cathode-Ray Tube,CRT)显示器、液晶显示器(Liquid Crystal Displayer,LCD)、等离子体显示器(Plasma Display Panel,PDP)、投影仪和某些特殊的三维显示设备等,它能直接显示图形图像,是图形图像处理中的一项重要设备,直接关系到图形图像的最终呈现,并且已经逐渐形成了信息显示技术这门学科。本节将重点介绍应用最广的CRT和LCD。
2.4.1 输入设备
1. 键盘
键盘作为计算机中最基本也是最重要的输入装置,经历着不断地改革和创新。
键盘的内部结构主要包括控制电路板、按键、底板和面板等。其中控制电路板是核心部分,位于键盘的内部,主要负责按键扫描识别、编码和传输接口工作。不论键盘形式如何变化基本的按键排列保持不变,分为主键盘区、数字辅助键盘区、F键功能键盘区和控制键区;而对于多功能键盘还增添了快捷键区,如图2.9所示。
图2.9 键盘
键盘通常采用行列扫描法来确定按键所在的行列位置。即按键排列成矩阵,需要用硬件或软件的方法轮转式地对其行、列分别扫描,以查询和确认是否有键按动。如有键按动,键盘就会向主机发送按键所在的行列矩阵的位置编码,称为键扫描码;然后转换为ASCII码,经过键盘输入/输出电路送入主机,并由显示器显示出来。
根据按键的结构,键盘可分为机械式键盘和电容式键盘。早期的键盘都是机械式的,特点是手感较差,击键时用力大,击键的声音大,手指易疲劳,键盘磨损快,故障率高,但维修比较方便。机械式键盘的按键全部为触点式,它的按键原理非常简单,每个按键就像一个按钮式的开关,按下去之后,金属片就会和触点接触而连通电路。目前常见的键盘按键都是电容式的,特点是击键声音小,使用寿命长,手感好,工作过程中不会出现接触不良等问题,而且灵敏性高,稳定性强;但由于采用密封组装(避免电极间进入灰尘),不可拆卸,所以不易维修。电容式键盘按键多采用电容式无触点开关,由于电容的容量是由介质、两极的距离及两极的面积来决定的,所以当键按下时,两极的距离发生变化,这就引起电容容量发生改变。当参数设计合适时,按键时就有输出,这个输出再经过整形放大,去驱动编码器。
键盘的接口有AT接口、PS/2接口和最新的USB接口。AT接口俗称“大口”,用于普通的计算机,一般由较老的主板提供。PS/2接口本是IBM公司的专利,俗称“小口”,现已广泛用于计算机上,并且越来越多的新型主板都开始提供PS/2键盘接口。若想实现两种接口的兼容性问题,可以使用转接线或者大小口键盘转换连接器。USB接口作为一种新兴的结构,伴随着闪存和移动硬盘的普及,越来越受到用户的青睐,一些公司也推出了USB接口的键盘,但是在实际应用中,由于受到驱动方面的限制,USB键盘并没有表现出更多的优势。
2. 鼠标
鼠标(又称鼠标器)是一种通过移动光标进行选择操作的计算机输入设备,具有给屏幕光标定位的功能,除了键盘外,它已经成为用户使用计算机的主要输入工具,如图2.10所示。在流行的视窗操作系统下,没有鼠标几乎是寸步难行,鼠标所特有的简便、灵活的特点是其他任何工具都无法代替的。
图2.10 各种形式的鼠标
1968年12月9日,鼠标诞生于美国加州斯坦福大学,它的发明者是Douglas Engle-bart博士。Englebart博士设计鼠标的初衷就是为了使计算机的操作更加简便,以代替键盘那种烦琐的指令。他制作的鼠标是一个小木头盒子,由盒子底部的小球带动枢轴转动,并带动变阻器改变阻值来产生位移信号,信号经计算机处理后,屏幕上的光标就可以移动。
鼠标的基本工作原理是:当移动鼠标时,它把移动距离及方向的信息变成脉冲送给计算机,计算机再把脉冲转换成相对坐标数据,再通过屏幕显示光标,从而达到指示位置的目的。
根据鼠标中测量位移的部件,可将鼠标分为光电式、光机式和机械式三种。
光电式鼠标是三种鼠标中可靠性最好的一种,它利用LED(发光二极管)、光敏晶体管的组合来测量位移。过去这种鼠标工作时要放在一块专用的光电板上,LED与光敏晶体管之间的夹角使前者发出的光照到光电板后,正好反射给后者。由于光电板上印有间隔相同的网格,鼠标移动时反射的光有强有弱,鼠标中的电路就将检测到的光强弱变化转换成表示位移的脉冲。光电式鼠标有两组这种发光/测光元件,分别用来测量x轴和y轴两个方向的位移。现在所使用的光电式鼠标已不再需要专用的光电板,利用了图像处理的功能,只要在不透光的平整表面就可正常使用。
光机式鼠标只要一块光滑的桌面即可工作,它也用光敏半导体器件测量位移,其中装有三个滚轴:一个是空轴(起支撑作用),另两个分别是x方向滚轴和y方向滚轴。这三个滚轴都与一个可以滚动的小球接触,小球的一部分露出鼠标底部。当拖动鼠标时,摩擦力使小球滚动,小球带动三个滚轴转动,x方向和y方向滚轴又各带动一个小轮(称为译码轮)转动。由于放在两组传感器(传感器A和传感器B,用于识别鼠标移动方向)中的译码轮上刻有一圈小孔,因此当译码轮被带动时,由LED发出而照到光敏晶体管上的光就会时而被阻断,从而产生表示位移的脉冲。传感器A与传感器B的位置被安放成使脉冲A与脉冲B有一个90°的相位差,利用这种方法,就能测出鼠标的移动方向(如前进或后退)。也就是说,脉冲A的相位比脉冲B的相位提前90°时,表示一个位移方向;反之,表示另一个位移方向。
机械式鼠标实际上是机电式鼠标,其中测量位移的译码轮上没有小孔,而是一圈金属片,译码轮插在两组电刷对之间。当它旋转时,电刷接触到金属片就接通开关;反之则断开开关,从而产生脉冲。译码轮上金属片的布局以及两组电刷对的位置,使两组电刷对产生的脉冲有一个相位差,根据相位差可以判断鼠标的移动方向。
在鼠标发明后的30年时间里,人们对鼠标进行了不断的改造和创新,各种款式新颖的鼠标层出不穷。除了上面介绍的基本类型外,还有轨迹球鼠标、网络鼠标、无球鼠标、红外线鼠标等。
轨迹球鼠标从外观上看就像是翻转过来的机械式鼠标,用手拨动轨迹球来控制光标的移动。工作时球在上面,直接用手拨动,而球座固定不动,因而占用空间小,多用于便携机。轨迹球配有两个按钮,为选择提供方便。在笔记本式计算机上可以看到这种鼠标,用起来十分贴手。
网络鼠标相对于普通鼠标多了一个或两个滚轮按键,在浏览网页或处理文档时只需拨动滚轮即可实现翻页功能,不必再拖动滚动条,十分方便。
无球鼠标是Microsoft公司新推出的一款鼠标,它的最大特点之一是底部没有一般传统鼠标所具有的那只滑鼠球;另一个特点是全部实现了数字化,在鼠标内没有任何移动部件,全部功能都由装设在鼠标里面的DSP(数字信号处理器)完成,其操作速度比目前人们使用的传统鼠标快10倍以上。
另外,市场上还出现了红外线鼠标,需在鼠标内装入电池,并在串行通信口上接红外线通信盒,鼠标用红外线通信方式与主机进行通信。随着蓝牙技术(一种短距离无线连接技术)的广泛应用,目前市场上也出现了更多的无线鼠标产品。
鼠标按照接口分类可分为三种:串行接口、PS/2口和USB接口。串行接口鼠标就是人们常说的“大口”,它接在计算机的串口上,目前基本上被淘汰;PS/2接口鼠标即人们常说的“小口”,接在主板上专门给鼠标留的PS/2接口上;USB接口鼠标是相对较新的产品,具有支持热插拔的特点,在笔记本电脑上应用广泛。
3. 光笔
光笔是一种检测装置,确切地说是能检测出光的笔。光笔的形状和大小像一支圆珠笔,笔尖处开有一个圆孔,荧光屏上的光通过这个孔进入光笔。光笔的头部有一组透镜,把所收集的光聚集至光导纤维的一个端面上,光导纤维再把光引至光笔另一端的光电倍增管,从而将光信号转换成电信号,经过整形后输出一个有合适信噪比的逻辑电平,并作为中断信号送给计算机和显示器的显示控制器。光笔的这种结构和工作过程如图2.11所示。还有一种光笔的结构是将光电转换器件和放大整形电路都装在笔体内,这样可省去光导纤维,光笔直接输出电脉冲信号。
图2.11 光笔结构示意图
光笔上的按钮开关控制电脉冲是否被输出。工作时,光笔将荧光屏当作图形平板,屏上的像素矩阵能够发光,当光笔所指的像素被激活,像素发出的光就被转换为脉冲信号。这个脉冲信号与扫描时序进行比较后,便得出光笔所指位置的方位。
光笔原理简单、操作直观,是早期CAD系统中最主要的图形输入设备。光笔具有定位、拾取、笔画跟踪等多种功能,不过它本身容易损坏,在通常的图形输入设备中已很少使用,但是目前在某些射击类的游戏外部设备中,基于光笔原理的外部设备仍然应用广泛。
4. 数字化仪
数字化仪(digitizer)是一种能够直接跟踪图形,把图形信息转换成计算机能接收的数字量的专用图形输入设备,其工作方式有电磁感应式和回声式等多种。
采用电磁感应技术制作的电磁感应式数字化仪是在一块布满金属栅格的绝缘平台上放置一个可移动的定位装置——游标。游标内嵌有一个电感线圈,它的小透明窗口中有一个由两根细丝直交的十字,其交点为定位参考点,用它来跟踪。当有电流流过游标中的线圈时,产生感应磁场,从而使其正下方向金属栅格上产生相应的感应电流。根据已产生电流的金属栅格的位置,就可以测得游标当前的位置,获得其坐标值,完成图形几何位置的量化过程,实现了数字化功能。
还有的数字化仪采用回声的方式工作,在一块长方形平板的两相邻边装上条状麦克风,用以接收声音信号,一支连在电缆线上的细笔称作触笔,它们构成了一个数字化仪。连接触笔的电缆中通过周期性脉冲电流,操作人员手持触笔跟踪图线并轻压笔尖,脉冲电流在笔尖处产生火花并伴有爆裂声,这个声音以不同的时间延迟被条状麦克风接收,传到水平与垂直两个方向麦克风的时间延迟乘以声速便是笔尖到它们的距离,于是测得了笔尖所在位置的坐标值。
一些大型的台式数字化仪通常还被称作数字化桌(digitizing table),用于大幅图面图形输入,而较小尺寸的数字化仪也称作图形输入板(tablet),通常放在桌面上,用做小型图面的图形输入。
5. 触摸屏
触摸屏(touch screen)也是一种定位装置,它是一种对于物体触摸能产生反应的屏幕。当人们的手指或其他的物体触碰到屏幕的不同位置时,计算机能接收到该触摸信号并按着软件的要求进行相应的处理。根据所采用的技术,触摸屏分为电阻式、电容式、红外线式和表面声波式几种。
电阻式触摸屏是将两层导电的透明薄膜涂层涂在玻璃或塑料表面上,再安装到屏幕上或直接涂到屏幕上。这两个透明涂层之间有0.0025mm的间隙,当手触碰屏幕时,接触点产生一个电接触,使该处的电阻发生变化。通过测得屏幕水平与垂直方向上的电阻值的改变就可测出该触摸点的位置坐标。
电容式触摸屏是将接近透明的金属涂层覆盖在一个玻璃表面上,当手接触到这个涂层时,由于电容的改变,使得连接在一角的振荡器产生的振荡频率发生变化,根据频率改变的大小就可确定触摸的位置。
电阻式和电容式触摸屏对涂层的均匀度和测量精度要求较高,工艺难度较大,因而它的售价较高,而且使用不慎易受损坏,所以应用受限。
红外线式触摸屏利用红外线发射与接收原理,屏幕的一边由红外发光器件发射红外光,与之相向的另一边设有接收装置检测光线被遮挡的情况。红外线触摸屏通常有两种结构:一种是直线接收式,它是由两列互相垂直的红外发光器件在屏幕的上边和左边与屏幕平行的平面上组成网格,而在下边和右边用光电器件接收。当手指触到屏幕上的某个位置时,就会挡住一些光束,相应位置的光电器件就会因为接收不到光线而使输出电平发生变化,在水平与垂直方向上发生变化的相应位置就构成了手指所触屏幕位置的坐标。另一种是倾斜角光束扫描式,它利用扇形的红外光束从屏幕的两角照射屏幕,平行于屏幕形成一个光平面。当产生触摸时,通过测量投射到另外两边的阴影覆盖范围来确定触摸的位置。倾斜角光束扫描式产生的数据量大,需要一个解算过程,要求机器有较高的处理速度,但它的分辨率要比直线接收式的高。红外线式触摸屏由于价格低、分辨率较高而得到了较普通的应用。
声表面波触摸屏由压电变送器、反射器和触摸屏器件组成,它们可以固定在一块平的或微曲的玻璃表面上,也可以直接固定在显示器屏幕的外表面上。压力变送器在声表面波控制器的控制下用5.53MHz的晶体振荡器驱动,将电能转换为高频振荡,这个高频声波沿玻璃表面传送。反射器沿屏幕的上边和右边排列,它的功能是将声波反射。当被反射的声波到达屏幕相对的另一个边时,又被另一个反射器反射并送到位于屏幕右下角的接收器中,接收器将声波转换成电信号。当手指触到屏幕时,通过触及位置的声波发生衰减,声表面波控制器将这些衰减声波的电信号根据其到达接收器的时间延迟不同而计算出触摸点的x,y坐标。声表面波触摸屏具有很高的分辨率,它的价格居中,使用也较方便,也是比较实用的一种触摸屏。
6. 数码相机
数码相机(digital camera)是专门用来获取数字化图像的照相机。如图2.12所示,虽然从外观上看数码相机很像一架普通的光学相机,它也有机身、镜头和闪光灯等部件,但数码相机与光学相机的内部结构大不相同。数码相机利用电荷耦合器件成像,图像存储在半导体器件上。
数码相机作为计算机的输入设备,将存储在半导体器件上的图像输入到计算机中,并利用相应的软件(如Photo-shop)进行编辑处理,然后用彩色打印机打印输出,生成彩色“照片”。数码相机的图像一般存储在芯片中,而且它的图像存储介质可以反复使用。
图2.12 数码相机
最早的数码相机摄入的图像是存储在一个特殊的内存中。内存的容量限制了存储照片的数量,特别是存储高分辨率图像时,对内存空间的要求就更大。而内存是无法随时扩充和更换的,当内存已经被占满后,就必须将图像输入计算机或将它们删除,这对外出拍照很不方便。为解决这个问题,目前的数码相机使用存储卡来存储图像,既经济,又方便,可以随时更换、插拔,而且存储容量大。
7. 数据手套
在某些情况下,获得关于用户手的详细跟踪信息是非常有用的,如手指怎样弯曲、两个手指是否相互叠在一起等,数据手套就是可以提供这类信息的输入设备。
数据手套通常用于手势和手形识别,可以被用在各种不同的交互技术中。例如,手腕的轻摇可以暗示用户想要删除一个对象。一个指点手形可以象征诸如驾驶的漫游技术。通常,手形和手势常用作系统控制技术中的系统指令。值得注意的是,如果希望识别一些手势(如挥手),则必须在数据手套上附着一个运动跟踪器。
在一些三维用户界面设计中,需要用户的手或双手的虚拟表示。结合了跟踪系统的数据手套可以提供这样的表征。一般来说,在用户的视野中的真实世界被完全遮挡住的时候,这类表征是非常有用的,用户需要看见他的手和其他的虚拟对象一起处在场景中。例如,用户可能希望知道在一个虚拟车的内部他的手的位置以及与各种刻度盘和控件的关系。
数据手套通常有5~22个传感器。比如,5个传感器的手套通常测量每个手指的一个关节,而18个传感器的手套可以测量每个手指至少两个关节、手指间的外展、腕关节的扭曲和偏转及其他信息,它有两种基本类型:弯曲感觉手套和压力手套。
弯曲感觉数据手套是完全被动的输入设备,用来检测用户的手形(静态的形状)和特定的手势(一系列的手形)。例如,设备可以区分拳头、指点手形和张开的手。手套获得的原始数据常常是以测量的关节角度给出的。根据这些测量结果,通过软件可以判定手形和手势。
这些年通过使用各式各样的传感器开发了很多数据手套。比如,基于光的传感器使用一端带有光源另一端是光电池的柔性管。当手指弯曲时,击中光电池的光线数目会变化,从而生成一个测量结果。另一种基于光的方法是使用带有内部反射面的柔性管组成的光纤角度仪传感器,一端放置光源,另一端放置光敏探测器,探测直接的和反射的光线。依靠软管的弯曲度,探测器可以根据光强度的变化而改变它的电阻。这类基于光的传感器被用在较早的第一代数据手套中。今天,有更多精密的传感器技术可以使用,比如光纤传感器、电阻墨水传感器和张力测量器弯曲传感器。不论是哪种类型的传感器,它们通常都是嵌入到手套中或者放在手套表面。
弯曲感觉手套的一个主要优点是它能提供大量的自由度信息,使得它不但可以识别各种手势和手形,而且可以给3D应用提供用户的手的表征,但是弯曲感觉手套有时需要根据不同用户的情况进行校准。
压力手套系统是一种判断用户是否将两个或多个指尖接触在一起的输入设备。这类手套的每个指尖有一个导电材料,这样用户可以通过两个手指的捏压产生一个电路连接。这类设备通常用来在物体选取、模式转换和其他一些技术中,用于判断用户的抓取和捏压手势。
这种设备的一个有趣的特点是:在手套的背部沿着手指和拇指的方向也有导电布料。例如,如果在指尖上附着一个跟踪器,用户可以通过将被跟踪的指尖和另一只手套的背部半导体布料条带的连接来做一个简单的滑动手势。当连接建立以后,用户沿着半导体条带上下滑动的时候,系统可以判定被跟踪的指尖的位置。如果在另一只手套上附着另一个跟踪器,则可以很轻松地判断用户在做手势时手指是移近手腕还是远离手腕。这种简单的技术被用来调整对象的大小或增减参数值。
和手持式输入设备相比,压力手套非常轻,能够降低用户的疲劳度。它还同样提供双手交互。虽然这个设备事实上可以产生上千种捏压组合,提供从输入设备到任务映射的很大的设计空间,但是只有少数是有用的、适合人类功效操作的。
2.4.2 CRT的工作原理
CRT是图形显示器的核心,电视机中的显像管也是CRT,大多数的视频监视器的操作都是基于标准的CRT而设计的。
CRT的基本工作原理是:由电子枪发出的电子束(阴极射线),通过聚焦系统和偏转系统,射向涂覆荧光层的屏幕上的指定位置。在电子束冲击的每个位置,荧光层发出一个小的亮点,从而产生可见图形。
1. CRT的结构
CRT主要由5个部分组成:电子枪、聚焦系统、加速电极、偏转系统和荧光屏。
图2.13 CRT结构示意图
(1)电子枪:由灯丝、阴极和控制栅组成。阴极由灯丝加热发出电子束;控制栅加上负电压后,能够控制带负电的电子束的强弱,通过调节负电压高低来控制电子数量,即控制荧光屏上相应点的亮度。
(2)聚焦系统:保证电子束在轰击屏幕时,会聚成很细的点。
(3)加速结构:加速电极上加正的高压电压(几万伏),使电子束高速运动。
(4)偏转系统:用静电场或磁场控制电子束运行的方向,产生偏转。电子束要到达屏幕的边缘时,偏转角度就会增大。到达屏幕最边缘的偏转角度称为最大偏转角。最大偏转角是衡量系统性能的最重要的指标,显示器长短与此有关,CRT显示器屏幕越大整个显像管就越长。
(5)荧光屏:含有荧光物质,当它被电子轰击时发出亮光。这里存在一个持续发光时间的概念,即电子束离开某点后,该点的亮度值衰减到初始值1/10所需的时间。因此要保持显示一幅稳定的画面,必须不断地发射电子束,即刷新。
CRT的技术指标主要有两条,一是分辨率,二是显示速度。一个CRT在水平和垂直方向单位长度上能识别出的最大光点数(光点亦称之为像素)称之为分辨率。分辨率主要取决于CRT荧光屏所用荧光物质的类型、聚焦和偏转系统。显然,对相同尺寸的屏幕,点数越多,距离越小,分辨率越高,显示的图形就会越精细。常用CRT的分辨率在1024× 1024像素左右,即屏幕水平和垂直方向上有1024个像素点,高分辨率的图形显示器分辨率达到4096×4096像素。分辨率的提高,除了CRT自身的因素外,还与确定像素位置的计算机字长、存储像素信息的介质、A/D转换的精度及速度有关。衡量CRT显示速度的指标一般用每秒显示矢量线段的条数来表示。显示速度取决于偏转系统的速度、CRT矢量发生器的速度、计算机发送显示命令的速度。CRT采用静电偏转速度快,满屏偏转只需要3μs,但结构复杂,成本高;采用磁偏转速度较慢,满屏偏转需要30μs。通常CRT所用荧光屏材料的刷新频率在每秒20~30帧。
2. 彩色CRT
对于图形显示来说,采用彩色显示不仅增加了美术感染力,而且大大提高了显示信息量。在单一颜色的显示设备中,只能依靠线型、位置、尺寸和亮度的不同来表示各种不同类型的数据。如果引入彩色,则可以依靠颜色来表示更多的信息,以突出显示内容的重点、类型等。显然,彩色显示比黑白显示具有更好的效果。
显示设备中常用的彩色CRT有两种:一种是荫罩(荫罩指安装在荧光屏后面约l0mm处的薄钢板,其上开有许多孔或槽,看上去像纱罩)式彩色CRT;另一种是电压穿透式彩色CRT。
电压穿透式彩色CRT通常是一红一绿两层荧光层涂覆在CRT荧光屏的内层。不同速度的电子束能穿透不同的荧光粉层而发出不同颜色的光。电子束所产生的颜色依赖于电子束穿透荧光粉层的深浅。或者说,电子束的速度决定了屏幕上光点的颜色。例如,低速电子束只能激励外层的红色荧光粉而发出红光;高速电子束则可穿透外层而激励内层发绿光的荧光粉层而发出绿光:中速电子束则同时激励两层的荧光粉而发出两者的组合光(橙色光和黄色光)。因此,电子束穿透法用于随机扫描监视器,是随机扫描监视器生成彩色的廉价途径,成本低,价格便宜,但它一般只能产生四种颜色(如红、橙、黄和绿),同时其显示图形的质量相对较差,所以现在一般已被淘汰。
在电视机中最早使用的荫罩式彩色CRT是三枪三束式彩色CRT。1970年前后研制成功了单枪三束管,它比三枪三束管有了很大的进步。1973年,又推出了一种更优良的自会聚彩色CRT,为目前电视机和计算机显示终端所广泛使用。表2.1列出了荫罩式彩色CRT的各种类型及其结构特点。
表2.1 荫罩式彩色CRT的各种类型及其结构特点
图2.14所示为两种典型荫罩式彩色CRT的结构简图。一种是圆形荫罩孔,荧光粉点也是圆的,电子枪呈“品”字形排列,并略向管轴倾斜,为“影孔板、点状屏”彩色CRT,如图2.14(a)所示。这种结构是最原始的,但在显示终端领域至今仍占主导地位,其原因是分辨率比其他结构高,图像表现稳定。另一种采用长条缝隙形荫罩和交替地涂有红、绿、蓝垂直粉段的荧光屏,电子枪呈“一”字形排列,称为“槽形板、条状屏”结构,如图2.14(b)所示。
图2.14 两种荫罩结构示意图
以图2.14(a)荫孔板、点状屏为例,相邻的红、绿、蓝三个荧光粉点成等边三角形排列,构成一个三色点组(traids)。当三支电子束分别激发它们时,便发出红、绿、蓝三基色光。由于这三个光点靠得很近,落在人眼视网膜同一视敏细胞上,于是人眼感觉到的是合成了的彩色。满屏大约有40万个三色点组,必须保证红、绿、蓝三支电子束分别打到对应的红、绿、蓝三色荧光粉点上,否则就会使显示出来的彩色不纯或出现色斑,称为色度误差,引起色纯(purity)不良;同时从一个荫罩孔射出的三支电子束必须打到同一个三色点组上,也就是要求三支电子束要在荫罩孔处会聚(conver-gence)。
如果三支电子束会聚有误差(或称为失会聚),并达到人眼觉察的程度,就会看到大面积颜色失真,或显示的字符/图形有彩色镶边。由此可见,彩色CRT比起单色CRT来,制造工艺要复杂得多。
图2.15 电子束轰击荧光屏示意图
如果把图2.14(a)的局部区域加以放大,如图2.15所示,就可清楚地看出电子束穿过荫罩板时的情况。为了保证在偏转扫描时三个电子束与相应的荧光粉点有良好的一一对应关系,实际在荫罩板处电子束的直径必然要大于荫罩孔的直径,因此在工作中荫罩板截获了相当大部分的电子,实际只有大约全部束电流的15%~20%能到达荧光屏去激发荧光粉发光,而80%~85%的电子都打到荫罩板上变成热能消耗掉了。可见,电子能量的利用率是很低的。为了提供足够的亮度就必须提高加速阳极的电压。通常彩色CRT的加速阳极电压高达20~25kV,三个电子束的总电流约在1mA左右,比普通单色管(最大束电流约100μA)要大得多。在这种高压下,会产生较多的X射线辐射,为此彩色CRT玻璃壳内通常要加入防X射线辐射的氧化铝或氧化锶等元素,以防止X射线对人体健康的影响。
显然,图2.14(b)所示的槽形荫罩比影孔板截获电子要少些,束电流的30%以上可有效地激发荧光粉发光。现有的彩色电视机显像管普遍采用这种结构,它与前一种结构相比水平分辨率低一些,但被荫罩截获的电子少,发光效率更高,彩色也更鲜艳。
此外,还有一种障栅(aperture grill)型结构,可叫做荫栅式彩色CRT。采用紧固的垂直金属丝代替荫罩,屏幕上的荧光粉涂成垂直整条,对应于荫孔板可称为“隐条板、条状屏”:电子枪成呈“一”字形排列,屏幕为柱面。习惯上把这种结构的显像管称为“特丽珑”(Trinitron)管,其实际含义是单枪三束彩色显像管或栅条彩色显像管的意思。特丽珑管截获的电子比槽形板还少,显示的图像更靓丽;不会像荫孔板那样产生“莫尔”(Moire)效应(所谓莫尔效应是指当显示分辨率等于或小于CRT荫罩孔的极限分辨率时产生木纹式图案的现象);也不容易因局部发热变形而引起色纯度变化;同时,柱面屏在水平方向几乎没有几何失真,会聚校正也简单一些。
障栅结构的不足之处如下:
重——必须拉紧金属丝,像钢琴架子一样,有笨重的支撑结构。
贵——价格与重量成比例。
柱面屏——这一点根据个人的嗜好,也可能是优点,近年来已发展为平面屏。
有固定的可见金属丝——在高分辨率CRT中,为使特丽珑管不受机械振动和冲击的影响,需要1~3 条金属丝横跨于屏上。一般对角线尺寸在38cm以下的管子只需一条,38~54cm的管子需两条,54cm以上需三条。在显示的图像亮度较大时,屏幕上可看出这些横线。这一点在某些特定的应用场合(如医疗诊断应用)是难以接受的。
特丽珑管是索尼公司的专利。三菱公司在索尼公司的特许下制作出了“钻石珑”(Diamondtron)CRT,其细微的差别是采用了三枪三束电子枪设计,使得在整个CRT屏面上光点均匀一致。
3. 光栅扫描原理
光栅扫描方式中,电子束总是不断地从左到右、从上到下反复扫描整个屏幕,在扫描过程中,只要在对应时刻在对应位置控制电子束的强度就能显示所要的图形。电子束横向从左到右扫描一次称为一条扫描线,在每条扫描线末端,电子束返回到屏幕的左边,又开始显示下一条扫描线。每条扫描线扫过后,返回到屏幕左端。而从屏幕顶部到屏幕底部(纵向)的扫描线构成一帧图像。一帧图像是光栅显示系统执行一次全屏幕循环扫描(一次屏幕刷新)所产生的图像。每帧终了,电子束返回到屏幕的左上角,开始下一帧。
光栅扫描显示器每秒刷新的循环数称为CRT的刷新频率。大多数光栅图形显示设备使用电视监视器作为输出设备,并且为了产生无明显闪烁的图像,每秒至少必须执行30次循环。一般,光栅扫描显示器的刷新是按每秒60~80帧的速率进行的,但有些系统设计成更高的刷新速率。有时,刷新频率以每秒多少周期或赫兹(Hz)为单位来描述的:一个周期对应于一帧。每秒60帧的刷新频率为60Hz。
电子束的扫描有两种方式:逐行扫描和隔行扫描,如图2.16所示。逐行扫描是指扫描线在屏幕上自上而下一条一条地扫描。当电子束从左到右到达屏幕的右边,在每条扫描线末端电子束又返回到屏幕的左边,重新开始显示下一条扫描线。在回扫过程中,电子束几乎不发射出电子,而且速度也很快。回扫有两种:每条扫描线扫过后,返回到屏幕左端称为水平回扫;而当电子束到达屏幕底部时,又返回到屏幕的左上角称为垂直回扫。然后,从头开始扫描下一帧。
图2.16 两种不同的扫描方式
某些光栅扫描系统(TV)中采用隔行刷新方式,每帧显示分为两趟:第一趟,电子束从顶到底,一行隔一行地扫描;第二趟,垂直回扫后,电子束则再扫描另一半扫描线。以这种方式的隔行扫描使在逐行扫描所需时间的一半时就能看到整个屏幕显示。隔行扫描技术主要用于较慢的刷新速率。例如,对一个较老的每秒30帧的非隔行扫描显示,可注意到它的闪烁。采用隔行扫描,两趟中的每一趟可以1/60秒完成,也就是说,刷新速率接近每秒60帧。这是避免闪烁且提供相邻扫描线包含类似的显示信息的有效技术,也是降低成本而不增加闪烁感的有效办法。
4. 帧缓存
每条扫描线是由一系列像素组成,或者说,光栅扫描显示器显示一幅画面是由称为像素(pixel,picture element)的小点组成;光栅扫描生成的图像中所有像素的强度值都要存放在一个存储器中,这个存储器称为帧缓存(frame buffer)或刷新存储器(refresh buff-er),俗称显示存储器。光栅扫描显示是通过读取存储器中的强度值并在屏幕的适当位置显示图像。
光栅扫描系统的帧缓存对屏幕每一点都有存储强度/颜色信息的能力。帧缓存的单元个数至少与显示器能显示的像素总数相同,且存储单元一一对应于可寻址的屏幕像素位置。光栅扫描系统能较好地适用于包含细微阴影和彩色模式的场景的逼真显示,因此,光栅扫描显示器具有丰富的灰度和色彩,能产生真实感很强的复杂图形。
在每像素一位(0和1两个值)系统中,每个屏幕点或亮或暗,只需一个二进制位来控制屏幕位置亮度,这时的帧缓存通常叫做位图(bitmap);彩色显示和单色多灰度显示时,要能显示彩色并且强度可变,就需附加位,每个像素需要使用多个二进制位表示,此时,帧缓存常常视为像素图(pix-map)。
帧缓存每一个存储单元的位长决定了一幅画面上能同时显示的不同灰度的数目或颜色的种类,位长为n的存储单元在一幅画面上能同时显示的不同灰度的数目或颜色的种类为2n,在采用彩色表之前,一幅画面上能同时显示的灰度等级数或颜色种类与显示器能显示的灰度等级数或颜色种类数相同。高质量的光栅图形系统的帧缓存中每个像素对应24位,即每个电子枪发出的电子束的强度有256个等级,则该显示器能显示:28 ×28 × 28=224=16兆种颜色。帧缓存的容量一定时,分辨率越大,帧缓存中每个单元可分配的位长越小,可同时显示的颜色种类也越少。例如,具有1MB的帧缓存,若分辨率为640× 480,则帧缓存每单元的位长就为24位:若分辨率为1024×768,则帧缓存每单元的位长就为略多于8位。
帧缓存的容量往往设计得比屏幕画面的位图大得多。也就是说,帧缓存可以同时存放多幅画面的位图,这时帧缓存区域可分成若干页面,每个页面存放一幅位图,并通过控制器就实现不同画面的切换。页面的大小可以划分得比屏幕位图大得多,甚至是整个帧缓存。这时,从程序员的角度来看,可输出显示的画面将远大于实际的物理屏幕,此时物理屏幕仅是一个窗口,它显示的不过是全部画面的一部分,通过上下滚动(scroll)和左右移屏(shift)功能,用户可以看到帧缓存中的整个画面。
帧缓存的存储量由系统的分辨率决定。每个像素24位,而屏幕分辨率为1024× 1024的系统需要3MB存储量作帧缓存。可见用于高分辨率彩色显示时所需要的帧缓存的开销是相当高的。
5. 彩色查找表
彩色查找表或颜色索引技术是不增加帧缓存存储容量而得到更多颜色的一种技术,它在帧缓存与显示屏的数模转换器之间加一个查色表(color lookup table,又称调色板)。
彩色查找表(彩色表)可看成是一维线性表(如图2.17所示),每一项(元素)对应于一种颜色,但帧缓存中每个单元存储的是对应于某一像素颜色在彩色查找表中的地址,而不是颜色值。彩色表的地址长度由帧缓存每个存储单元的位数决定,这确定了一幅画面能同时显示的颜色种类数;彩色表的宽度(元素位长)由帧缓存每个存储单元的基色数决定,这决定了显示器可选择显示的颜色种类总数。
图2.17 彩色查找表示意图
彩色表中元素的位数可取得很大,这样的颜色可以变化得更细致,扩大了可选择显示的颜色范围,每一种独立的颜色成分可以定义为更高的精度。但每幅图上同时出现不同颜色的总数目仍然是由帧缓存每一单元的位数决定,只是它的内容可以自由设置,显示器能显示的颜色都可被彩色表选用。对一幅图像来说,所用的彩色种类并没有增加,但可方便地修改彩色表,可使广泛的颜色出现在各帧画面上,总的来说扩大了色彩的范围。使用彩色查找表技术,使得即使帧缓存每个存储单元的位数不增加,也能具有在很大范围内挑选颜色的能力。例如,像素帧缓存为8位,彩色表中包含红、绿、蓝三种颜色,每种颜色用4位存储,则彩色表共有28=256个地址,每个地址单元的元素位长为3×4=12位,能够表示的颜色总数则为212=4096。假设每一个基色用8位表示,那么彩色表的宽度就为24位,这样可得到1600多万种颜色的可能,这被称之为1600多万种颜色中同屏显示256种颜色,记为:256/16777216。
彩色表的使用还增加了一些附加功能。例如,彩色表内容全部置成背景色可快速清除屏幕画面;将彩色表中某两种颜色的索引对换,则可以在不扫描全体像素的基础上实现图图像中颜色的互换。
6. 光栅扫描系统
交互式光栅扫描系统的结构如图2.18所示,系统中通常使用几个处理部件。除了中央处理器(CPU)以外还使用一个显示处理器也有称为图形处理器(Graphic Process Unit,GPU)来控制显示设备的操作,显示处理器的用途是使CPU从图形杂务中解脱出来。除了系统存储器外,还提供独立的显示处理器存储区域,帧缓冲器可在显示存储区的任意位置,显示处理器访问帧缓冲器以刷新屏幕。视频控制器主要用于直接驱动CRT以进行硬件相关的操作。除了GPU,更复杂的光栅系统常常运用其他处理器作协处理器和加速器,并执行各种图形操作。光栅扫描系统中帧缓冲器使用系统存储器的固定区域且由显示处理器直接访问。
图2.18 交互式光栅扫描系统的结构
除了基本刷新操作外,显示处理器还能执行一些其他操作。对于多类应用,显示处理器在不同刷新周期内可从不同存储区取出像素强度值。例如,在高性能系统中,常常提供两个帧缓冲器,一个缓冲器用来刷新的同时,另一个以强度值填充:然后,这两个缓冲器可互换角色,这提供了生成实时动画的快速机制,因为在当前帧屏幕刷新的同时,下一帧数据可以在后台同步进行加工并装入另一个缓冲器。
2.4.3 液晶显示器的工作原理
CRT固有的物理结构限制了它向更广的显示领域发展,屏幕的加大必然导致显像管的加长、显示器体积的加大,在使用时就会受到空间的限制;另外CRT是利用电子枪发射电子束来产生图像,容易受电磁波干扰,长期的电磁辐射也会对人的健康产生不良影响。
随着材料科学的发展,越来越多的新材料被应用到显示器的设计中,液晶(Liquid Crystal)就是其中的一种。液晶是一种介于液体和固体之间的特殊物质,它具有液体的流态性质和固体的光学性质,在一定温度范围内既有各向异性的晶体双折射性,又有液体的流动性,是一种不同于固体(晶体)、液体(各向同性物质)和气体的特殊物质态。当液晶受到电压的影响时,就会改变其物理性质而发生形变,此时通过它的光折射角度就会发生变化,而产生色彩。1888年,奥地利植物学家莱尼茨尔(F.Reinitzer)首先发现了液晶。1963年,美国无线电公司的威廉斯(R.Williams)发现向列型液晶层上施加电压时会使其变混浊。1968年,海尔梅尔(G.H.Heilmeier)进一步研究了这一现象,并利用这种现象研制了数字、字符显示器件和液晶钟表、驾驶台显示器等一系列应用产品,由此开创了液晶在显示领域应用的新纪元。1969年,日本NHK的研究引起日本科技界、工业界的高度重视,将当时的大规模集成电路与液晶相结合,以个人电子化市场为导向,很快打开了液晶的应用局面,促成日本微电子工业在20世纪70年代的惊人发展。几十年来,一批当代科学家十分关注液晶技术,并为此做出了杰出的贡献,使液晶从理论到实践不断发展、不断完善,形成为一门独立的学科。
一台显示器要正常工作,必须解决4个方面的问题:通断的形成——如何控制显示的亮和暗;颜色的产生——如何产生显示所需要的各种颜色;定位的控制——如何在需要的任意位置显示信息;刷新的实现——如何产生持续稳定的显示画面。对于液晶显示器(Liquid Crystal Displayer,LCD),它的工作原理实质上就是针对这四个问题的解决方案。
1. 通/断的形成
LCD技术是把液晶灌入两个列有细槽的平面之间。这两个平面上的槽互相垂直(相交成90°)。也就是说,若一个平面上的分子南北向排列,则另一平面上的分子东西向排列,而位于两个平面之间的分子被强迫进入一种90°扭转的状态。由于光线顺着分子的排列方向传播,所以光线经过液晶时也被扭转90°,如图2.19(a)所示。但当液晶上加一个电压时,分子便会重新垂直排列,使光线能直射出去,而不发生任何扭转,如图2.19(b)所示。
图2.19 液晶的排列
光是横波,其振动方向垂直于光的传播方向,而自然光线是朝四面八方随机发散的,当光穿越偏振片时,只有振动方向与偏振片方向一致的光能够穿过,这就形成了单一偏振方向的偏振光。LCD正是由这样两个相互垂直的偏振片构成,在液晶平面的上方放置水平偏振片,而在下方放置垂直偏振片,在正常情况下应该阻断所有试图穿透的光线。但是,由于两个偏振片之间充满了扭曲液晶,所以在光线穿出第一个偏振片后,会被液晶分子扭转90°,最后从第二个偏振片中穿出,这就形成了显示的“亮”信号。另外,若为液晶加一个电压,分子又会重新排列并完全平行,使光线不再扭转,所以正好被第二个滤光器挡住,于是就形成了“暗”信号。加电将光线阻断,不加电则使光线射出,这就构成了显示的通/断。
2. 颜色的产生
LCD中颜色的产生实质上和通/断的形成密切相关,将每个液晶显示单元细化成为可以独立控制通断的三个小单元,并在每个小单元的光路上添加红、绿、蓝三色滤色片。当光路导通时,小单元就产生相应颜色的单色光,三个小单元分别导通,就能够产生红绿蓝不同的组合,从而形成不同的颜色。例如,红色单元和绿色单元导通,蓝色单元断开,这种组合就使得整个显示单元呈现出黄色。
3. 定位的控制
LCD中的关键部件就是液晶显示面板,而面板是实际上是由许多显示单元按照行列组合排列而成,一个或多个单元就构成屏幕上的一个像素。在面板的玻璃外壳与液晶材料之间是透明的控制电极,电极分为行和列,在行与列的交叉点上,可以通过改变电压而改变光路的通断状态。通过这种机制,就可以很方便地利用行列寻址找到相应的控制电极,对相应的控制电极改变电压,就能实现在特定位置上像素的显示。
4. 刷新的实现
CRT由于其荧光点发光时存在衰退现象,因此就需要持续不断的用电子束轰击,以维持稳定的发光状态。而LCD由于通过控制是否透光来控制亮和暗,当电压不变时,液晶的旋光性也保持不变,于是发光状态也就维持不变。这种机制实际上就无须考虑刷新的问题,只需维持稳定的电压状态就可以实现稳定的画面显示。
5. LCD的特性
LCD显示分主动式和被动式两种,被动式液晶屏幕有超扭曲向列(Super TN,STN)和双层超扭曲向列(Double layer Super TN,DSTN)LCD等;最流行的主动式液晶屏幕是薄膜晶体管(Thin Film Transistor,TFT)。主动式LCD使用了场效应晶体管并结合了共用电极,可以让液晶体在下一次的电压改变前一直保持电位状态,就不会产生在被动式LCD中常见的鬼影,或是画面延迟的残像等。
LCD的基本指标有可视角度、点距与分辨率。视线与屏幕中心法向成一定角度时,就不能清晰地看到屏幕图像,而能看到清晰图像的最大角度称为可视角度;一般所说的可视角度是指左右两边的最大角度相加,工业上有CR10(contrast ratio 10)、CR5两种标准来判断LCD的可视角度。点距就是两个液晶颗粒(光点)之间的距离,一般在0.28~0.32mm内就能得到较好的显示效果。而通常所说的LCD分辨率是指其真实分辨率,表示水平方向的像素点数与垂直方向的像素点数的乘积。
相比CRT,LCD有许多优点:工作电压低,功耗小;平板型结构,厚度只有6.5~8.5cm,使用方便,便于大规模生产;被动显示型,更适合人的视觉习惯(人类视觉感受的外部信息中,90%以上为外部物体对光的反射);无荫罩的限制,显示信息量大;易于彩色化(有多种彩色化的方法);无电磁辐射,对人体安全和信息保密都是理想的;几乎无器件劣化问题,寿命长。
但是液晶显示技术也存在弱点和技术瓶颈,与CRT显示器相比在亮度、画面均匀度、可视角度和反应时间上都存在明显的差距。LCD的色彩表现和饱和度不如CRT显示器丰富和鲜艳,而且LCD的像素从亮到暗和从暗到亮得响应时间比CRT显示器长,一旦显示更新速度快的画面时,液晶显示器的弱点就暴露出来了,画面延迟会产生重影、脱尾等现象,严重影响显示质量。目前LCD的发展就是在尽可能的程度上克服这些问题,力争在显示效果上达到CRT的质量。
2.5 软件基础知识
图形图像的显示是利用了计算机系统的图形功能,事实上,如第1章所述,图形和图像在逻辑上是两个不同的概念,但对于PC而言,最终到显示器上都是以像素点方式显示,而不区分图形图像。因此,本节将重点介绍像素显示的程序实现,以此构成图形图像的显示。
2.5.1 图形图像显示的底层原理
早期计算机的显示主要有两种方式:文本方式和图形方式,而且大多数情况是工作在文本方式下。要进行图形图像的显示,必须通过底层操作,首先切换到图形显示方式,接着设置显示系统所代表的颜色,最后用这些颜色画出像素点并且由像素点组成各种图形或者图像。这个过程实际上就对应着显示初始化、设置调色板和写像素点三个步骤。
在程序实现上,早期各类编程语言提供的标准图形处理函数很可能不能满足所有的应用需求,此时往往就需要直接利用中断进行底层操作,事实上,这些标准函数都可以利用中断来实现。与图形图像相关的中断号是10H,为显示中断,主要完成图形图像显示方面的所有功能,它具体的功能和使用方法请参考相关硬件手册。
1. 显示初始化
图形图像显示初始化实际上就是利用了PC中的图形初始化。所谓初始化,就是装载一个图形驱动程序或校验已登记的驱动程序是否存在,在内存中分配一块空间映射为显示内存,并使系统进入图形方式。就C语言而言,初始化方法有两种。
●调用标准函数初始化
C语言中常用的相关函数为:
initgraph(int far* gdriver, int far* gmode, char far* path)
参数指明initgraph装入哪个驱动程序,使用哪种显示方式,对应关系如表2.2所示。
表2.2 initgraph显示驱动程序对应关系
不同的驱动程序对应不同的显示卡,而同一种显示卡又有多种不同的显示方式,在gmode中定义。具体参见graphics.h头文件。这里的显示方式号是C语言定义的显示方式号,而不是BIOS所定义的通常的显示方式号。
●利用BIOS中断10H实现初始化
C语言提供的标准显示功能往往不能满足特殊情况下的要求,于是需要利用10H中断,来达到特殊应用目的。
C语言中的常用中断调用函数如下:
int int86x( int n, union REGS * inregs, union REGS * outregs, struct SREGS* segregs); int int86(int n, union REGS* inregs, union REGS* outregs,); void intr(int n, struct REGPACK* regs);
其中结构与联合的定义如下:
union REGS {struct WORDREGS x; struct BYTEREGS h}; struct WORDREGS {unsigned int ax,bx,cx,dx,si,di,cflag,flags} struct BYTEREGS {unsigned char al,ah,bl,bh,cl,ch,dl,dh}
我们知道,在中断调用时,AH中的参数对应该中断相应的功能;AL中存储完成该功能所需的参数。对于初始化操作,中断10H的入口参数AH=00H,表示执行初始化功能;AL=mode,表示相应的显示模式。以int86()为例,程序代码为:
union REGS regs; regs.h.ah= 0; regs.h.al= mode; // 确定显示模式 int86(0X10,®s,®s);
gmode参数代表的显示模式反映出当前的显示类型,即显示方式、分辨率、颜色数、帧缓存起始地址等,早期常用的几种显示模式如表2.3所示(T表示文本方式,G表示图形方式),随着硬件水平的提高,新的显示模式也不断地被扩充,以满足各种场合的显示需求。
2. 设置调色板
在2.4.2节已经说明,在彩色CRT中,彩色查找表是不增加帧缓存存储容量而得到更多颜色的一种技术,通常将彩色查找表形象地称为“调色板”,如同画家手中配置颜色的工具,在更专业的领域也把它们称为“颜色寄存器”,即通过设置这些寄存器来得到各种颜色。
表2.3 常用的显示模式
对于彩色图像,查找表有多长就能同时显示多少种图像。在VGA卡中,共有256组颜色寄存器,每组分为R、G、B三个,共计256×3=768个,但对于每个R、G、B寄存器均只有6位,所以总共可显示的彩色数为218=256K种颜色。
对于灰度图像的显示,由于R、G、B寄存器均只有6位,所以最大显示的灰度级数只有64级。
设置调色板一般用到中断10H的10H号功能,此功能入口参数:AH=10H,AL=12H,其含义是设置成片的颜色寄存器,也就是将存储区的一片连续的数据设置成为调色板的值。当AL取不同的值时,可以有不同的设置调色板的方法。具体用法如下。
unsigned char Gray[192]; union REGS regs; for(i=0;i<64;i++) Gary[3*i]=Gary[3*i+1]=Gary[3*i+2]=i;//将RGB颜色寄存器设置为同样的数值 regs.x.cx=64; //设置彩色查找表长为64 regs.x.bx=0; //起始编号 regs.x.cs=FP_SEG(Gray); //数据起始段址 regs.x.dx=FP_OFF(Gray); //数据起始偏移量 regs.h.ah=0X10; regs.h.al=0X12; int86(0X10,®s,®s);
3. 写像素点
在计算机的显示器上,不管多么复杂的图形或图像,它的显示最终都是通过逐个写像素点来实现的,这些像素点按照一定的分布规律来排列,就形成我们所看见的图形或图像。因此,写像素点是最基本的步骤。对于各种编程语言,在图形显示方面都有标准的写像素点的函数,只要调用这些函数,输入相关的参数就可以在屏幕上显示一个像素点,这种方式简单直观,就不再过多介绍。我们需要详细说明的是另外两种写像素点的方式:基于中断的方式和直接写视频缓存区的方式,这两种方式实际上也是标准函数完成写像素点功能的实现手段。
●利用中断写像素点
写像素点利用了中断10H的0C号功能,此功能入口参数为:AH=0CH,AL=颜色值,CX=X坐标,DX=Y坐标,其含义就是在屏幕上(X,Y)处写一个AL寄存器所指定颜色的点。具体C语言程序如下。
union REGS regs; regs.h.ah=0X0c; regs.h.al=color; //设置显示像素点的颜色 regs.x.cx=x; regs.x.dx=y; //设置像素点的坐标 int86(0X10,®s,®s);
●直接写视频缓存区
在2.4.2节中已经介绍,在显示器的硬件中有一个帧缓存区,用来存储将要显示的数据信息。这种帧缓存往往位于计算机的显卡上,常称为显存,而显卡上的显存映射到计算机内存中,则对应着64K的一片存储区,由硬件完成地址映射关系。例如,在13H模的显示模式下,存储区起始地址为A0000(参见表2.3)。由于这片存储区式和计算机的视频显示相关,所以又把它叫做视频缓存区。
在视频缓存区中,图像数据是按行序存放的,一个像素占用视频缓存区的一个字节。我们可以通过往视频缓存区写入相应的像素数据从而实现在屏上的写像素点操作。这就是直接写视频缓存区的基本原理,具体程序如下。
unsigned int seg, off; unsigned char far *ptr; off=x+320*y; //通过x、y坐标计算偏移量 seg=0XA000; //设置段基址 ptr=(unsigned char*)MK_FP(seg,off); //形成指向相应位置的指针 *ptr=color; //写一个颜色为color的像素
2.5.2 Windows下图形图像的显示
在DOS编程的年代,为了在应用程序中绘制图形图像,必须对图形硬件进行大量的底层控制操作,如2.5.1节所介绍的那样。这种控制操作要求用户具有广泛的知识,深入理解系统硬件,尤其是可能会在其计算机上使用的各种图形卡以及显示器和分辨率的各种选项。Windows操作系统相对于DOS系统的一个很大的进步就在于Windows系统具有丰富的图形界面,并且为所有的Windows应用程序提供了一个虚拟图形设备。该虚拟设备不随硬件的改变而改变,而是对所有用户可能使用的图形卡都保持不变。这种一致性允许在应用程序中创建任意的图形,这样用户就不用与具体的硬件打交道,极大地方便了编程。
1. 图形设备接口与设备环境
图形设备接口(Graphics Device Interface,GDI)表示的是一个抽象的接口。通过该接口可以实现对图形的颜色、线条的粗细等属性的控制(甚至包括输出文字在内)。应用程序可以通过调用这些GDI函数和硬件打交道,而不必知道到底是哪个厂家生产的硬件,从而实现了设备无关性。Windows系统本身也使用GDI来绘制用户界面的各个部分,我们看见的应用程序主窗口、菜单、对话框等,都是通过调用GDI来完成绘制的。
Windows的GDI对象类型是通过MFC库中的类来表示的,其中CGdiobject类是所有GDI对象的抽象基类,其派生类包括CBitmap类、CBrush类、CFont类、CPen类、CRgn类和CPalette类。这些派生类对于绘制图形和图像来说都是非常重要的,程序员经常使用这些类来创建绘图工具,而很少直接使用基类CGdiobject。
CBitmap——位图是一种位矩阵,每一个显示像素都对应于其中的一个或多个位。用户可以利用位图来表示图像,也可以利用它来创建画刷。
CBrush——画刷定义了一种位图形式的像素,利用它可对区域内部填充颜色。
CFont——字体是一种具有某种风格和尺寸的所有字符的完整集合,它常常被当作资源存于磁盘中,其中有一些还依赖于某种设备。
CPen——画笔是一种用来画线及绘制有形边框的工具,用户可以指定它的颜色及厚度,并且可以指定它画实线、点线或虚线。
CRgn——区域是由多边形、椭圆或二者组合形成的一种范围,可以利用它来进行填充、裁剪以及鼠标点中测试。
CPalette——调色板是一种颜色映射接口,它允许应用程序在不干扰其他应用程序的前提下,充分利用输出设备的颜色描绘能力。
为了使用某种GDI对象,一般来说需要首先构造一个GDI对象,然后将这个GDI对象放入设备环境中,进行绘制工作。绘制完毕后,还必须将GDI对象释放。
设备环境(device context,DC),也称设备上下文或设备描述表是一种包含各种绘图属性(如前面说的字体、颜色等)和方法(即各种绘图函数)的数据结构(或者集合)。它不仅可以绘制各种图形,而且还可以确定在应用窗口中绘制图形的方式,即确定绘图混合模式和映射模式。
DC中除了提供绘图的函数以外,还会提供给用户改变绘图属性的函数。Windows的设备环境是GDI的关键元素,它代表了不同的物理设备。分为4种类型:显示器型、打印机型、内存型和信息型。每种类型的设备环境都有各自的特定用途,详见表2.4。
表2.4 设备环境的类型和用途
设备环境和图形设备接口是实现计算机绘图的两个重要的组成部分,设备环境主要定义了绘图的状态和方式,而图形设备接口则主要定义了用来绘图的工具。设备环境中包含有默认的GDI对象。在绘图之前,必须获取绘图窗口区域的一个设备环境DC。接着才能进行GDI函数的调用,执行适合于设备环境DC的命令。
在MFC类库中,设备环境被CDC类封装了起来,它的常用函数如表2.5所示,除了绘制图形的函数以外,还有以Get开头的获取绘图属性的函数,以及以Set开头的设置绘图属性的函数。
表2.5 CDC类的常用函数
2. 常用图形对象的显示与绘制
常用的图形对象通常指点、线和多边形,它们是构成复杂图形对象的基础。要绘制这些对象首先要获取设备环境指针,然后再调用表2.5 所示的函数完成相关图形对象的绘制。
●获取设备环境
GetDC函数用于获取指定窗口工作区的显示器设备环境,其原型声明如下:
CDC * CWnd::GetDC()
该函数不带任何参数。如果调用成功,则返回标识CWnd客户区的设备环境,否则返回NULL。返回的指针可能是临时性的,所以应该把它保存下来供以后使用。
对于公用的设备环境,GetDC成员函数为每一次被获取的设备环境指定默认属性。对于私有的设备环境,GetDC成员函数保持它先前所具有的属性不变。设备环境可以用于后面的图形设备接口(GDI)函数中在客户区中绘图。
一般来说,在完成作图之后,用GetDC成员函数获取的设备环境必须通过调用ReleaseDC成员函数来释放。因为在一个给定的时刻,系统只有五个公共的设备环境是可用的,所以如果使用了设备环境后不释放,则有可能会妨碍其他的应用程序访问设备环境。及时释放设备环境,是一个程序员应该养成的良好习惯。
ReleaseDC用于释放一个设备环境,以便该设备环境可以被其他应用程序申请使用。其原型声明如下:
int ReleaseDC(CDC*pDC)
其中pDC为待释放的设备环境的指针。如果释放成功,函数返回非零值,否则,函数返回零。相关的Visual C++代码如下。
CDC * pDC; pDC=GetDC(); //获取设备环境 //然后调用各种绘制函数进行绘制 ReleaseDC(pDC); //释放设备环境
●绘制像素点
像素点的绘制调用SetPixel函数,具体用法如下。
pDC->SetPixel(100,50,RGB(255,0,0));
上面的代码表示在(100,50)位置画一个红色的点。这里的RGB是一个宏,将三个颜色分量转换成为Windows系统的颜色,三个分量分别表示红、绿、蓝的分量值,取值范围是0~255。常用的8种颜色的RCB值如表2.6所示。
表2.6 常用的8种颜色的RGB值
●绘制线段
绘制线段一般使用LineTo()函数,当绘制多条线段构成的折线时,也使用Polyline()函数,具体的用法如下。
pDC->MoveTo(0,0); pDC->LineTo(100,100); //绘制单条线段
上面的代码表示从(0,0)点画线到(100,100)点。MoveTo()函数用来移动画笔到相应位置,LineTo()函数从当前位置画线到指定位置。
POINT polyline[4]={{240,240},{80,120},{240,120},{80,240}}; pDC->Polyline(polyline,4); //绘制多条线段构成的折线
上面的代码将给定的4个点顺序练成折线,Polyline()函数中的第一个参数为折线的顶点数组名,第二个参数表示一共有几个点构成折线(最小必须是2)。POINT是Windows的一种结构,用来标识一个点,它有两个成员变量,分别用来表示点的X坐标和Y坐标。在MFC类库中,CPoint封装了这种结构。
●绘制多边形
绘制多边形使用Polygon()函数,具体用法和Polyline类似。
POINT polygon[3]={{380,330},{530,260},{500,360}}; pDC->Ploygon(polygon,3); //绘制由3个顶点决定的多边形
上面的代码绘制由三个顶点决定的多边形,这三个顶点按顺序首位相连并封闭成多边形。Ploygon()的第一个参数为多边形的顶点数组名,第二个参数表示多边形顶点的数目。
3. 位图的显示
图像的显示在Windows系统中是通过位图方式进行的,在Windows中有两种类型的位图:DDB位图(设备相关位图,也有的书上称为GDI位图)和DIB位图(设备无关位图)。DDB位图对象是由MFC库6.0版本CBitmap类定义的。DDB位图对象有一个与之关联的Windows数据结构,它在Windows GDI模块内进行维护。程序可以获得位图数据的副本,但是其中位的排列则取决于显示硬件。在同一台机器中,GDI位图可以在各个程序之间任意进行传输;但是,由于它们是设备相关的,所以,通过磁盘或网络来传输位图,其意义就不很明显。
DDB中不包括颜色信息,因此显示时是以系统的调色板为基础进行各位的颜色映射的,Windows只能保证系统调色板的前20种颜色稳定不变,所以DDB只能保证正确显示少于20色的位图。
Windows SDK提供了标准的DDB位图操作函数,MFC 6.0版本更是定义了Cbit-map类对DDB结构BITMAP和DDB位图操作,进行了封装。
DIB位图自带颜色信息,因此调色板管理非常容易。DIB也使打印时的灰度阴影的控制更加容易。任何运行Windows的计算机都可以处理DIB,它通常以BMP文件的形式被保存在磁盘中或者作为资源保存在EXE文件和DLL文件中。
不管是DDB还是DIB,要显示相关的图像,一般都要经过4个步骤:加载位图资源、创建兼容内存设备环境、将位图对象放入内存设备环境中、显示位图。
加载位图资源一般使用函数LoadBitmap()或者LoadImage(),前者用于从应用程序的资源中加载位图,而后者不仅可以从资源库中加载各种图像资源(包括位图、光标和图标),还可以直接从文件中加载。
创建兼容内存设备环境主要是预先在内存中为将来在显示设备上显示的位图创建一个环境,并且要求与显示设备环境兼容,常用函数CreateCompatibleDC()实现。
将位图对象放入内存设备环境使用函数SelectObject()。
显示位图可以使用函数BitBlt()或者StretchBlt(),使用BitBlt()只能按照位图原来的比例显示,而StretchBlt()则可以对位图进行放大或者缩小。两个函数的原形如下,为了获得位图的高度和宽度信息,还必须声明一个BITMAP结构,然后调用函数GetObject()来获取相关的位图信息。
BOOL BitBlt(int x,int y,int nWidth,int nHeight,CDC * pSrcDC,int xSrC,int ySrc,DWORD dwRop);
其中x、y说明了显示位图的位置:nWidth、nHeight说明了显示位图的宽、高的范围;pSrcDC为已选入位图的内存设备环境的指针;xSrc、ySrc为原位图的起始位置;dwRop是光栅操作符,该参数定义在屏幕上绘制图形时和屏幕上已有的屏幕图形进行结合的方式,常用的取值如表2.7所示。通常情况下使用SRCCOPY直接将整个位图复制到显示设备环境中就可以了。
表2.7 常用光栅操作代码
B OOL StretchBlt(int x,int y,int nWidth,int nHeight,CDC* pSrcDC,int xS- rc,int nSrcwidth,int nSrcHeight,DWORD dwRop);
可见此函数比BitBlt()多了两个参数:nSrcWidth、nSrcHeight,分别为源位图的宽度和高度,其他参数的意义与BitBlt()函数的参数相同。当nSrcWidth和nSrcHeight的取值(位图的实际大小)与nWidth和nHeight(位图的显示大小)相同时,位图没有被缩放。一旦两组数的取值不同,就会出现缩放效果。
显示一个位图文件的相关代码如下,假设图像文件名为lena.bmp。
CBitmap bitmap; //第一步,从文件中加载位图 HBITMAP hbitmap=(HBITMAP)LoadImage( NULL, //如果从资源加载,则指明包含位图的资源 “lena.bmp”, //位图文件名或者位图资源的ID IMAGE_BITMAP, //加载的图像类型是位图 0,0, //宽度和高度,0表示使用默认值 LR_LOADFROMFILE); //加载标志,表示从文件加载 bitmap.Attach(hbitmap); //将HBITMAP对象附加给CBitmap对象 //第二步,创建一个兼容DC CDC dccomp,*pDC; pDC=GetDC(); //获取设备环境,pDC为显示设备环境的指针 dccomp.CreateCompatibleDC(pDC); //创建与pDC兼容的设备环境 //第三步,将位图放入兼容DC中 dccomp.SelectObject(&bitmap); //第四步,显示位图 BITMAP bminfo; bitmap.GetObject(sizeof(bminfo),&bminfo); //获取位图文件相关信息 pDC->BitBlt( 0,0, //位图显示位置 bminfo.bmWidth,bminfo.bmHeight, //显示位图的宽度和高度 &dccomp, //位图所在兼容DC 0,0, //兼容DC中的位置 SRCCOPY); //显示方式
2.5.3 常用的图像文件的格式
1. BMP图像文件格式
BMP图像是在Windows下应用最广的一种图像格式,各种图像处理工具都能够支持它,并且可以将其与其他格式的图像相互转换。常常将BMP图像作为一个中间桥梁,实现不同格式间的转换。
BMP图像文件的结构分为4个部分,具体顺序如下。
图像文件的相关信息,14字节
图像本身的相关信息,40字节
该文件所用的调色板信息,长度由其他因素决定
图像数据
(1)位图文件头
struct tagBitMapFileHeader { WORD bfType; //位图文件标志,必须为‘BM’ DWORD bfSize; //位图文件大小,以字节为单位 WORD bfReserved1; //位图文件保留字,必须为0 WORD bfReserved2; //位图文件保留字,必须为0 DWORD bfOffBits; //图像数据相对于文件头的偏移量 }
这个结构的长度是固定的,为14个字节,其中WORD为无符号16位整数,DWORD为无符号32位整数。
(2)位图信息头
struct tagBitMapInfoHeader
{
DWORD biSize; //信息头的长度,以字节为单位
LONG biWidth; //位图的宽度,以像素为单位
LONG biHeight; //位图的高度,以像素为单位
WORD biPlans; //图像的色彩平面表,固定为1
WORD biBitCount; //每个像素所需的位数,1:单色
//4:16色,8:256色,24:224色
DWORD biCompression; //图像的压缩类型,0:不压缩
//1:RLE8压缩,2:RLE4压缩
DWORD biSizeImage; //图像的大小,以字节为单位
LONG biXPelsPerMeter //设备水平分辨率,每米像素数
LONG biYPelsPerMeter //设备垂直分辨率,每米像素数
DWORD biClrUsed; //图像实际使用的色彩数
//若为0,则由biBitCount决定
DWORD biClrImportant; //图像中重要的色彩数目
}
biSize为信息头的长度,固定为40字节。
biSizeImage表示实际位图数据所占据的字节数,一般等于位图数据的宽度和高度的乘积,但是此时宽度要取和实际宽度最接近的4的倍数。
biClrImportant表示本图像中重要的颜色数目,如果该值为0,则认为所有的颜色都是重要的。
(3)调色板数据
struct tagRGBQuad { BYTE rgbBlue; //蓝色值,0~255 BYTE rgbGreen; //绿色值,0~255 BYTE rgbRed; //红色值,0~255 BYTE rgbReserved; //保留,固定为0 }
调色板数据的存储是以结构数组的方式进行,具体的项数由信息头中的相关参数决定。其格式为:[BGRRe][BGRRe]……
(4)图像数据
对于用到调色板的位图,图像数据就是该像素颜色在调色板中的索引值,对于真彩色图,图像数据就是实际的R、G、B值。BMP图像数据的存储顺序是从左往右,从下往上,依次存储图像的每一个像素,这和我们习惯的顺序刚好是上下颠倒的,同时图像数据根据biBitCount的值决定一个字节存储的像素数目。
biBitCount=1,对于2色位图,用1位就可以表示该像素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个像素。
biBitCount=4,对于16色位图,用4位可以表示一个像素的颜色,所以1个字节可以表示2个像素。
biBitCount=8,对于256色位图,1个字节刚好可以表示1个像素。
对于真彩色图,3个字节才能表示1个像素
BMP格式还规定,每行像素所占的字节必须是4的倍数,不足者补0。
BMP格式支持两种压缩方式,BI_RLE8和BI_RLE4,它们分别是基于8位和4位的Run_Length压缩。
2. PCX文件
PCX是Zsoft公司研制的一种常用图像格式,主要用于PC Paintbrush软件,是存储光栅图形的最早标准之一,因为应用时间长,从而得到了许多应用软件的支持,也成为图像相互转换的桥梁。早期PCX文件支持4种分辨率:640×200×16色,640×350×16色,640×480×16色以及320×200×256色,但是其最新版本支持24位色彩,图像大小可达64k×64k个像素。由于这种文件的压缩比并不是很高,所以现在应用并不是很广泛。
PCX文件结构包含了文件头,图像数据和可选的调色板,文件结构如下。
PCX文件由固定的128字节的文件头开始。文件头包含版本号、被打印或扫描图像的分辨率(单位为每英寸点数)、大小(单位为像素数)、每扫描行字节数、每像素位数和彩色平面数等信息。文件还可能包括一个调色板,以及表明该调色板是灰度还是彩色的一个代码。
文件的核心部分是位图数据。位图数据以游程长度压缩形式记录,像素值通常是单字节的索引值,指向调色板中的位置。
如果版本号为5,则文件末尾处还有一个单一的位平面和一个RGB值的256色调色板(三种原色各占1个字节)。
(1)文件头
struct PCXFileHeader { BYTE Header; //PCX识别码,为0x0A BYTE Version; //版本信息 BYTE Encoder; //数据压缩方式,固定为1 BYTE BitPerPix; //每个像素所需的位数 int XMin; //左上角X坐标 int YMin; //左上角Y坐标 int XMax; //右下角X坐标 int YMax; //右下角Y坐标 int HRes; //设备水平分辨率,像素/英寸 int VRes; //设备垂直分辨率,像素/英寸 BYTE Palette[48]; //调色板信息 BYTE Reserved; //保留字,为0 BYTE ColorPlane; //彩色平面数 int BytePerLine; //图像宽度 //压缩前一行像素所占字节数,总是偶数 int PaletteEx //调色板解释,= 1表示彩色或黑白; //= 2表示灰度图像 int ScreenX //视频输出的水平像素数-1 int ScreenY //视频输出的垂直像素数-1 BYTE Unused[54]; //保留,一般为0 }
其中版本字节Version表示所采用的Paintbrush技术,其值代表的含义如表2.8所示,各个版本的区别在于处理色彩的能力不同。
表2.8 版本号对应数值的含义
如果PCX文件要显示256种颜色,则在文件末尾加上0x0C后,再跟上附加调色板。附加调色板共有256 种颜色,每种颜色用三个字节,分别表示RGB分量的值,共计256×3=768字节。
在PCX文件头中,每个像素所需的位数BitPerPix和彩色平面数ColorPlane共同解释了图像的类型,其组合关系如表2.9所示。
表2.9 PCX图像类型的解释
平面数说明了是否使用了调色板,多于一平面意味着没有调色板。如果使用了调色板,则由版本号和相关的参数决定PCX所使用的调色板类型。
(2)图像数据
PCX图像数据编码按照从左往右、从上往下的顺序进行,采用行程编码技术,其原则如下。
① 以字节为单位;
② 每条扫描线分开压缩;
③ 若图像数据中相邻n个字节相等,则将n与0xC0相或(记为n|0xC0)后,再往文件中写入n|0xC0和该字节;
④ 若相邻数据不等,数据大于0xC0 时,先写入0xC1 再跟数据,否则直接写入该数据;
⑤ 若数据重复次数大于63,则必须分次处理。
例:有一行数据:0x09,0x09,0x09,0x09,0x09,0x13,0xF9,0x09,0x08,0x08,0x08
则编码后为:0xC5,0x09,0x13,0xC1,0xF9,0x09,0xC3,0x08
解码流程如下:
step1:读入一个字节到ch step2:if((ch&0xC0)==0xC0) { count=ch&0x3F; 读入下一字节,重复count次; } else 直接读入下一字节 step3:重复1.2,直到解完一条扫描线。
3. GIF图像文件格式
GIF是图像交换格式(graphics interchange format)的简称,它是由美国CompuServe公司在1987年所提出的图像文件格式,它最初的目的是希望每个BBS的使用者能够通过GIF图像文件轻易存储并交换图像数据,这也就是它为什么被称为图像交换格式的原因了。
GIF文件格式采用了一种经过改进的LZW压缩算法,通常称之为GIF-LZW算法。这是一种无损的压缩算法,压缩效率也比较高,并且GIF支持在一幅GIF文件中存放多幅彩色图像,并且可以按照一定的顺序和时间间隔将多幅图像依次读出并显示在屏幕上,这样就可以形成一种简单的动画效果。尽管GIF最多只支持256色,但是由于它具有极佳的压缩效率并且可以做成动画而早已被广泛接纳采用。
GIF图像文件是以块的形式来存储图像信息,其中的块又称为区域结构。按照其中块的特征又可以将所有的块分成三大类,分别是控制块(Control Block)、图像描述块(Graphic Rendering Block)和特殊用途块(Special Purpose Block)。控制块包含了控制数据流的处理以及硬件参数的设置,其成员主要包括文件头信息、逻辑屏幕描述块、图像控制扩充块和文件结尾块。图像描述块包含了在显示设备上描述图像所需的信息,其成员包括图像描述块、全局调色板、局部调色板、图像压缩数据和图像说明扩充块。特殊用途块包含了与图像数据处理无直接关系的信息,其成员包括图像注释扩充块和应用程序扩充块。下面详细介绍每一个块的详细结构。
(1)文件头信息
GIF的文件头只有6个字节,其结构定义如下。
typedef struct gifheader { BYTE bySignature[3]; //GIF文件标示码,其固定值为“GIF” BYTE byVersion[3]; //GIF文件的版本信息 }GIFHEADER;
其中,使用者可以通过bySignature域来判断一个图像文件是否是GIF图像格式的文件,byVersion的取值固定为“87a”和“89a”。分别表示GIF文件的版本为GIF87a或GIF89a。这两个版本有一些不同,GIF87a公布的时间为1987年,该版本不支持动画和一些扩展属性。GIF89a是1989年确定的一个版本标准,只有89a版本才支持动画、注释扩展和文本扩展。
(2)逻辑屏幕描述块
逻辑屏幕(logical screen)是一个虚拟屏幕(virtual screen),它相当于画布,所有的操作都是在它的基础上进行的,同时它也决定了图像的长度和宽度。逻辑屏幕描述块共占有7个字节,其具体结构定义如下。
typedef struct gifscrdesc { WORD wWidth; //逻辑屏幕的宽度 WORD wDepth; //逻辑屏幕的高度 struct globalflag //全局性标志,占一个字节 { BIT PalBits: 3; //全局调色板的位数 BIT SortFlag: 1; //是否排序 BIT ColorRes: 3; //图像的色彩分辨率 BIT GlobalPal: 1; //是否具有全局调色板 }GlobalFlag; BYTE byBackground; //逻辑屏幕的背景颜色 BYTE byAspect; //逻辑屏幕的像素的长宽比例 }GIFSCRDESC;
其中globalflag为全局性标志,总长度为一个字节。第0位到第2位指定全局调色板的位数,可以通过该值来计算全局调色板的大小。第3位表明全局调色板中的RGB颜色值是否按照使用率由高到低的次序排序。第4位到第6位指定图像的色彩分辨率。第7位指明GIF文件中是否具有全局调色板,其值取1表示具有全局调色板,为0则表示没有。一个GIF文件可以有全局调色板也可以没有,如果定义了全局调色板并且没有定义某一幅图像的局部调色板,则本幅图像采用全局调色板;如果某一幅图像定义的自己的局部调色板,则该幅图像使用自己的局部调色板。如果没有定义全局调色板,则GIF文件中的每一幅图像都必须定义自己的局部调色板。全局调色板必须紧跟在逻辑屏幕描述块的后面,其大小由GlobalFlag.PalBits决定,其最大长度为768(3×256)字节。全局调色板的数据按照RGB顺序排列的方式存储。byBackground指定逻辑屏幕的背景颜色,相当于画布的颜色。当图像长宽小于逻辑屏幕的大小时,未被图像覆盖部分的颜色值由该值对应的全局调色板中的索引颜色值确定。如果没有全局调色板,该值无效,默认背景颜色为黑色。
(3)图像描述块
一幅GIF图像文件中可以存储多幅图像,并且这些图像没有固定的存放次序。为了区分两幅图像,GIF采用了一个字节的识别码(image separator)来判断下面的数据是否是图像描述块。图像描述块以0x2C开始,定义紧接着它的图像的性质,包括图像相对于逻辑屏幕边界的偏移量、图像大小以及有无局部调色板和调色板的大小。图像描述块由10个字节组成。
typedef struct gifimage { WORD wLeft; //图像相对逻辑屏幕左上角的X坐标,单位:像素 WORD wTop; //图像相对逻辑屏幕左上角的Y坐标 WORD wWidth; //图像的宽度 WORD wDepth; //图像的高度 struct localflag //局部标志位,长度为一个字节 { BIT PalBits: 3; //局部调色板的位数 BIT Reserved: 2; //保留位,固定为0 BIT SortFlag: 1; //颜色值是否经过排序 BIT Interlace: 1; //图像是否以交错方式存储 BIT LocalPal: 1; //图像是否含有局部调色板 }LocalFlag; }GIFIMAGE;
其中LocalFlag用来指定区域性数据,也就是具体一幅图像的属性。LocalFlag的总长度为一个字节,其中的前三位用来指定局部调色板的位数,可以根据该值来计算局部调色板的大小。第4位到第5位为保留位,没有使用,其值固定为0。第6位指明局部调色板中的RGB颜色值是否经过排序,其值为1表示调色板中的RGB颜色值是按照其使用率从高到低的次序进行排序。第7位表示GIF图像是否以交错方式存储,其取值为1表示以交错的方式进行存储。当图像是按照交错方式存储时,其图像数据的处理可以分为4个阶段:第一阶段从第0行开始,每次间隔8行进行处理;第二阶段从第4行开始,每次间隔8行进行处理;第三阶段从第2行开始,每次间隔4行进行处理;第四阶段从第1行开始,每次间隔2行进行处理,这样当完成第一阶段时就可以看到图像的概貌,当处理完第二阶段时,图像会变得清晰一些;当处理完第三阶段时,图像处理完成一半,清晰效果也进一步增强,当完成第四阶段,图像处理完毕,显示出完整清晰的整幅图像。以交错方式存储是GIF文件格式的一个重要的特点,也是GIF文件格式的一个重要的优点。以交错方式存储的图像的好处就是无须将整个图像文件解压完成就可以看到图像的概貌,这样可以减少用户的等待时间。第8位指明GIF图像是否含有局部调色板,如果含有局部调色板,则局部调色板的内容应当紧跟在图像描述块的后面。
(4)图像压缩数据
图像压缩数据是按照GIF-LZW压缩编码后存储于图像压缩数据块中的。GIF-LZW编码是一种经过改良的LZW编码方式,它是一种无损压缩的编码方法。GIF-LZW编码方法是将原始数据中的重复字符串建立一个字符串表,然后用该重复字符串在字符串表中的索引来替代原始数据以达到压缩的目的。由于GIF-LZW压缩编码的需要,必须首先存储GIF-LZW的最小编码长度以供解码程序使用,然后再存储编码后的图像数据。编码后的图像数据以一个个数据子块的方式存储的,每个数据子块的最大长度为256字节。数据子块的第一个字节指定该数据子块的长度,接下来的数据为数据子块的内容。如果某个数据子块的第一个字节数值为0,即该数据子块中没有包含任何有用数据,则该子块称为块终结符,用来标识数据子块到此结束。
(5)图像控制扩充块
图像控制扩充块是可选的,只应用于89a版本,它描述了与图像控制相关的参数。一般情况下,图像控制扩充块位于一个图像块(包括图像标识符、局部颜色列表和图像数据)或文本扩展块的前面,用来控制跟在它后面的第一个图像(或文本)的渲染(render)形式,组成结构如下。
typedef struct gifcontrol { BYTE byBlockSize; //图像控制扩充块的长度,取值固定为4 struct flag //图像控制相关数据,长度为一个字节 { BIT Transparency: 1; //是否具有透明性的颜色 BIT UserInput: 1; //显示图像时是否需要用户输入 BIT DisposalMethod: 3; //图像显示后的处理方式 BIT Reserved: 3; //保留位,固定为0 }Flag; WORD wDelayTime; //指定延迟的时间 BYTE byTransparencyIndex; //指定图像中透明色的颜色索引 BYTE byTerminator; //块终结符,其值固定为0。 }GIFCONTROL;
其中Flag的长度为1个字节。第0位用来指定图像中是否具有透明性的颜色,如果该位为1,这表明图像中某种颜色具有透明性,由参数byTransparencyIndex指定。第1位用来判断在显示一幅图像后,是否需要用户输入后再进行下一个动作。如果该位为1,则表示应用程序在进行下一个动作之前需要用户输入。第2~4位用来指定图像显示后的处理方式,该值为0时,表示没有指定任何处理方式;该值为1时,不进行任何处理动作;该值为2时,表明图像显示后以背景色擦去;该值为3时,表明图像显示后恢复原先的背景图像。第5~7位为保留位,没有任何含义,固定为0。wDelayTime用来指定应用程序进行下一步操作之前延迟的时间,单位为0.01s。如果Flag.UserInput和wDelayTime都设定了,则以先发者为主,如果没有到指定的延迟时间即有用户输入,则应用程序直接进行下一步操作。如果到达延迟时间后还没有用户输入,应用程序也直接进入下一步操作。byTransparenceIndex用来指定图像中透明色的颜色索引,指定的透明色将不在显示设备上显示。
(6)图像说明扩充块
图像说明扩充块又称为图像文本扩展块,它用来绘制一个简单的文本图像,这一部分由用来绘制的纯文本数据(7位ASCII字符)和控制绘制的参数等组成。绘制文本借助于一个文本框(text grid)来定义边界,在文本框中划分多个单元格,每个字符占用一个单元。绘制时按从左到右、从上到下的顺序依次进行,直到最后一个字符或者占满整个文本框(之后的字符将被忽略,因此定义文本框的大小时应该注意到是否可以容纳整个文本)。绘制文本的颜色使用全局颜色列表,没有则可以使用一个已经保存的前一个颜色列表。另外,图形文本扩展块也属于图形块(graphic rendering block),可以在它前面定义图形控制扩展对它的表现形式进一步修改。图像说明扩充块的组成如下。
typedef struct gifplaintext { BYTE byBlockSize; //指定图像扩充块的长度,取值固定为12 WORD wTextGridLeft; //文字显示方格相对于逻辑屏幕左上角 //的X坐标(以像素为单位) WORD wTextGridTop; //文字显示方格相对于左上角的Y坐标 WORD wTextGridWidth; //文字显示方格的宽度 WORD wTextGridDepth; //文字显示方格的高度 BYTE byCharCellWidth; //指定字符的宽度 BYTE byCharCellDepth; //指定字符的高度 BYTE byForeColorIndex; //指定字符的前景色 BYTE byBackColorIndex; //指定字符的背景色
}GIFPLAINTEXT;
(7)图像注释扩充块
图像注释扩充块包含了图像的文字注释说明,可以用来记录图形、版权、描述等任何的非图形和控制的纯文本数据(7位的ASCII字符),注释扩展并不影响对图像数据流的处理,解码器完全可以忽略它。存放位置可以是数据流的任何地方,最好不要妨碍控制和数据块,推荐放在数据流的开始或结尾。在GIF中用识别码0xFE来判断一个扩充块是否为图像注释扩充块。图像注释扩充块中的数据子块个数不限,必须通过块终结符来判断该扩充块是否结束。
(8)应用程序扩充块
应用程序扩充块包含了制作该GIF图像文件的应用程序的信息,GIF中用识别码0xFF来判断一个扩充块是否为应用程序扩充块。它的结构定义如下。
typedef struct gifapplication { BYTE byBlockSize; //应用程序扩充块的长度,取值固定为11 BYTE byIdentifier[8]; //指定应用程序名称 BYTE byAuthentication[3]; //指定应用程序的识别码 }GIFAPPLICATION;
(9)文件结尾块
文件结尾块为GIF图像文件的最后一个字节,其取值固定为0x3B。
习题二
1.光学中的主要计量单位有哪些?它们的含义是什么?
2.什么叫三原色?相加混色和相减混色的原色各是什么?简述它们构成不同彩色的机理。
3.什么是颜色模型?常见的颜色模型有哪些?比较它们的特点和应用场合。
4.什么是马赫带现象?它反映人眼的视觉具有怎样的特点?
5.视觉错觉现象对图形图像处理有什么意义?
6.简述CRT显示器的构造和工作原理。
7.什么是帧缓存?如果帧缓存的大小一定,那么显示系统的屏幕分辨率与可同时显示的颜色数目之间有什么关系?
8.设有三个不同的光栅显示系统,分辨率分别为640×480,1280×1024,2560× 2048,假设每个像素需要12位来存储,那么它们的帧缓存各需要多少字节?如果每像素需要24位,这些系统又需要多大的帧缓存?
9.假设光栅显示系统采用8英寸×10英寸的屏幕,水平和垂直方向的分辨率分别是100PPI(pixel per inch),如果每个像素需要4位来表示,那么帧缓存最少需要多少字节?
10.某彩色图形显示系统,其分辨率为800×600,能显示216种颜色,其帧缓存的容量应为多少?
11.什么是彩色查找表?采用彩色查找表的显示系统工作原理是什么?有什么优越性?
12.某彩色图形显示系统,其分辨率为1024×1024,它可以从217种颜色中选出215种来显示,那么其帧缓存的容量应为多少?彩色查找表的长度和宽度各为多少?
13.17英寸的液晶显示器标准分辨率是1280×1024,如果显示控制器刷新屏幕的速率是每秒60帧,那么系统每秒钟应访问多少像素?每个像素的访问时间是多少?
14.一个光栅扫描显示系统的分辨率是1024×1024,刷新率为每秒60帧,那么在屏幕刷新期间,水平扫描每行像素需要多长时间?
15.假设光栅显示系统采用8英寸×10英寸的屏幕,水平和垂直方向的分辨率分别是100PPI,如果每个像素需要1位来表示,帧缓存的字长为8位,起始地址为0,屏幕上坐标为(x,y)的像素对应在帧缓存的地址是什么?
16.DDB和DIB有什么区别?
17.编写程序将一个二进制的纯数据文件显示成为一幅灰度图像,数据文件中每个字节对应一个像素,图像尺寸人为指定。
18.编程实现BMP文件的显示。
19.假设图像中某行像素值为:0x09(重复70个),0xFA,0x0F,0x06,0x01,如果采用PCX文件的编码方式,则编码后的序列是什么?