我有一个所有者绘制的控件,其中性能是快速重绘期间的问题,例如对象拖动,调整大小和绘制选择器方块。我注意到其他几个应用,包括 Picasa ,会在快速重绘场景中暂时绘制质量降低的图片,然后更新图片用户界面“安定下来”时的高质量版本。
当我进行许多快速重绘时,我应该如何(可以?)生成质量较差的图像?是否存在类似于此的其他策略,我可以使用它来提高性能(或伪造性能提升。)
额外信息:
这是一个类似于表单设计器的应用程序,它大量使用所有者绘图。它工作得很好但是当需要在客户区域中将超过三或四个图像绘制成矩形时开始陷入困境。 (最终用户可以创建不同类型的元素,其中的图像在绘图时会产生最沉重的代价。)
我正在使用DrawImageUnscaled GDI +方法绘制图像,这些图像应该比DrawImage更有效,但性能分析显示DrawImageUnscaled仍然是瓶颈。我认为我唯一的办法是想出一些聪明的方法来减少吸引力。
P.S。之前与此问题相关的问题为我赢得了Tumbleweed徽章,因此我采取了另一种方法:How to increase performance over GDI's DrawImage(Unscaled)?
答案 0 :(得分:3)
策略:
-image对象具有Last Position / Size(rect)成员变量
-repaint of image object绘制全品质
-repaint of image更新最后位置
- 拖动,执行此操作:
* StrechBlt从最后位置/大小到当前位置/大小
*更新最后位置/尺寸
*如果超过几秒钟。从最后一次鼠标移动开始,绘制和/或> .2s,调用重绘(不仅仅是无效 - 你现在想要它)来获得一个新的全质量图像。如果您检测到来自其他对象的重叠(也将获得StrechBlt),也会这样做
我在应用程序中使用的示例代码执行类似的操作(放大效果,可以调整可以包含100个对象的窗口大小 - 看起来像ipad演示更顺畅):
Declare Function StretchBlt Lib "gdi32.dll" _
(ByVal hdcDest As IntPtr, _
ByVal nXOriginDest As Integer, _
ByVal nYOriginDest As Integer, _
ByVal nWidthDest As Integer, _
ByVal nHeightDest As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXOriginSrc As Integer, _
ByVal nYOriginSrc As Integer, _
ByVal nWidthSrc As Integer, _
ByVal nHeightSrc As Integer, _
ByVal dwRop As Int32) As Boolean
Using g As Graphics = f.pb.CreateGraphics
' parm of True says draw plain view - no text = looks bad Zooming.
f.DrawAll(g, True)
For i As Integer = iSteps To 1 Step -1
Dim HDC1 As IntPtr = g.GetHdc
Try
' Size of bite will not be right, but by re-adjusting
' with each iteration, it will make it to full-screen.
' Looks as good as having it right to start with, only much easier.
TopBite = objTop \ i
BottomBite = h - ((h - objBottom) \ i)
' Stretch/move the stuff.
StretchBlt(HDC1, 0, 0, w - LeftBite, h, _
HDC1, LeftBite, TopBite, w - LeftBite, BottomBite - TopBite, 13369376)
' Calculate where MyEntry would be after each stretch. Then the Bite
' size calcs above will ensure its closer next time.
SimulateStretch(objTop, objBottom, TopBite, BottomBite, h)
Finally
g.ReleaseHdc(HDC1)
End Try
' Clear exposed/invalid area to the right.
g.FillRectangle(br, w - LeftBite, 0, LeftBite, h)
' Sleep will make Swells close in duration between small/big window.
' (Can I actually sleep this short of a time?)
System.Threading.Thread.Sleep(5)
Next
End Using
当然,如果某人按照大小的图像然后进行备份,那么它将是超低质量和像素化的 - 所以如果不调整大小,你可以使用更聪明的算法偶尔在mousedrag期间触发真正的onpaint。
注意这个的细节将取决于具体的实施。您应该提供有关您的应用程序的更多详细信息,以便我能够做到正确(它究竟是什么样子?)我假设一个大型的方形用户控件w /许多所有者绘制的元素,所有都同时调整大小。如果你让它们从小处开始并调整大小以便它们开始重叠,那么在鼠标调整大小操作期间,你将不得不经常定期进行完全重绘。