VB哪个函数或程序画图最快呢? 我用FORM自带的PAINTPICTURE,非常慢,有类似的API比较快,而且可以平铺图片吗? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 PAINTPICTURE应该不慢,除非你循环调用个成千上万下.类似的API有: BITBLT, TRANSPARENTBLT, StretchBlt等等 还有,图形上处理慢的原因估计是你用的是你把AutoRedraw设置为True,然后进行绘制过程。这样效率会降低很多。因为你没做一个动作它都会记忆一次,并且刷新到窗口上显示出来。如果你要进行平铺50张图片,那么就会记忆和刷新50次,效率肯定不会高。通常的做法应该是将要处理的过程在内存中直接处理好,然后再刷新窗口显示出来。对于图形而言,通常使用GDI或GDI+或DirectX来做这些事。比较符合Windows习惯的做法就是GDI。GDI是一系列的API函数,通常GDI函数是指调用gdi32.dll里的API函数。比如楼上所说的BitBlt函数和StretchBlt函数都属于标准的GDI函数。但即使是GDI的API函数,如果使用的方法不对也是不能提高效率的,比如如果还是按照绘制一张图就刷新到窗口上显示出来,速度也不会提高多少,因为还是经过了平凡的显示着一块,这是很浪费资源的操作(在重复多次操作中特别明显)。所以需要在内存中直接处理重复的这些操作,然后可以在处理完成后一次刷新结果到窗口上,这样效果会好很多。不知道你有没有看过用GDI方法开发的游戏,大致就是这么一个过程,因为在频繁的图片绘制中,如果每一个小图片或小标志都要刷新一次窗口显示出来,那个游戏肯定没法玩下去,呵呵。而这种所谓在内存的处理方法其实就是建立一个内存里的GDI设备来完成,这个GDI设备就像PictureBox的hDC设备,但是他和不关联窗口(当然可以做关联窗口的设备),所以在这种设备绘制完不会显示出来,如果要显示这个设备的内容,那么就把这个设备的内容整个绘制到你要显示的设备上就可以了。就你的需求来说其实就像我上面所说的,用区域的方式以刷子填充还是比较快的,至于如何实现,你可以参考以下几个GDI函数:CreateRectRgnCreateEllipticRgnCreatePolygonRgnCreatePolyPolygonRgnFillRgnPaintRgnSelectObjectDeleteObjectCreatePatternBrushCreateDIBSectionCreateCompatibleDCDeleteDC这些GDI函数使用起来也不难,在网上可以查一下使用方法应该可以做出你想要的效果了 这段话的观点我完全不同意。Autoredraw吧不会拖慢绘图的速度,你说的会拖慢是因为你用了不恰当的方法。如果你把Autoredraw设置为true,为了执行效率,你就不要用VB自带的一些绘图方法了,比如line,circle,因为这些封装好的方法会在执行完毕后执行refresh,这个时候我们就应该用GDI的函数来代替这些方法,并且在绘图结束后,手动调用refresh方法,让后台DC的图像绘制倒前台DC。Autoredraw和你后面所说的在内存中建立缓冲区是一个目的,都是为了实现双缓冲而已。如果我们自己建立双缓冲,一般都是需要在paint事件中加入代码的,而如果设置了autoredraw,则VB会bang我们完成任务。 SupermanKing和laviewpbt所说的我都认真看过了,可能我真的应该如laviewpbt所说,方法用得不太好,我是在usercontrol里来画一个窗口,然后再用一般的form进行加载来显示的,刚调用的时候没什么,但后来发现在改变大小后觉得非常慢,我主要是用paintpicture来画图,不知道是否因为usercontrol导致慢了? 发表一下我的看法:如果在同样的条件下频繁绘图,Autoredraw设置为true决对没有Autoredraw设置为False的速度快,因为Autoredraw设置为true毕竟会多一些处理过程,除了占用内存,还占用CPU,如果对大量频繁的绘图操作来说是很不利的。比如一个游戏的绘图操作基本都是这么个过程...IsExit=FalseDo '这里是扫描键盘呀鼠标呀什么的其他过程 ... '这里是将有关信息在设备里处理并绘图过程 ... Scene.Refresh '刷新到窗口Loop IsExit=Trueend...如果这时要刷新的窗口或PictureBox的Autoredraw设置为true,可能会产生以下问题1、会有卡的现象,画面可能不流畅(当然这也和硬件或分辨率有关,有些硬件快起来根本看不出卡,呵呵)2、有可能导致内存不够的情况(这种情况在Autoredraw设置为true的时候频繁操作很容易出现)但是Autoredraw设置为False则非常流畅,同时如果对比系统资源的使用情况将会发现,内存和CPU的占用也会少很多,对于频繁的绘图操作,比如动画、游戏等,建议都不要将Autoredraw设置为true,因为重绘窗口的速度可能比收到paint消息的速度还要快还要频繁,没必要让VB再去存储呀处理的了。 关键要考虑绘图速度和刷新频率。1)如果绘图比较慢。比如很复杂的图,要用 0.1 秒才能画出来,那么中间过程肉眼能够看到,用双缓冲(AutoRedraw = True)就能避免视觉滞留导致的闪烁。2)如果绘图很快,刷新适中。比如频率为 20 帧/秒,每帧只要 0.001 秒就可以画完,那么不用缓冲直接绘制(AutoRedraw = False)最合适。3)如果刷新过快。还是 0.001 秒画完 1 帧,但是频率为 1000 帧/秒,远高于一般显示器的刷新频率,大部分帧根本没机会显示到屏幕上;而且无论是否用缓冲,过量的刷新事件会拖慢整个程序的响应速度。 非常同意Tiger_Zhao (VB老鸟) 的意见。 一般的Bitblt就行了,比那个PaintPicture快多了。还想再快就要用Direct3D 或者 DirectDraw了。 但如果想平铺图片,用bitblt不就应该用for来循环吗?这样还会比paintpicture快吗? 会,如果在GDI设备环境下会快很多,图像越大差距越大。 关键是 penguinhzf 实测 1 次绘图用时多少?需求决定方案,没有前提单纯讨论哪种方案好是没意义的。 SQL语句问题。。急急急。。 神哪!救救偶吧!! vb按行逐个读取txt数据 并作为记录保存到ACESS的代码 有关recordset的问题 新手问,关于函数定义,参数可不可以为数组? 这是不是病呀 请高手指点迷津,这是什么问题? 怎样实现access数据的相互导入???? ⊙⊙知情者请告知,真的有这么好的事情?Up者有分⊙⊙ 打开WINDOWS文件夹对话框如何设置默认值? VBA如何执行带参数的存储过程 看来看去还是这本好. 什么起点纵横都是渣呀.
类似的API有: BITBLT, TRANSPARENTBLT, StretchBlt等等
这样效率会降低很多。因为你没做一个动作它都会记忆一次,并且刷新到窗口上显示出来。
如果你要进行平铺50张图片,那么就会记忆和刷新50次,效率肯定不会高。通常的做法应该是将要处理的过程在内存中直接处理好,然后再刷新窗口显示出来。对于图形而言,
通常使用GDI或GDI+或DirectX来做这些事。比较符合Windows习惯的做法就是GDI。GDI是一系列的API函数,通常GDI函数是指调用gdi32.dll里的API函数。比如楼上所说的BitBlt
函数和StretchBlt函数都属于标准的GDI函数。但即使是GDI的API函数,如果使用的方法不对也是不能提高效率的,比如如果还是按照绘制一张图
就刷新到窗口上显示出来,速度也不会提高多少,因为还是经过了平凡的显示着一块,这是很浪费资
源的操作(在重复多次操作中特别明显)。所以需要在内存中直接处理重复的这些操作,然后可以在
处理完成后一次刷新结果到窗口上,这样效果会好很多。不知道你有没有看过用GDI方法开发的游戏,大致就是这么一个过程,因为在频繁的图片绘制中,如果
每一个小图片或小标志都要刷新一次窗口显示出来,那个游戏肯定没法玩下去,呵呵。而这种所谓在内存的处理方法其实就是建立一个内存里的GDI设备来完成,这个GDI设备就像PictureBox
的hDC设备,但是他和不关联窗口(当然可以做关联窗口的设备),所以在这种设备绘制完不会显示出来,
如果要显示这个设备的内容,那么就把这个设备的内容整个绘制到你要显示的设备上就可以了。就你的需求来说其实就像我上面所说的,用区域的方式以刷子填充还是比较快的,至于如何实现,你可以
参考以下几个GDI函数:
CreateRectRgn
CreateEllipticRgn
CreatePolygonRgn
CreatePolyPolygonRgn
FillRgn
PaintRgn
SelectObject
DeleteObject
CreatePatternBrush
CreateDIBSection
CreateCompatibleDC
DeleteDC这些GDI函数使用起来也不难,在网上可以查一下使用方法应该可以做出你想要的效果了
这段话的观点我完全不同意。
Autoredraw吧不会拖慢绘图的速度,你说的会拖慢是因为你用了不恰当的方法。
如果你把Autoredraw设置为true,为了执行效率,你就不要用VB自带的一些绘图方法了,比如line,circle,因为这些封装好的方法会在执行完毕后执行refresh,这个时候我们就应该用GDI的函数来代替这些方法,并且在绘图结束后,手动调用refresh方法,让后台DC的图像绘制倒前台DC。Autoredraw和你后面所说的在内存中建立缓冲区是一个目的,都是为了实现双缓冲而已。如果我们自己建立双缓冲,一般都是需要在paint事件中加入代码的,而如果设置了autoredraw,则VB会bang我们完成任务。
如果在同样的条件下频繁绘图,Autoredraw设置为true决对没有Autoredraw设置为False的速度快,
因为Autoredraw设置为true毕竟会多一些处理过程,除了占用内存,还占用CPU,如果对大量频繁的
绘图操作来说是很不利的。
比如一个游戏的绘图操作基本都是这么个过程
...
IsExit=False
Do
'这里是扫描键盘呀鼠标呀什么的其他过程
...
'这里是将有关信息在设备里处理并绘图过程
...
Scene.Refresh '刷新到窗口
Loop IsExit=True
end...如果这时要刷新的窗口或PictureBox的Autoredraw设置为true,可能会产生以下问题
1、会有卡的现象,画面可能不流畅(当然这也和硬件或分辨率有关,有些硬件快起来根本看不出卡,呵呵)
2、有可能导致内存不够的情况(这种情况在Autoredraw设置为true的时候频繁操作很容易出现)但是Autoredraw设置为False则非常流畅,同时如果对比系统资源的使用情况将会发现,
内存和CPU的占用也会少很多,对于频繁的绘图操作,比如动画、游戏等,建议都不要将
Autoredraw设置为true,因为重绘窗口的速度可能比收到paint消息的速度还要快还要
频繁,没必要让VB再去存储呀处理的了。
比如很复杂的图,要用 0.1 秒才能画出来,那么中间过程肉眼能够看到,用双缓冲(AutoRedraw = True)就能避免视觉滞留导致的闪烁。2)如果绘图很快,刷新适中。
比如频率为 20 帧/秒,每帧只要 0.001 秒就可以画完,那么不用缓冲直接绘制(AutoRedraw = False)最合适。3)如果刷新过快。
还是 0.001 秒画完 1 帧,但是频率为 1000 帧/秒,远高于一般显示器的刷新频率,大部分帧根本没机会显示到屏幕上;而且无论是否用缓冲,过量的刷新事件会拖慢整个程序的响应速度。
(VB老鸟) 的意见。
还想再快就要用Direct3D 或者 DirectDraw了。
但如果想平铺图片,用bitblt不就应该用for来循环吗?这样还会比paintpicture快吗?
需求决定方案,没有前提单纯讨论哪种方案好是没意义的。