GDI + Как изменить Line SmoothingMode? - PullRequest
6 голосов
/ 17 февраля 2010

Можно ли изменить PowerPacks.LineShape smoothingMode?

Я пытался использовать этот код (класс, который наследует LineShape):

  Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    Dim g As Graphics = e.Graphics   

    ' no difference when changing the SmoothingMode ' 
    g.SmoothingMode = SmoothingMode.AntiAlias 

    Using pen As New Pen(Color.Blue, 3)
      g.DrawLine(pen, X1, Y1, X2, Y2)
    End Using

    ' MyBase.OnPaint(e) '
  End Sub

У меня всегда один и тот же результат, вот так: альтернативный текст http://lh6.ggpht.com/_1TPOP7DzY1E/S3v1IbxlbCI/AAAAAAAADD4/q1Y9kP8wJ0g/s800/Capture2.png

=======

РЕДАКТИРОВАТЬ

обновлен тест:

  Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    Dim g As Graphics = e.Graphics

    Dim oldmode As SmoothingMode = g.SmoothingMode

    Using pen As New Pen(Color.Blue, 3)
      g.SmoothingMode = SmoothingMode.AntiAlias
      g.DrawLine(pen, X1, Y1, X2, Y2)
      g.SmoothingMode = SmoothingMode.None
      g.DrawLine(pen, X1 + 50, Y1, X2 + 50, Y2)
    End Using

    g.SmoothingMode = oldmode
    g.Flush()

    'MyBase.OnPaint(e)'
  End Sub

Результат (не принимать во внимание метки и кружки):

альтернативный текст http://lh3.ggpht.com/_1TPOP7DzY1E/S447qYvTqzI/AAAAAAAADE8/eP3kCLqQJbk/s800/Capture2.png

видимо, режим сглаживания не принимается во внимание ...

Ответы [ 4 ]

3 голосов
/ 26 февраля 2010

Режим SmoothingMode определенно должен влиять на ваш вывод

Вот некоторые настройки, которые я недавно использовал для изменения размера изображения с минимальной потерей качества:

graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

InterpolationMode, вероятно, не относится к вашему примеру, но может быть PixelOffsetMode. Позвольте мне раскрутить приложение для быстрого тестирования.

Обновление: Вот приложение для быстрого тестирования, SmoothingMode определенно влияет на линии, которые я рисую.

private void Form1_Load(object sender, EventArgs e)
{
    foreach (var value in Enum.GetValues(typeof(SmoothingMode)))
    {
        _ComboBoxSmoothingMode.Items.Add(value);
    }

    foreach (var value in Enum.GetValues(typeof(PixelOffsetMode)))
    {
        _ComboBoxPixelOffsetMode.Items.Add(value);
    }

    _ComboBoxPixelOffsetMode.SelectedIndex = 0;
    _ComboBoxSmoothingMode.SelectedIndex = 0;
}

private void _ButtonDraw_Click(object sender, EventArgs e)
{
    using (Graphics g = _LabelDrawing.CreateGraphics())
    {
        g.Clear(Color.White);

        if (_ComboBoxPixelOffsetMode.SelectedItem != null && (PixelOffsetMode)_ComboBoxPixelOffsetMode.SelectedItem != PixelOffsetMode.Invalid)
        {
            g.PixelOffsetMode = (PixelOffsetMode)_ComboBoxPixelOffsetMode.SelectedItem;
        }

        if (_ComboBoxSmoothingMode.SelectedItem != null && (SmoothingMode)_ComboBoxSmoothingMode.SelectedItem != SmoothingMode.Invalid)
        {
            g.SmoothingMode = (SmoothingMode)_ComboBoxSmoothingMode.SelectedItem;
        }

        using (Pen pen = new Pen(Color.Blue, 3))
        {
            g.DrawLines(pen, new[] { new Point(0, 0), new Point(25, 50), new Point(_LabelDrawing.Width - 25, _LabelDrawing.Height - 50), new Point(_LabelDrawing.Width, _LabelDrawing.Height), });
        }
    }
}

SmoothingMode: AntiAlias None

SmoothingMode.AntiAlias ​​http://www.ccswe.com/temp/SmoothingMode_AntiAlias.png SmoothingMode.None http://www.ccswe.com/temp/SmoothingMode_None.png

Обновление: Как указал Морбо, если объект Graphics, представленный вам в PaintEventArgs, не является тем же объектом Graphics, который в конечном итоге будет использоваться для отображения, а затем может изменить сглаживание не имеет никакого эффекта. Хотя я не ожидал бы такой резкой разницы, если бы это был Graphics объект из памяти Image или что-то еще.

Хотел бы я предложить больше. Может быть, если бы я лучше понял, что LineShape давал вам и вашим аргументам в пользу его использования вместо одного из методов Graphics.DrawLine ().

Причина, по которой я подвергаю сомнению использование вами LineShape, заключается в том, что вы переопределяете его OnPaint и рисуете свою собственную линию. Похоже, вы могли бы упростить ваше приложение и отказаться от LineShape, но, возможно, я что-то упустил.


Обновление: Хорошо, тогда понятно, почему вы тогда используете LineShape. Единственное предложение, которое я могу предложить на данный момент, это переопределить OnPaint на вашей панели или LineShape, попробуйте установить там режим сглаживания перед вызовом базового события. Что-то вроде:

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphichs.SmoothingMode = SmoothingMode.AntiAlias;
    base.OnPaint(e);
}
2 голосов
/ 03 марта 2010

Какие настройки дисплея установлены? Как минимум 24 битный цвет?

Я могу подтвердить, что получение класса из LineShape и переопределение OnPaint, как вы показали, действительно действительно влияет на рендеринг строки, как и ожидалось. Я также могу подтвердить, что и Power Pack 3.0, и версия в Visual Studio 2010 оба специально используют AntiAlias ​​в методе LineShape.DrawInternal.

Я начал с пустого приложения .NET 2.0 для Windows Forms. Я добавил следующий класс, который почти идентичен вашему, и форму, которая содержит только ShapeContainer и диагональную форму MyLine.

Imports Microsoft.VisualBasic.PowerPacks

Public Class MyLine
    Inherits LineShape

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)

        Dim g As Graphics = e.Graphics

        'g.SmoothingMode = SmoothingMode.AntiAlias '

        Using pen As New Pen(Color.Blue, 3)
            g.DrawLine(pen, X1, Y1, X2, Y2)
        End Using

        'MyBase.OnPaint(e) '

    End Sub

End Class

Если я запускаю проект с приведенным выше кодом как есть, в строке появляется псевдоним (зазубренный). Если я раскомментирую параметр SmoothingMode, линия станет сглаженной (сглаженной).

Так что это определенно должно работать. Я знаю, это кажется глупым вопросом, но вы проверили, чтобы убедиться, что ваш код попал в отладчик? Вы пытались вызвать Graphics.Flush () сразу после вашей DrawLine?

Кроме того, какую версию PowerPack вы используете? Как я уже сказал, в Reflector я могу ясно видеть, что LineShape.DrawInternal специально устанавливает SmoothingMode в AntiAlias ​​в блоке try / finally. Восстанавливает старый режим сглаживания перед возвратом. Но в вашем примере вы никогда не должны нажимать на это, потому что вы не вызываете базовый метод.

2 голосов
/ 26 февраля 2010

Из того, что я могу сказать в Reflector, компонент PowerPack LineShape рисует, используя объект Graphics из исходного события Paint контейнера. Изменение свойств указанного вами объекта Graphics может повлиять на все остальное в контейнере, который рисует после вашей фигуры.

Какие ваши объекты LineShape содержатся в вашем образце? (Если это элемент управления, нарисованный пользователем, создаете ли вы растровое изображение в какой-то момент? Как?) Если они находятся внутри пользовательского элемента управления с низкой глубиной цвета, это может быть источником проблемы. LineShape рисует сглаживание по умолчанию на моей машине.

0 голосов
/ 03 марта 2010

Вопрос был в моем режиме разработки: через подключение к удаленному рабочему столу на виртуальном ПК.

В моем случае RDC не учитывает свойство графики AntiAlias. Были ли у вас проблемы с разработкой на Виртуальном ПК?

Спасибо всем за участие, извините, это не было действительно проблемой .NET.

...