C#:为什么绘图速度很慢?

发布于 2024-10-01 00:23:52 字数 689 浏览 2 评论 0原文

我通过绘制颜色变化的线条来手动绘制线性渐变。然而,这非常慢,当我调整窗口大小时,我似乎会更新。我怎样才能让它更快?在这个例子中,色标是线性的,但后来我不想制作非线性渐变。

protected override void OnPaintBackground(PaintEventArgs paintEvnt)
        {
            SuspendLayout();

            // Get the graphics object
            Graphics gfx = paintEvnt.Graphics;
            // Create a new pen that we shall use for drawing the line

            // Loop and create a horizontal line 10 pixels below the last one
            for (int i = 0; i <= 500; i++)
            {
                Pen myPen = new Pen(Color.FromArgb(i/2,0,0));
                gfx.DrawLine(myPen, 0, i, 132, i);
            }

            ResumeLayout();

        }

Im drawing a linear gradient manually by drawing lines with changing colors. However, this is very slow, and i seems to update, when i resize the window. How do i make it faster? The color scale is linear in this example, but later i wan't to make non-linear gradients.

protected override void OnPaintBackground(PaintEventArgs paintEvnt)
        {
            SuspendLayout();

            // Get the graphics object
            Graphics gfx = paintEvnt.Graphics;
            // Create a new pen that we shall use for drawing the line

            // Loop and create a horizontal line 10 pixels below the last one
            for (int i = 0; i <= 500; i++)
            {
                Pen myPen = new Pen(Color.FromArgb(i/2,0,0));
                gfx.DrawLine(myPen, 0, i, 132, i);
            }

            ResumeLayout();

        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

檐上三寸雪 2024-10-08 00:23:52

问题是 GDI+ 非常慢。

您应该使用相对较快的 GDI+ 高级构造(相对于像现在这样绘制线条)。请参阅 http://msdn.microsoft.com/en- us/library/system.drawing.drawing2d. Lineargradientbrush.aspx 有关例如 LinearGradientBrush 的更多信息。还有更多这样的画笔和笔可以帮助您提高表现。

另一件事: Suspend/ResumeLayout 在您的示例中不执行任何操作。这些方法仅适用于您进行布局时,例如将 Control 添加到当前表单或更改现有 Control 上的属性(例如 Dock 属性)或高度宽度

The problem is that GDI+ is incredibly slow.

You should use high level constructs with GDI+ which are relatively fast (relative to drawing lines like you do now). See http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.lineargradientbrush.aspx for more information about e.g. the LinearGradientBrush. There are much more of these brushes and pens which should help you increase your performance.

One more thing: the Suspend/ResumeLayout doesn't do anything in your example. These methods only apply when you are doing layout by e.g. adding Controls to the current form or changing properties on existing Controls like the Dock property or the Height and Width.

千柳 2024-10-08 00:23:52

如果您只想绘制一次且不调整大小,我建议您将其写入 Bitmap 对象一次,然后将此位图绘制到背景。此外,您还可以在表单上启用双缓冲。这应该是一个名为 DoubleBuffering 的属性,或类似的属性。这应该会减少重绘表单时出现的闪烁。

If you want to paint it once and only once, without resizing, I suggest you write this to a Bitmap object once, and then draw this bitmap to the background. Also, you can enable double buffering on the form. this should be a property called DoubleBuffering, or something similar. This should reduce the flashing you get when redrawing your form.

旧夏天 2024-10-08 00:23:52

您可以预先计算颜色值,这样就不必在每次重绘时都执行此操作。除此之外,如果不求助于更底层的 API(例如 XNA),您就无能为力。

更新:在WinForms控件中托管XNA是完全可行的。 这个问题中有一些不错的链接。

You could pre-compute the color values so you won't have to do it on every redraw. Other than that, there's not much more you can do without resorting to more lowlevel APIs, like XNA.

Update: it is perfectly feasible to host XNA within WinForms controls. There's some nice links forward in this question.

夜空下最亮的亮点 2024-10-08 00:23:52

也许指定 ColorBlend 与 Pieter 建议的 LinearGradientBrush 一起使用将解决您对将来能够绘制非线性渐变的担忧吗?

您可以创建一个 ColorBlend 对象来指定您选择的颜色以及每种颜色的任意位置。通过将 LinearGradientBrushInterpolationColors 属性设置为 ColorBlend 对象,您应该能够获得您想要的任何效果。

MSDN给出了以下示例:

protected override void OnPaint(PaintEventArgs e)
{
    //Draw ellipse using ColorBlend.
    Point startPoint2 = new Point(20, 110);
    Point endPoint2 = new Point(140, 110);
    Color[] myColors = {Color.Green, Color.Yellow, Color.Yellow, Color.Blue, Color.Red, Color.Red};
    float[] myPositions = {0.0f,.20f,.40f,.60f,.80f,1.0f};
    ColorBlend myBlend = new ColorBlend();
    myBlend.Colors = myColors;
    myBlend.Positions = myPositions;
    LinearGradientBrush lgBrush2 = new LinearGradientBrush(startPoint2, endPoint2, Color.Green, Color.Red);
    lgBrush2.InterpolationColors = myBlend;
    Rectangle ellipseRect2 = new Rectangle(20, 110, 120, 80);
    e.Graphics.FillEllipse(lgBrush2, ellipseRect2);
}

Perhaps specifying a ColorBlend to use with the LinearGradientBrush suggested by Pieter will address your concerns about being able to paint non-linear gradients in the future?

You can create a ColorBlend object that specifies the colors of your choice and an arbitrary position for each. By setting the InterpolationColors property of the LinearGradientBrush to your ColorBlend object, you should be able to get any effect that you want.

MSDN gives the following sample:

protected override void OnPaint(PaintEventArgs e)
{
    //Draw ellipse using ColorBlend.
    Point startPoint2 = new Point(20, 110);
    Point endPoint2 = new Point(140, 110);
    Color[] myColors = {Color.Green, Color.Yellow, Color.Yellow, Color.Blue, Color.Red, Color.Red};
    float[] myPositions = {0.0f,.20f,.40f,.60f,.80f,1.0f};
    ColorBlend myBlend = new ColorBlend();
    myBlend.Colors = myColors;
    myBlend.Positions = myPositions;
    LinearGradientBrush lgBrush2 = new LinearGradientBrush(startPoint2, endPoint2, Color.Green, Color.Red);
    lgBrush2.InterpolationColors = myBlend;
    Rectangle ellipseRect2 = new Rectangle(20, 110, 120, 80);
    e.Graphics.FillEllipse(lgBrush2, ellipseRect2);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文