三、Windows图像处理—画点和线(绘图方式)
设备内容中定义的绘图方式也影响显示器上所画线的外观。设想画这样一条直线,它的色彩由画笔色彩和画线区域原来的色彩共同决定。设想用同一种画笔在白色表面上画出黑线而在黑色表面上画出白线,而且不用知道表面是什么色彩。这样的功能对您有用吗?通过绘图方式的设定,这些都可以实作。
当Windows使用画笔来画线时,它实际上执行画笔图素与目标位置处原来图素之间的某种位布尔运算。图素间的位布尔运算叫做「位映像运算」,简称为「ROP」。由于画一条直线只涉及两种图素(画笔和目标),因此这种布尔运算又称为「二元位映像运算」,简记为「ROP2」。Windows定义了16种ROP2代码,表示Windows组合画笔图素和目标图素的方式。在内定设备内容中,绘图方式定义为R2_COPYPEN,这意味着Windows只是将画笔图素复制到目标图素,这也是我们通常所熟知的。此外,还有15种ROP2码。
16种不同的ROP2码是怎样得来的呢?为了示范的需要,我们假设使用单色系统,目标色(窗口显示区域的色彩)为黑色(用0来表示)或者白色(用1来表示),画笔也可以为黑色或者白色。用黑色或者白色画笔在黑色或者白色目标上画图有四种组合:白笔与白目标、白笔与黑目标、黑笔与白目标、黑笔与黑目标。
画笔在目标上绘制后会得到什么呢?一种可能是不管画笔和目标的色彩,画出的线总是黑色的,这种绘图方式由ROP2代码R2_BLACK表示。另一种可能是只有当画笔与目标都为黑色时,画出的结果才是白色,其它情况下画出的都是黑色。尽管这似乎有些奇怪,Windows还是为这种方式起了一个名字,叫做R2_NOTMERGEPEN。Windows执行目标图素与画笔图素的位「或」运算,然后翻转所得色彩。
表5-2显示了所有16种ROP2绘图方式,表中指示了画笔色彩(P)与目标色彩(D)是如何组合而成结果色彩的。在标有「布尔操作」的那一栏中,用C语言的表示法给出了目标图素与画笔图素的组合方式。
表5-2 |
画笔(P):目标(D): |
1 1 |
1 0 |
0 1 |
0 0 |
布尔操作 |
绘图模式 |
结果: |
0 |
0 |
0 |
0 |
0 |
R2_BLACK |
0 |
0 |
0 |
1 |
~(P | D) |
R2_NOTMERGEPEN |
|
0 |
0 |
1 |
0 |
~P & D |
R2_MASKNOTPEN |
|
0 |
0 |
1 |
1 |
~P |
R2_NOTCOPYPEN |
|
0 |
1 |
0 |
0 |
P & ~D |
R2_MASKPENNOT |
|
0 |
1 |
0 |
1 |
~D |
R2_NOT |
|
0 |
1 |
1 |
0 |
P ^ D |
R2_XORPEN |
|
0 |
1 |
1 |
1 |
~(P & D) |
R2_NOTMASKPEN |
|
1 |
0 |
0 |
0 |
P & D |
R2_MASKPEN |
|
1 |
0 |
0 |
1 |
~(P ^ D) |
R2_NOTXORPEN |
|
1 |
0 |
1 |
0 |
D |
R2_NOP |
|
1 |
0 |
1 |
1 |
~P | D |
R2_MERGENOTPEN |
|
1 |
1 |
0 |
0 |
P |
R2_COPYPEN(内定) |
|
1 |
1 |
0 |
1 |
P | ~D |
R2_MERGEPENNOT |
|
1 |
1 |
1 |
0 |
P | D |
R2_MERGEPEN |
|
1 |
1 |
1 |
1 |
1 |
R2_WHITE |
可以通过以下呼叫在设备内容中设定新的绘图模式:
SetROP2 (hdc, iDrawMode) ;
iDrawMode参数是表中「绘图模式」一栏中给出的值之一。您可以用函数:
iDrawMode = GetROP2 (hdc) ;
来取得目前绘图方式。设备内容中的内定设定为R2_COPYPEN,它用画笔色彩替代目标色彩。在R2_NOTCOPYPEN方式下,若画笔为黑色,则画成白色;若画笔为白色,则画成黑色。R2_BLACK方式下,不管画笔和背景色为何种色彩,总是画成黑色。与此相反,R2_WHITE方式下总是画成白色。R2_NOP方式就是「不操作」,让目标保持不变。
现在,我们已经讨论了单色系统。然而,大多数系统是彩色的。在彩色系统中,Windows为画笔和目标图素的每个颜色位执行绘图方式的位运算,并再次使用上表描述的16种ROP2代码。R2_NOT绘图方式总是翻转目标色彩来决定线的颜色,而不管画笔的色彩是什么。例如,在青色目标上的线会变成紫色。R2_NOT方式总是产生可见的画笔,除非画笔在中等灰度的背景上绘图。我将在 第七章的BLOKOUT程序中展示R2_NOT绘图方式的使用。