继续请教windows画图程序的刷新方法。

guopo 2006-06-14 06:55:18
拿一个简单的列子来说明一下我现在遇到的问题。

我用windows自带的画图软件,首先打开一张bmp图片,然后进入画直线功能,这时我在鼠标点击并按下后,你会看到直线会跟着鼠标改变方向,松开左健直线绘制结束。我观察整个鼠标移动过程中,对于1280x1024的位图,cpu占用率为20%以内。

我的功能大概与此类似,找了一天的原因,发现cpu占用率高,主要是因为重绘。所以我对绘制部分作了大量的测试,结果还是达不到理想的效率,尤其是鼠标快速移动时,cpu使用率迅速提高,我用了局部刷新,用了后台缓冲,还是不行,不过如果我每10个刷一次效果就好很多,但处理起来有些顿,再次请教高手,能否分析一下画图软件的刷新过程(在一幅bmp图上画直线)。


...全文
396 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
hikuers 2006-06-17
  • 打赏
  • 举报
回复
楼主有没有研究过一些矢量作图的软件,比如arcinfo,mapinfo等等,
我看了一下mapinfo的绘图,cpu的占用率比画图板的还地一点,
还有autocad的也很低的
noneone 2006-06-17
  • 打赏
  • 举报
回复
你的问题应该是重画太频繁了,彻底的解决方案是将鼠标操作和绘图分离,譬如放到两个线程里面,主进程响应鼠标动作,并记录图像的内容,绘图进程定期绘制图片。
如果图省事的话,有个土办法,根据电影的原理,如果每秒超过24帧的话,人的视觉系统就认为图像是连续的,那么我们可以认为两次绘制间隔时间少于1/24秒的话人的眼睛是分辨不出来的(事实上不完全是这样),所以解决方法如下:
1.每次有效绘制(即真正有绘制操作)时记录一下时间戳;
2.绘制时如果发现上次有效绘制时间距离现在少于1/24秒,那么不进行绘制
3.使用其他方法处理一下边界问题

声明一下,后面这种方法我没有用过,如果造成任何损失,我不负任何责任。原理上应该是可行的,因为这两种方式事实上是一样的,只是一个是双线程,另一个是把所有的操作放到了一个线程里面。
吃狼的豆腐 2006-06-17
  • 打赏
  • 举报
回复
当MouseMove的时候检查鼠标左键有没有按下,然后直接画就好了啊
cpio 2006-06-17
  • 打赏
  • 举报
回复


你不要在鼠标移动的时候调用Invalidate,直接往上面画就行了

调用Invalidate后会导致图片重绘,你现在只是要画线

void CDlgXXX::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

static CPoint oldPoint(point);
CDC *pDC = GetDC();
pDC->MoveTo(oldPoint);
pDC->LineTo(point);
oldPoint= point;
ReleaseDC(pDC);
xing_xing_xing 2006-06-17
  • 打赏
  • 举报
回复
InvalidateRect(&r,FALSE);
gdsdyl 2006-06-17
  • 打赏
  • 举报
回复
使用OpenGL或者GDI+
fireseed 2006-06-16
  • 打赏
  • 举报
回复
用异或来处理像素,不要重绘
dic_walter 2006-06-16
  • 打赏
  • 举报
回复
在你松开鼠标的时候画出来即可
dic_walter 2006-06-16
  • 打赏
  • 举报
回复
你建立一个内存链表,每次更改的时候,先写到临时内存里面,然后一次性画出来,这样就不需要在移动鼠标的都刷新了。
蒋晟 2006-06-15
  • 打赏
  • 举报
回复
The CRectTracker class uses XOR drawing. Step through its source to find out how it works
guopo 2006-06-15
  • 打赏
  • 举报
回复
谢谢大家!

to cenchure:
我觉得如果是开新窗口的话,其实和局部刷新的效果差不多,而且还麻烦.

to cpio:

测试结果表明鼠标移动过程中频繁刷新会占用很高的cpu.

gentlelotus:
我还是希望在bmp上直接画.

to DentistryDoctor:
我正是这么测试的.

jiangsheng:
我不想用mfc,我想做一个win32的dll

希望继续讨论!
biosheep 2006-06-15
  • 打赏
  • 举报
回复
路过,学习

原来jiangsheng(蒋晟.Net[MVP])这么练就的,这么晚才睡觉!
敬佩!!!
蒋晟 2006-06-15
  • 打赏
  • 举报
回复
override CRectTracker...
CUG122032 2006-06-15
  • 打赏
  • 举报
回复
GDI+
xiangrujian 2006-06-14
  • 打赏
  • 举报
回复
学习帮顶!
gentlelotus 2006-06-14
  • 打赏
  • 举报
回复
听起来好像你在处理每个鼠标移动消息时都作了整个窗口的重绘动作吧,如果这样的话,那么也许可以作如下的修改:对于使用GDI绘制的情况,使用橡皮线的绘制原理(就是使用XOR绘制模式)绘制动态直线,当鼠标松开时才正式的在BMP图中绘制你要绘制的直线并进行刷新(这样带来的问题就是,如果实际是要绘制一条红色的直线段,那么在拖动鼠标时绘制的一般不是红色的线,只有松开了鼠标才能看到是红色的线,不过大部分比较简单的绘图软件本身也没有解决这个问题);对于使用OpenGL或者GDI+等其他方式绘制应该只要使用缓冲了就不会有问题。
DentistryDoctor 2006-06-14
  • 打赏
  • 举报
回复
用双缓冲,并且只刷新需要刷新的部分。
cpio 2006-06-14
  • 打赏
  • 举报
回复
以前说过吧,用GDI画很快

图片直接用Bitblt,也不占什么CPU啊
cenchure 2006-06-14
  • 打赏
  • 举报
回复
他的直线可能 不是 及时画上去的, 是贴的,mousedown 会有个新窗口 在上面 ,窗口的颜色就是 直线的颜色。鼠标 按键 LMouseUP 后才贴到真正的 贴画布上的

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧