изменение значений цвета RGB для представления значения - PullRequest
1 голос
/ 15 сентября 2009

Я пытаюсь изменить цвет на холсте в Java, чтобы представить, насколько сильные или слабые значения, представленные цветом, относительно друг друга.

Цвета RGB должны быть одного цвета, только разные оттенки, от белого до серого до черного и каждый промежуточный оттенок серого. Как я могу изменить значения rgb, учитывая, что значения, которые я представляю, сильно варьируются от -9999999 до положительных 9999999.

Ответы [ 4 ]

4 голосов
/ 15 сентября 2009

Я думаю, вам стоит взглянуть на HSL / HSV вместо RGB.

Хотя RGB по своей природе элементарен в том смысле, что он выражает цвета в терминах основных цветов, он не позволяет вносить «понятные» изменения в значения R, G или B для получения «похожих» цветов. С моделью HSL / HSV вы сможете вносить изменения в яркость / яркость / значение (L / V), чтобы получить цвета с различным количеством серого, или вносить изменения в оттенок (H) для получения похожих цветов по всему спектру. , Вы можете начать с полной яркости (белый) и создавать более темные оттенки серого, уменьшив значение L / V и в конечном итоге достигнув цвета без яркости (черный).

Очень мягкое введение в теорию цвета, для разработчиков доступно здесь .

Что касается вашего вопроса, вы должны выразить свои цвета в терминах HSL, с увеличением значения насыщенности, чтобы иметь диапазон цветов, начиная от белого до черного. Конечно, если вам нужны серые тона между белым и черным без какого-либо другого цвета, вам следует сохранить минимальный оттенок.

Ниже приведен короткий пример получения диапазона цветов. Для краткости я заполнил цвета в массив, но это не обязательно, так как вы можете использовать правильный цвет (помимо учета требований к памяти).

private Color[] produceColorRange(int steps)
{
    float value = 1.0f; //Starting with full brightness
    Color[] colors = new Color[steps];
    for(int ctr = 0; ctr < steps; ctr++)
    {
        value = value - (1.0f/steps); //tend to darkness
        int rgb = Color.HSBtoRGB(0.7f, 0.0f, value); //create a darker color
                                             //Hue is Blue, not noticeable
                                             //because Saturation is 0
        Color color = new Color(rgb);
        colors[ctr] = color;
    }
    return colors;
}

Если вы используете описанный выше метод и нарисуете JFrame, вы сможете получить результат, аналогичный приведенному ниже (за исключением того, что я изменил оттенок и насыщенность, чтобы получить свой диапазон цветов).

Color Range screenshot

Обратите внимание: если вы хотите получить более простой способ получения цветового диапазона, инициализируйте объект Color с помощью Color.WHITE и вызовите color.darker (). Конечно, вы не сможете контролировать приращение.

3 голосов
/ 15 сентября 2009

Да, масштабируйте свои значения в соответствии с вашим доменом. Это зависит от того, как хранятся ваши значения RGB. Обычно 8 бит используются для каждого. Поскольку серый имеет R = G = B, необходимо масштабировать значения в диапазоне (-9999999,9999999) до (0, 255).

Рассмотрим х в первом интервале. Поскольку первый диапазон охватывает также отрицательные числа, сначала сделайте сдвиг.

х = х + 9999999

Теперь x находится в интервале (0, 19999998). И следующий шаг - уменьшить его до (0, 255). Поскольку значения цвета в этом интервале растут линейно, все, что вам нужно сделать, это:

х = х * 255/19999998

Теперь x находится в интервале (0, 255) так, как вы хотите.

Как правило, если ваши начальные значения находятся в интервале (a, b) и хотите преобразовать его в (0, c), примените следующую формулу: (Обратите внимание, что a может быть отрицательным)

x = (x - a) * c / (b - a)

Итак, если значения R, G, B имеют длину 16 бит, c будет 2 ** 16 = 65536 и формула:

x = (x + 9999999) * 65536/19999998

Надеюсь, это поможет.

0 голосов
/ 15 сентября 2009

Класс HSL Color реализует формулы, представленные в ссылке на Википедию на HSL / HSV, предоставленной выше.

0 голосов
/ 15 сентября 2009

Я не совсем уверен, что понимаю ваш вопрос, но, если я понимаю:

Почему бы просто не масштабировать значения RGB до значений в вашем диапазоне (от -9999999 до положительного 9999999)? Кроме того, установите R, G и B на одно и то же значение, чтобы использовать оттенки серого для представления значения.

Как это:

private final int MIN = -9999999;
private final int MAX = 9999999;

public Color getScaledColor(int val) {
    int gray = (int) Math.round((double) (val - MIN) / (double) (MAX - MIN)
            * 255.0);
    Color color = new Color(gray, gray, gray);

    return color;
}

Обратите внимание, что это решение не даст уникальные цвета для всех значений в указанном диапазоне. Но также имейте в виду, что человеческий глаз может различать только столько оттенков (а 2 * 9999999 + 1, вероятно, больше, чем количество оттенков, которое может различать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...