现在的位置: 首页 > 综合 > 正文

画图板(一)MFC双缓冲机制

2013年09月21日 ⁄ 综合 ⁄ 共 1953字 ⁄ 字号 评论关闭

 宿舍一个哥们经常问我,openCV和openGL有什么区别,我很装逼地回答:openCV是处理图像,openGL是图形。并反问:你知道图像和图像的区别吗?看来是我有眼不识泰山了,openCV的强大功能远在我的狭隘认识之上,尤其是那些矩阵的操作,又让 我回想起了当时看openGL函数的挠头,但是学还是要学的,言归正传,这次用openCV提供的函数,完成一个画图板的功能。

功能要求:完成windows画图板的功能。

设计实现:核心函数openCV,界面MFC。

---------------------------------------------------------------------------------------------------------------

截图工具实现:

红线标注图像中感兴趣区域,后台函数将感兴趣区域(ROI)存储。标注感兴趣区域采用鼠标拖动的方式,鼠标按下时确定ROI矩形框的一角,鼠标松开时确定矩形框的另一角,此两点确定矩形的主对角线,从而确定矩形。记录矩形坐标,然后使用openCV函数存储ROI图像。

ROI矩形的记录属于细节问题,

关键点<1>:双缓冲。如果不用双缓冲技术,图像会闪烁,比如我们的程序,每次鼠标的移动都要引起重绘,重绘过程中闪烁现象很明显。此时需要双缓冲技术,网上关于双缓冲的文章汗牛充栋,本文末会附上相关的链接。我总结双缓冲技术是为了解决两个关键点:①重绘初始时,”白素帧"的插入导致巨大的视觉发差②直接将数据写入显存,复杂的显示过程与图像显示同时进行。所以你会看到大部分介绍双缓冲的文章,都会让你这样做:①对重绘消息响应时,直接返回TRUE,以此避免“白素帧”②在重绘函数中,首先将数据写入一个兼容的设备中,然后进行内存的复制。

下面的代码说明一下双缓冲的主要技术

	CDC dcMem;//设备描述符的创建,相当于DC的一个对等体,双缓冲中所有的画图操作都在这个对等体中完成。
	CBitmap bitmapMem;//创建兼容位图,并将此位图装入内存兼容设备环境
	dcMem.CreateCompatibleDC(pDC);//声明,我这个设备描述符是和真正的设备描述符是对等体。
	bitmapMem.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//对位图做类似的声明
	CBitmap *pOldBitmapMem=dcMem.SelectObject(&bitmapMem);

做一个比喻。许多人向A君借钱,到要债的时候了,能一个一个去要吗?可以,但是A君是大忙人,他可不能把大把的时间花在坐飞机去,敲门,要债,喝茶,出门,坐飞机回这样的琐事上,于是他和弟弟B说好了--你替我去要债,都要完后,一并把这些钱给我。这样,同样的结果--A拿到了钱,但是花费的成本完全不同,坐享其成可比挨家挨户地要省力多。A君和B君是对等体,同样在双缓冲机制中,显示器的设备上下文pDC,和我们在OnPaint或者OnDraw中声明的与之兼容的设备上下文dcMem也是对等体,我们让所有的计算过程都在弟弟dcMem上完成,然后由它将做好的位图一手交给哥哥pDC显示。如此一来,可不是能够降低显示的复杂度了么,因为复制过程(通过BitBlt函数完成)可比那些计算过程简单多了。

关键点<2>:显示红色ROI框时,不能使用openCV里的cvRectangle函数,这个函数是破坏性的,会直接将源图像中相应的点变成红色,无法修复。所以,显示红色ROI框,我们选用MFC中设备上下文的相关函数。

好了,这就是一些主要的问题,剩的都是一些小细节的编程问题,本文最后附上一些实现过程中有用的资料,希望可以帮助到网友们。

CArray数组的用法:http://www.cnblogs.com/kingln/archive/2008/08/21/1272962.html

Rectangle用法:http://blog.csdn.net/muzi9_17/article/details/6376922

双缓冲问题: http://blog.csdn.net/zhoxier/article/details/7542371   

http://blog.163.com/yuanlong_zheng@126/blog/static/49846449201033093333394/

http://guohaiyang.blog.163.com/blog/static/3213403720081027104147/     VC对话框中如何添加WM_ERASEBKGND(OnEraseBkgnd函数)

                       

抱歉!评论已关闭.