У меня есть цвет, который я только знаю во времени выполнения. Используя этот цвет я хочу создать два новых цвета, один очень яркий и один ни один яркая версия цвета.
Таким образом для разъяснения скажите, что у меня есть красный цвет; я хочу создать шестнадцатеричное значение для "светло-красного" цвета и "темно-красного" цвета.
Как я пошел бы о выполнении этого? Мой код написан в Java с помощью GWT.
I не знаю, в каком формате у вас есть цвет (я пытался узнать, использует ли GWT цвета ... но они сильно зависят от CSS, поэтому у них нет определенных свойств).
В любом случае, если у вас есть одно значение для каждого компонента (красный, зеленый, синий), и каждое значение находится в диапазоне от 0 до 255 - это стандартно - тогда примените следующий алгоритм:
Тогда у вас будет новый цвет (новый трехкомпонентный кортеж).
Цвета в шестнадцатеричном формате
Если у вас есть цвета в веб-формате:
RRGGBB
RR - two hexa digits for red
GG - two hexa digits for green
BB - two hexa digits for blue
, вам нужно преобразовать их в int и обратно в шестнадцатеричные:
Шестнадцатеричная строка в int
Integer.parseInt("AB", 16"); // returns 171
int в шестнадцатеричную строку
Integer.toHexaString(171); // returns "AB"
Для этого есть как минимум два достойных решения, одно лучше (во всяком случае, более «правильное»), чем другое. Это зависит от того, для чего вы хотите использовать цвет, или от компромисса с коротким и простым кодом.
Проблема в том, что ваши цвета, вероятно, указаны как RGB (т. Е. Количество красного, зеленого и синего, отражающих ваш монитор.) Лучший способ изменить яркость цвета - указать цвета в другом цветовом пространстве, где яркость является одним из компонентов, например HSB - оттенок («цвет»), насыщенность («количество» цвета) и яркость (сам -пояснительно, я думаю!)
Эта статья в Википедии о цветовых моделях HSL и HSV объясняет гораздо больше, чем вы, вероятно, хотите знать :)
Взгляните на эту демонстрацию HSB .
Дело в том, что если ваши цвета указаны в другом пространстве, где одним из компонентов является яркость, изменить яркость легко, потому что вы можете увеличивать или уменьшать этот компонент по своему усмотрению, точно так же, как вы можете увеличивать или уменьшать количество синего цвета в цвете RGB. Я думаю, что в Java есть некоторые встроенные функции преобразования цвета - некоторые поисковые запросы обнаружили эту страницу с удобным примером Color.RGBtoHSB ()
и вернулись назад с Color.HSBtoRGB
].
Это более хакерский, но эффективный в большинстве ситуаций, и большая часть написанного мной кода требует получения двух версий цвета (например, градиента) для чего-то неважного, например Фон пользовательского интерфейса использует такой метод. Логика состоит в том, что цвет будет ярче по мере приближения к белому (RGB 255,255,255) и темнее по мере приближения к черному (RGB 0,0,0). Чтобы сделать что-то ярче, смешайте с белым, скажем, 25%. Вы можете смешивать два цвета, беря пропорцию одного цвета и обратную пропорцию другого для каждого канала / компонента.
Нижеследующее не проверено и представляет собой преобразование кода Delphi, который я использовал для того же самого (код взят из памяти, и, кроме того, я не использовал Java в течение многих лет и не помню синтаксис и классы хороши, поэтому я не ожидаю, что это будет скомпилировано, но вы должны иметь представление):
Color Blend(Color clOne, Color clTwo, float fAmount) {
float fInverse = 1.0 - fAmount;
// I had to look up getting colour components in java. Google is good :)
float afOne[] = new float[3];
clOne.getColorComponents(afOne);
float afTwo[] = new float[3];
clTwo.getColorComponents(afTwo);
float afResult[] = new float[3];
afResult[0] = afOne[0] * fAmount + afTwo[0] * fInverse;
afResult[1] = afOne[1] * fAmount + afTwo[1] * fInverse;
afResult[2] = afOne[2] * fAmount + afTwo[2] * fInverse;
return new Color (afResult[0], afResult[1], afResult[2]);
}
И вы, вероятно, использовали бы это как:
Color clBrighter = Blend(Color.red, Color.white, 0.25);
Возможно, вы захотите добавить код безопасности, например как обеспечение ограничения между 0..255 для каждого компонента или проверка того, что dAmount
действительно находится в диапазоне 0..1.
Документация Java Color выглядит так, как будто класс Color
имеет всевозможные полезные методы. (Изменить: я только что заметил, что вы сказали, что используете gwt
, а не awt
- я не использовал его и понятия не имею, какие классы из стандартной Java включены. Это должно указать вам в любом случае в правильном направлении.) Возможно, это не самый чистый способ в Java - это будет из-за моего незнания классов и методов в наши дни - но этого должно быть достаточно, чтобы вы хорошо продвинулись по пути. Надеюсь, это поможет!
Преобразуйте цвета в пространство HSB/HSV (Hue-Saturation-Brightness/Value) и отрегулируйте Brightness вверх для более светлых и вниз для более темных. Затем снова преобразуйте обратно. В Java:
import java.awt.Color;
float hsbVals[] = Color.RGBtoHSB( originalColour.getRed(),
originalColour.getGreen(),
originalColour.getBlue(), null );
Color highlight = Color.getHSBColor( hsbVals[0], hsbVals[1], 0.5f * ( 1f + hsbVals[2] ));
Color shadow = Color.getHSBColor( hsbVals[0], hsbVals[1], 0.5f * hsbVals[2] );
Пространство HSB предназначено для такого рода операций.
Суть в том, что для получения нужного эффекта осветления/затемнения вам достаточно изменить член Brightness. Вам придется экспериментировать с тем, насколько сильно вы осветляете/затемняете.
Приведенный выше код смещает Яркость на половину к белому для блика и на половину к черному для тени. (Я использовал этот код для создания эффекта выделенной границы на кнопке.)
См: http://en.wikipedia.org/wiki/HSL_and_HSV и http://www.acasystems.com/en/color-picker/faq-hsb-hsv-color.htm
Edit: Согласно комментариям, класс java.awt.Color
не может быть использован в GWT. Поскольку единственной частью класса Color
, которую мы используем, являются преобразования HSV в RGB и RGB в HSV, так как вы используете GWT, вы можете вместо этого поискать реализацию этих алгоритмов в Google: Google HSV RGB алгоритм преобразования. Например: