如何模仿Picasa渲染质量降低的图像以加快绘图速度

Pau*_*sik 7 .net c# vb.net performance gdi+

我有一个所有者绘制的控件,其中性能是快速重绘期间的问题,例如对象拖动,调整大小和绘制选择器方块.我注意到其他几个应用程序,包括Picasa,将在快速重绘场景中暂时绘制质量较低的图像,然后在UI"稳定下来"时使用更高质量的版本更新图像.

当我进行许多快速重绘时,我应该怎样(可以吗?)制作质量较低的图像?是否有其他类似的策略我可以用来提高性能(或虚假提高性能.)

额外信息:

这是一个类似于表单设计器的应用程序,它大量使用所有者绘图.它工作得很好但是当需要在客户区域中将超过三或四个图像绘制成矩形时开始陷入困境.(允许最终用户创建不同类型的元素,其中图像对绘图造成的影响最大.)

我使用DrawImageUnscaled GDI +方法绘制图像,这些图像应该比DrawImage更有效,但性能分析显示DrawImageUnscaled仍然是瓶颈.我认为我唯一的办法就是想出一些聪明的方法来减少吸引力.

PS上一个与此问题相关的问题为我赢得了Tumbleweed徽章,所以我采取了另一种方法:如何提高GDI的DrawImage(非标榜)的性能?

Fas*_*tAl 3

等等——你在这里错过了一个容易实现的目标。在调整大小操作期间,这些可能根本没有真正重新绘制图像。他们可能会使用 StretchBlt 调整视频 RAM 中现有图像的大小,这可以通过视频驱动程序/硬件进行优化,速度非常非常快,比您“重新绘制质量降低的图像”还要快。

策略
-图像对象具有最后位置/大小(矩形)的成员变量
-图像对象的重新绘制绘制全质量 -
图像的重新绘制更新最后位置
-在拖动过程中,执行以下操作:
* StrechBlt 从最后位置/大小到当前位置/尺寸
* 更新最后位置/尺寸
* 如果超过几秒。绘图,和/或自上次鼠标移动后 >.2 秒,调用重绘(不仅仅是无效 - 您现在想要它)以获得新的全质量图像。如果您检测到与其他对象的重叠,也可以这样做(也会得到 StrechBlt'd)

我在一个应用程序中使用的示例代码执行类似的操作(类似放大的效果,可以调整可能包含 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
Run Code Online (Sandbox Code Playgroud)

当然,如果有人调整它的小图像大小然后备份,它将是超低质量和像素化的 - 因此,如果不调整大小,您可以使用更智能的算法在鼠标拖动期间偶尔触发真正的 onpaint。

请注意,具体细节取决于具体实施。您应该提供您的应用程序的更多详细信息,以便我可以正确使用它(它到底是什么样子?)我假设一个大方形用户控件带有许多所有者绘制的元素,所有元素一次均等地调整大小。如果您让它们从小处开始并调整大小以使它们开始重叠,则您必须在鼠标调整大小操作期间更频繁地定期进行完全重绘。