В моем .NET-приложении два цвета определяются пользователем.Я хотел бы каким-то образом получить цвет между этими двумя цветами.Это цвет в середине градиента.Есть ли способ добиться этого?
Получите смешение двух цветов в .NET
4 ответов
Итак, самый простой способ - это взять среднее значение каждого из красного, зеленого, синего и альфа-значений:
Color c1 = ...;
Color c2 = ...;
Color midpoint = Color.FromArgb((c1.A + c2.A) / 2,
(c1.R + c2.R) / 2,
(c1.G + c2.G) / 2,
(c1.B + c2.B) / 2);
Несмотря на то, что свойства A, R, G и B являются байтами, они будут преобразованы в целые числа перед добавлением, поэтому проблем с переполнением не возникнет.Результат деления по-прежнему будет в диапазоне [0, 255], а FromArgb
принимает Int32
значение, но отбрасывает все, кроме младших 8 бит - именно то, что мы хотим.
Альтернативой может быть использование другой цветовой модели (например, HSV), но это будет несколько сложнее.Для градиентов это должно быть нормально.
Под цветом вы подразумеваете экземпляр структуры Color
?
Если да, просто возьмите по очереди каждый из компонентов R
, G
и B
и вычислите среднее значение для каждого.Объедините результат, чтобы получить смешанный цвет.
Усреднение - лучший ответ, но одно предостережение:
Проблема средних значений цвета заключается в том, что, если они не относятся к одной тематической группе (высокий R, низкий G, низкий B), вы в конечном итоге будете иметь тенденцию к серому.
Обратите внимание: чем больше вы используете функцию усреднения, тем более серым будет результат.
Вам не нужно делать все десятичные дроби - просто используйте \ вместо /, чтобы использовать целочисленное деление.У вас отключена опция Option Strict?В противном случае я бы не ожидал, что он будет компилироваться.
– Jon Skeet13 ноября 2009, 21:06Отлично сработало.Мне также приходилось округлять до ближайшего целого числа, иначе в некоторых случаях он вылетал.Вот код VB, который я использовал:
MyColor = Color.FromArgb (_ Decimal.Round (((CInt (Color1.A) + CInt (Color2.A)) / 2)), _ Decimal.Round (((CInt (Color1.R) + CInt (Color2.R)) / 2)), _ Decimal.Round (((CInt (Color1.G) + CInt (Color2.G)) / 2)), _ Decimal.Round (((CInt (Color1.B) + CInt (Color2.B)) / 2)) _ )
– Jeff Stock13 ноября 2009, 20:59