复杂的开发测井工程图件因含有大量的图像元素,要经过大量的比例关系换算、坐标系的转换和复杂的坐标映射才能将像素在正确的位置显示出来。巨幅、需滚屏显示的测井曲线,其运算量更大,如按常规滚屏的方法直接在应用程序的窗口绘制全图,由于开始绘制曲线像素所需的大量图元计算时间和结束像素绘制时间之间有一个延迟,而经常会出现图像的刷新速度慢、图像重叠和闪烁、花屏等现象。应用双缓冲技术,首先在内存中绘制整个测井曲线,在滚屏显示过程中将内存中相应位块的图像剪贴到显示区域,就能克服上述问题,连续地显示曲线,进而将内存中的设备相关图像转换成设备无关的、标准格式的图像进行保存。
在Windows中,应用程序在下面情况下会发出WM_PAINT消息请求绘图:
(1)当创建窗体或改变窗体大小时;
(2)在程序中使用Invalidate等函数来指定更新区域时;
(3)执行其它会影响客户区的操作时;
Windwos接收WM_PAINT消息后,就会执行OnPaint函数进行窗口的重绘工作,Windows自身所提供的绘图机制中,重绘窗口分两步进行:首先,Windows要发送WM_ERASEBKGND消息到窗口来通知窗口擦除背景,当窗口接收到WM_ERASEBKGND消息后,会调OnEraseBkgnd函数来进行处理,这会导致用窗口的背景色填充整个窗口。上述背景重绘之后,接着实现窗口图形的重绘。如果不断有WM_PAINT消息请求绘图,就总会有窗口背景重绘和图形重绘交替出现。即造成屏幕图形闪烁有两种情况,屏幕背景刷新与测井图形刷新。
(1)针对背景刷新引起的闪烁,采用了不进行背景重绘的方法来消除。
可以采取如下方法实现不执行系统默认的擦除背景操作:
①把系统缺省的背景刷子设置为NULL,那么窗体就不会在刷新屏幕时擦除背景。可以在重载后窗体的PreCreateWindow函数中实现。
②重载OnEraseBkgnd函数,并在实现该函数时不调用基类函数。
③把默认的背景刷修改为NULL,也可以实现不擦除背景。
(2)针对测井图形刷新造成的屏幕闪烁现象,采用内存DC绘图来消除屏幕闪烁。
首先是创建内存曲线在windows程序中,所有的绘图操作必须建立在windows的DC(Device Context)基础上,在调用GDI(graphic device interface)函数绘制图形之前,首先要得到DC。DC是描述绘图设备的数据结构,它可能是实际的物理绘图设备或是伪设备,它的作用是提供与物理设备或伪设备之间的关系。创建内存位图,首先创建一个内存DC,再创建与显示DC相兼容的位图对象,将位图选人内存DC,再在内存上绘制整个测井曲线。部分C++代码如下:
CBitmap bitmap; CDC memDC; memDC.CreateCompatibleDC(pDC); CReet rect;GetClientRect(&rect); bitmap.CreateCompatibleBitmap(pDC,PicWidth,PicHeight); CBitmap *pOldBitmap = memDC.SelectObject(&bitmap); memDC.FillSolidRect(0,0,PicWidth,PicHeight,RealTimDisply.BackColor); pDC->BitBlt(0,0,PicWidth,PicHeight,&memDC,0,0,SRCCOPY); memDC.SelectObject(pOldBitmap); memDC.DeleteDC();
还可以利用局部重绘法实现大数据量测井图形的快速连续滚动显示
测井图形一般幅度很大,当道很多并且绘图深度很长时,横向和纵向都不可能在当前窗口一次全部显示出来.如果采用通常的绘图方法,一次把整幅测井图全部绘制出来,由于绘图数据量非常大,绘图速度很慢,甚至用户无法接受.所以必须采用好的绘图技术,提高绘图效率。连续滚动显示是常用的方法,但是必须解决巨幅测井图形的绘图速度问题。
(1)整幅图形全刷新的方法实现滚动存在的问题
为了解决屏幕闪烁问题,前面采用了内存DC绘图的技术。那么,如果采用一般的、也是最容易实现的滚动显示方案,就是每次滚动都重新绘制整幅图形,即:全刷新的方法。具体是:先根据实际测井图形的大小,在内存中把整幅图都绘制出来,每次滚动时,都重新绘制整幅图形,然后根据采用的映射方式,把整幅图拷贝到屏幕。现假设当前映射方式下X坐标向右为正,Y坐标向上为正,那么不管当前滚动条的位置在哪儿,只要把内存中的图形左上角对应屏幕坐标的(0,0)点进行拷贝,就可以实现滚动显示。如果绘制的图形幅度较小,这种方法实现比较容易,也能满足要求。但是测井图形一般很大,每次都绘整幅图形,绘图速度会很慢,而且由于图形大,开辟的内存也大,会出现严重的内存不足问题。所以实际开发中一般不采用。
(2)只刷新当前屏幕的方法实现滚动显示
只刷新当前屏幕的方法是指每次滚动都根据当前滚动条的位置,计算屏幕应该显示图形的哪部分,然后在内存中绘出图形,并拷贝到当前屏幕客户区。这种方法每次只需要绘制当前屏幕客户区一样大小的图形,这样一方面减少了每次滚动时绘图的数据量,提高了绘图速度,同时由于只绘制和屏幕一样大小的图形,所以占用的内存也小了,提高了绘图效率。这种方法比整幅图形刷新效率高很多,但是,每次刷新必须准确计算当前屏幕图形在整幅图形中的位置。
(3)局部重绘的方法实现快速连续滚动显示
只刷新当前屏幕的方法在一些情况下可以应用,但是当测井图形复杂,数据量很大时,仍然存在绘图速度慢的问题,如绘制声电成像测井图。而采用局部重绘的方法每次只绘制新滚入屏幕的部分,可以进一步减少绘图工作量,提高绘图速度,这种方法由于每次刷新重绘的面积小,绘图占用的内存也少,效率很高。