Функция генерации цвета

Рассмотрим следующий сценарий: функция, которая может генерировать цвета кода от белого до красного, от белого до синего, от белого до розового, от белого до оранжевого и т. д.

Код цвета представлен в формате RGB со значениями от 0 до 255.

Есть идеи? Можете ли вы дать мне псевдокод или ссылку на такой алгоритм?


person Duncan Benoit    schedule 17.05.2009    source источник
comment
Какой язык? Просто погуглите RGB!   -  person Dario    schedule 17.05.2009
comment
Чтобы найти значение RGB для оранжевого, розового и т. д., введите в Google «цветовой круг RGB».   -  person ChrisW    schedule 17.05.2009
comment
Эти переходы одного цвета в другой часто называют градиентами.   -  person M. Dudley    schedule 23.06.2009


Ответы (5)


Похоже, вам нужна линейная интерполяция — в вашем случае интерполяция от белого до указанного цвета . Например, в С#:

public IEnumerable<Color> Interpolate(Color from, Color to, int steps)
{
    int range = steps-1; // Makes things a bit easier
    for (int i=0; i < steps; i++)
    {
        // i is the proportion of the "to" colour to use.
        // j is the proportion of the "from" colour to use.

        int j = range - i;
        int r = ((from.R * j) + (to.R * i)) / range;
        int g = ((from.G * j) + (to.G * i)) / range;
        int b = ((from.B * j) + (to.B * i)) / range;
        yield return new Color(r, g, b);
    }
}

Конечно, кроме линейной интерполяции, есть и другие способы, но это, скорее всего, самый простой. Обратите внимание, что это становится сложным, если у вас много шагов или большие значения, потому что вам нужно учитывать возможность переполнения. В этом случае вы должны быть в порядке - вам вряд ли понадобится больше 256 шагов, а максимальное значение равно 255, поэтому вы не приблизитесь к пределу ints.

РЕДАКТИРОВАТЬ: Как отмечалось в комментариях, RGB может быть не лучшим доменом для использования линейной интерполяции. Лучше всего преобразовать значения RGB из/в в HSL или HSV и выполнить интерполяцию на те. Это может быть легко или сложно в зависимости от вашей платформы. Ссылка на Википедию в предыдущем предложении дает формулы для соответствующих расчетов, если они вам не предоставлены.

person Jon Skeet    schedule 17.05.2009
comment
На самом деле вы можете не захотеть делать линейную интерполяцию в RGB. Вы можете получить лучшие результаты, выполняя интерполяцию в HSL или HSV, в зависимости от эффекта, который вы ищете. Рассмотрим случай интерполяции между чистым красным и чистым зеленым цветом. В RGB это от (255, 0, 0) до (0, 255, 0). Линейная интерполяция дает середину (127, 127, 0) темно-желтого цвета. Однако вы можете ожидать ярко-желтого цвета. В HSV чистый красный — это (0°, 255, 255), а чистый зеленый — (120°, 255, 255), поэтому при интерполяции изменится только оттенок, а средняя точка будет чисто желтой. - person Laurence Gonsalves; 17.05.2009
comment
Все верно, но несколько сложнее, когда цвета предоставляются как RGB (как описано в вопросе). Конечно, все еще выполнимо путем преобразования исходных значений RGB в HSL/HSV, но это может быть немного продвинутым для OP. Я отредактирую ответ, чтобы упомянуть об этом как о возможности. - person Jon Skeet; 17.05.2009

Алгоритм:

  1. Найдите значение RGB для белого
  2. Найдите значение RGB для другого цвета (например, вы упомянули красный, синий, розовый, оранжевый)
  3. Вычислить значения RGB, чьи компоненты RGB арифметически находятся между компонентами RGB двух крайних значений.

Например, если один экстремум равен (0,0,0), а другой экстремум равен (0,255,255), то значение на полпути между этими двумя цветами равно (0,128,128)... и значение, которое составляет четверть пути между этими двумя цветами. два значения (0,64,64).

person ChrisW    schedule 17.05.2009
comment
К сожалению, выполнение этого в RGB обычно не дает наилучших визуальных результатов, особенно если два цвета имеют разные оттенки (хотя может работать для белого в цвет или черного в цвет). Идеальной процедурой было бы: найти RGB для исходного и целевого цветов; преобразовать в ЗОЖ; интерполировать в HLS; конвертировать интерполированные цвета обратно в RGB, один за другим. Кодировать это скучно, но после того, как это сделано, он работает быстро даже для большого количества шагов. - person heltonbiker; 19.07.2011

Интерполяция цветов через известные определенные точки часто используется для построения цветовых схем для графических данных. Альтернативой явной формуле интерполяции является выбор цветовой схемы, за представлением которой стоит определенный дизайн. Хорошим источником такой схемы является ColorBrewer.

Даже если вам нужно выполнить интерполяцию, использование хорошо продуманной цветовой схемы может дать гораздо более полезные результаты.

person RBerteig    schedule 18.05.2009

Начните с двух цветов, между которыми вы хотите создать градиент, и разделите их на части R, G и B.

Решите, сколько «шагов» вы хотите пройти.

Разделите разницу между частями R, G и B на количество шагов. Теперь у вас есть «разница в шагах» для каждого цвета.

Прокручивайте каждый шаг и добавляйте разницу шага к значению цвета один раз для каждой итерации. Округлите до целых последнее действие, которое вы делаете.

person Tomas Aschan    schedule 17.05.2009

На какие цвета вы хотите перейти? от белого к красному будет просто случай, когда вы начнете с 255 255 255 и уменьшите вторые два, пока не получите 255 0 0. синий будет сохранять последнее значение и уменьшать его до 0 0 255 и т. д.

person Simonw    schedule 17.05.2009
comment
это верно...но как насчет оранжевого, розового...и т.д...это моя проблема - person Duncan Benoit; 17.05.2009