C #: Почему рисование медленное? - PullRequest
2 голосов
/ 09 ноября 2010

Я рисую линейный градиент вручную, рисуя линии с изменением цвета. Тем не менее, это очень медленно, и я, кажется, обновить, когда я изменяю размер окна. Как мне сделать это быстрее? Цветовая шкала в этом примере линейная, но позже я не буду делать нелинейные градиенты.

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();

        }

Ответы [ 4 ]

3 голосов
/ 09 ноября 2010

Если вы хотите нарисовать его один раз и только один раз, без изменения размера, я предлагаю вам записать это в объект растрового изображения один раз, а затем нарисовать это растровое изображение на фоне.Также вы можете включить двойную буферизацию в форме.это должно быть свойство с именем DoubleBuffering или что-то подобное.Это должно уменьшить мигание, которое вы получаете при перерисовке вашей формы.

3 голосов
/ 09 ноября 2010

Проблема в том, что GDI + невероятно медленный.

Вы должны использовать высокоуровневые конструкции с GDI +, которые относительно быстрые (по сравнению с рисованием линий, как сейчас).См. http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.lineargradientbrush.aspx для получения дополнительной информации, например, о LinearGradientBrush.Этих кистей и ручек гораздо больше, что должно помочь вам повысить производительность.

Еще одна вещь: Suspend/ResumeLayout ничего не делает в вашем примере.Эти методы применяются только тогда, когда вы делаете макет, например, добавляя Control s к текущей форме или изменяя свойства существующих Control s, таких как свойство Dock или Height и Width.

1 голос
/ 09 ноября 2010

Вы можете предварительно вычислить значения цвета, чтобы вам не приходилось делать это при каждом перерисовке.Кроме этого, вы не можете сделать намного больше, не прибегая к более низкоуровневым API, таким как XNA.

Обновление: вполне возможно разместить XNA в элементах управления WinForms.В этом вопросе есть несколько интересных ссылок .

0 голосов
/ 09 ноября 2010

Возможно, указание ColorBlend для использования с LinearGradientBrush, предложенным Питером, поможет решить ваши проблемы с возможностью рисовать нелинейные градиенты в будущем?

Вы можете создать ColorBlend объект, который задает цвета по вашему выбору и произвольную позицию для каждого. Установив свойство InterpolationColors объекта LinearGradientBrush для объекта 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...