更新图形中的矩形区域

时间:2010-07-15 09:35:19

标签: .net optimization gdi+

我在绘图区域绘制绘图。

为了优化该绘图的性能,我决定仅在真正必要的区域(剪切区域)内重绘。见图。

问题是我没有到达构建一个方法(GetBitmapFromRectangle),它返回我的路径与剪切矩形的交集结果。 当用户移动(使用鼠标)路径时,此方法非常有用。在这种情况下,需要重新绘制前者和当前移动的路径区域 - 而不是整个图片,在复杂图片的情况下,可能会明显降低应用程序性能。

我的测试显示计算时间远不如绘图那么重要,所以我最好执行更多的绘图来进行绘图。

我想绘制的不是与矩形相交的整个路径,而是只绘制里面剪切区域的路径。

alt text http://lh5.ggpht.com/_1TPOP7DzY1E/TD7T0jNU-wI/AAAAAAAADUM/YxaQu4hANpU/s800/Capture1.gif

换句话说,我需要一种方法在红色区域内制作蓝色线条PINK

以下是代码:

using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication38
{
    public partial class Form1 : Form
    {
        Point center;
        int radius, penWidth;

        public Form1()
        {
            InitializeComponent();
            center = new Point(50, 50);
            radius = 100;
            penWidth = 5;
            this.ResizeRedraw = true;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            e.Graphics.Clear(this.BackColor);

            e.Graphics.DrawImage(
                GetBitmapFromRectangle(e.ClipRectangle),
                e.ClipRectangle.Location);

            //
            // INITIAL DRAWING METHOD
            //            
            Pen p = new Pen(Color.Blue, penWidth);
            // draw O
            e.Graphics.DrawEllipse(p, center.X - radius, center.Y - radius, radius * 2, radius * 2);
            // draw X
            Point[] line1 = new Point[] { new Point(0, 0), new Point(this.Width, this.Height) };
            Point[] line2 = new Point[] { new Point(this.Width, 0), new Point(0, this.Height) };
            e.Graphics.DrawLines(p, line1);
            e.Graphics.DrawLines(p, line2);
            p.Dispose();
        }

        private Bitmap GetBitmapFromRectangle(Rectangle rect)
        {
            Bitmap bmp = new Bitmap(rect.Width, rect.Height);
            Graphics g = Graphics.FromImage(bmp);
            if (rect != this.DisplayRectangle)
                g.Clear(Color.Red);
            else
                g.Clear(this.BackColor);

            // Draw ONLY! the intersetion between drawing and rectangle...
            // How to ???

            return bmp;
        }
    }
}

Nota bene

该示例仅用于演示目的的示例。在真实的项目中,我的图形非常复杂,绘图时间比计算时间要贵得多。这就是为什么我不想重绘所有的绘画,而只是重绘剪辑区域内的线条!

3 个答案:

答案 0 :(得分:0)

在此之前,我建议通过手动剔除集合来测试性能改进,并在有和没有剔除的情况下比较帧速率。您可能会发现GDI +已经优化了您在视口外部绘制的任何内容。

如果您发现剔除有帮助,最简单的方法是找到每个对象的边界框并测试矩形交叉点:

bool intersect = left1 < right2 && left2 < right1 && top1 < bottom2 && top2 < bottom1.

根据绘图的类型,这可能会有很高的误命中率,例如围绕视口的大空心圆,但它通常在大多数情况下表现良好。

答案 1 :(得分:0)

我会将现有的绘图代码复制到GetBitmapFromRectangle方法而不做任何更改。已经通过减少更新区域来完成所需的优化。复制到GetBitmapFromRectangle的现有代码只是在位图边界之外绘制一些行,这没关系 - Graphics类可以处理这个问题。使用剪切矩形测试每个绘图基元以确定是否会降低程序性能。

答案 2 :(得分:-1)

您应该查看System.Drawing.Drawing2D中的GraphicsPath类。