Джоэл дал отличный ответ о том, как выровнять градиентные кисти. Я хотел бы коснуться сложности автоматического создания новой градиентной кисти, которая гарантированно будет видна на фоне старой.
В WPF цвета моделируются трехмерно, поскольку для определения цвета WPF требуются три числа (например, R / G / B или H / S / B), не считая альфа-компонента. Заданную градиентную заливку можно рассматривать как путь, который проходит от одной цветовой точки к другой в трехмерном цветовом пространстве. Для создания обратного градиента, который контрастирует в каждой точке, требуется создание дополнительного пути, который ни в коем случае не «слишком близок» к исходному пути. «Слишком близкими» для этой цели являются любые два цвета, которые трудно различить человеческому глазу. Это на самом деле субъективно. Около 4% людей, страдающих дальтонизмом, будут толковать «слишком близко» иначе, чем те, кто этого не делает.
Для лица, не страдающего дальтонизмом, где "слишком близко" определено разумно, всегда будет множество путей, которые удовлетворяют критериям. В этом случае необходимы дополнительные критерии, чтобы решить, какой из них «лучше». Например, должен ли текст как можно более резко контрастировать с фоном, или он должен иметь тот же самый общий оттенок в большинстве случаев?
С другой стороны, консервативное определение «слишком близко», которое учитывает восприятие цвета каждым человеком, такое как «яркость должна отличаться как минимум на 25%», будет страдать от противоположной проблемы: единственный градиент, который удовлетворяет условию при каждая точка должна быть на самом деле прерывистой, то есть она должна сразу перейти от одного цвета к удаленному. Рассмотрим, например, простой градиент от черного к белому. Если задействована только яркость, контрастный фон должен иметь разрыв, в противном случае он будет совпадать в какой-то момент.
По этим причинам создание общего алгоритма для создания контрастного фона - больше искусство, чем наука. Можно использовать несколько алгоритмов, и в разных ситуациях будут подходить разные алгоритмы.
Простой алгоритм, который использовался для этой цели, состоит в том, чтобы сохранить оттенок и насыщенность на одном и том же градиенте и установить яркость на (luminance + 50%) mod 100%
. Однако этот алгоритм не дает очень эстетичных результатов в большинстве случаев и никогда не имеет вариации яркости более 50%. Модификация этого алгоритма заключается в инвертировании или сдвиге значений оттенков и насыщенности.
Еще более простой алгоритм для вычисления контрастной яркости - luminance>50% ? 0% : 100%
. Это также может иметь эстетические проблемы.
Суть в том, что нет единственного правильного ответа на инвертирование ваших градиентных цветов. Но если у вас есть алгоритм для этого, то с помощью техники маски непрозрачности Джоэля вместе с привязкой и IValueConverter, который реализует ваш алгоритм, все получится.