Динамическое создание цветов с разной яркостью - PullRequest
9 голосов
/ 01 марта 2010

У меня есть цвет, который я знаю только во время выполнения. Используя этот цвет, я хочу создать два новых цвета, один очень яркий и один не яркий вариант цвета.

Итак, чтобы уточнить, скажем, у меня есть красный цвет; Я хочу создать шестнадцатеричное значение для цвета «Светло-красный» и цвета «Темно-красный».

Как бы я поступил так? Мой код написан на Java с использованием GWT.

Ответы [ 5 ]

18 голосов
/ 01 марта 2010

Преобразуйте цвета в пространство HSB / HSV (Hue-Saturation-Brightness / Value) и отрегулируйте Яркость вверх для более светлых и вниз для темных. Затем снова вернитесь. В 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 предназначено для такого рода операций.

Суть в том, что вам нужно всего лишь изменить значение яркости, чтобы получить желаемый эффект осветления / затемнения. Вам придется поэкспериментировать с тем, насколько вы светлее / темнеете.

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

См .: http://en.wikipedia.org/wiki/HSL_and_HSV и http://www.acasystems.com/en/color-picker/faq-hsb-hsv-color.htm

Редактировать: Согласно комментариям, класс java.awt.Color нельзя использовать в GWT. Поскольку единственной частью класса Color, которую мы используем, являются преобразования HSV в RGB и преобразования RGB в HSV, поскольку вы используете GWT, вместо этого вы можете использовать Google для реализации этих алгоритмов: Преобразование Google HSV RGB алгоритм . Например:

5 голосов
/ 01 марта 2010

Для этого есть как минимум два достойных решения: одно лучше (в любом случае, более «правильное»), чем другое. Это зависит от того, для чего вы хотите использовать цвет или от короткого и простого кода.

Использование цветового пространства, моделирующего яркость

Проблема в том, что ваши цвета, вероятно, определены как 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 - это будет связано с тем, что в эти дни у меня недостаточно знаний о классах и методах, - но этого должно быть достаточно, чтобы помочь вам в этом. Надеюсь, это поможет!

2 голосов
/ 07 июня 2011

Поскольку вы используете GWT, вам следует выполнять расчеты цвета с использованием HSL, а не RGB, поскольку он более интуитивен и может применяться в качестве цвета стиля непосредственно к вашим компонентам.

Ваш начальный цвет "красный" определяется как "цвет: hsl (0,100%, 50%)", см. http://www.w3.org/TR/css3-color/#hsl-color для получения дополнительной информации о цветах стиля.

Чтобы получить светло-красный, все, что вам нужно, это увеличить компонент L (яркость), поэтому светло-красный будет "color: hsl (0,100%, 75%)". Чтобы получить темно-красный, уменьшите компонент L, «color: hsl (0,100%, 25%)»

Чтобы применить цвет, просто установите цвет с помощью

      component.getElement().getStyle().setColor("hsl(0,100%, 25%)")
2 голосов
/ 01 марта 2010

Я не знаю, в каком формате у вас есть цвет (я пытался проверить, использует ли GWT цвета ... но они сильно зависят от CSS, поэтому у них нет особых свойств).

В любом случае, если у вас есть одно значение для каждого компонента (красный, зеленый, синий) и каждое значение находится в диапазоне от 0 до 255 - это стандартное значение - примените этот алгоритм:

  • для каждого компонента
    • умножьте исходное значение на коэффициент (скажем, 1,1, на 10% ярче)
    • преобразовать значение типа float / double в int
    • если это значение превышает 255, уменьшите его до 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"
0 голосов
/ 01 февраля 2017

Просто добавьте следующую функцию в ваш код. Он вернет значение хэша для более светлого и темного цвета в соответствии с вашим требованием.

передать два аргумента. (1) значение хеша выбранного вами цвета. (2) насколько светлее или темнее вы хотите (например, если вы хотите более светлый оттенок на 10%, передайте 0,1 в качестве второго аргумента, а если вы хотите на 40% темнее, то передайте -0,4 (отрицательное значение для темнее) в качестве второго аргумента)

Так что, если вы хотите найти на 20% более светлый оттенок красного, звоните, как показано ниже
String lightred=convert("ff0000",0.2);

public static String convert(String hex, double num) {
    String rgb = "#",temp;
    int i;
    double c,cd;
    for (i = 0; i < 3; i++) {
        c = Integer.parseInt(hex.substring(i * 2,(i*2)+2), 16);
        c = Math.min(Math.max(0, c+(255*num)), 255);
        cd=c-(int)c;
        if(cd>0){c=(int)c+1;}
        temp = Integer.toHexString((int)c);
        if(temp.length()<2)
        {
            temp=temp+temp;
        }
        rgb += temp;
    }
    return rgb;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...