LinearGradientBrush Артефакт Обходной путь? - PullRequest
9 голосов
/ 21 сентября 2008

Кажется, что LinearGradientBrush в .net (или даже в GDI + в целом?) Имеет серьезную ошибку: иногда он вводит артефакты. (См. здесь или здесь - по сути, первая линия линейного градиента рисуется в конечном цвете, т.е. градиент от белого к черному начнется с черной линии, а затем с правильный градиент от белого к черному)

Интересно, нашел ли кто-нибудь рабочий способ для этого? Это действительно раздражающая ошибка: - (

Вот изображение Артефактов, обратите внимание, что есть 2 LinearGradientBrushes:

альтернативный текст http://img142.imageshack.us/img142/7711/gradientartifactmm6.jpg

Ответы [ 4 ]

9 голосов
/ 21 сентября 2008

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

5 голосов
/ 21 сентября 2008

Вы можете использовать хороший метод Inflate (int i) для прямоугольника, чтобы получить большую версию.

3 голосов
/ 05 декабря 2012

Я бы изобразил ответ Фила выше (это действительно комментарий, но у меня нет такой привилегии). Поведение, которое я вижу, противоречит документации , в которой говорится:

Начальная линия перпендикулярна линии ориентации и проходит через один из углов прямоугольника. Все точки на стартовой линии имеют начальный цвет. Затем конечная линия перпендикулярна линии ориентации и проходит через один из углов прямоугольника. Все точки на конечной линии имеют конечный цвет.

А именно, в некоторых случаях вы получаете обтекание в один пиксель. Насколько я могу судить (экспериментально), проблема возникает только тогда, когда ширина или высота прямоугольника нечетна. Поэтому, чтобы обойти эту ошибку, я считаю, что достаточно увеличить прямоугольник LinearGradientBrush на 1 пиксель, если и только если размер (до расширения) является нечетным числом. Другими словами, всегда округляйте прямоугольник кисти до следующего четного числа пикселей как по ширине, так и по высоте.

Итак, чтобы заполнить прямоугольник r Я использую что-то вроде:

Rectangle gradientRect = r;
if (r.Width % 2 == 1)
{
    gradientRect.Width += 1;
}
if (r.Height % 2 == 1)
{
    gradientRect.Height += 1;
}
var lgb = new LinearGradientBrush(gradientRect, startCol, endCol, angle);
graphics.FillRectangle(lgb, r);

Безумие, но правда.

1 голос
/ 23 октября 2008

По крайней мере, с WPF вы можете попытаться использовать GradientStop s для получения 100% правильных цветов по краям, даже при перекраске.

...