Генерация серии цветов между двумя цветами

15

Учитывая начальный цвет и конечный цвет, возможно ли алгоритмически генерировать диапазон цветов между ними? Например, учитывая светлые и темные оттенки синего / серого в начале и конце изображения ниже, как я могу создать промежуточные оттенки?

введите описание изображения здесь

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

Бен Паккард
источник
2
Взгляните на это: graphicdesign.stackexchange.com/questions/75417/… Может быть тогда быть дубликатом?
Рафаэль
Еще одна хорошая статья на эту тему: vis4.net/blog/posts/avoid-equidistant-hsv-colors
колючка
Это очень близко к тому, чтобы быть дубликатом этого вопроса переполнения стека
Дауд говорит восстановить Монику

Ответы:

13

Это называется интерполяцией цвета . Это то, что градиенты делают под капотом. Вы можете сделать это, используя различные средства и методы, и то, как именно интерполируются результаты, зависит от метода.

Я обычно делаю это для веб-проектов, использующих JavaScript, чтобы я мог динамически менять цвета, например, в этом музыкальном визуализаторе . Реализация JavaScript, которая имеет очень простой метод линейной интерполяции с использованием RGB, взятый из примера выше, выглядит следующим образом:

Живая демо

// Returns a single rgb color interpolation between given rgb color
// based on the factor given; via https://codepen.io/njmcode/pen/axoyD?editors=0010
function interpolateColor(color1, color2, factor) {
    if (arguments.length < 3) { 
        factor = 0.5; 
    }
    var result = color1.slice();
    for (var i = 0; i < 3; i++) {
        result[i] = Math.round(result[i] + factor * (color2[i] - color1[i]));
    }
    return result;
};
// My function to interpolate between two colors completely, returning an array
function interpolateColors(color1, color2, steps) {
    var stepFactor = 1 / (steps - 1),
        interpolatedColorArray = [];

    color1 = color1.match(/\d+/g).map(Number);
    color2 = color2.match(/\d+/g).map(Number);

    for(var i = 0; i < steps; i++) {
        interpolatedColorArray.push(interpolateColor(color1, color2, stepFactor * i));
    }

    return interpolatedColorArray;
}

Который используется как и так и возвращает массив интерполированных цветов:

var colorArray = interpolateColors("rgb(94, 79, 162)", "rgb(247, 148, 89)", 5);

Вы также можете найти расширения PhotoShop (и, вероятно, других программ) для выполнения цветовой интерполяции. Тем не менее, вы можете проверить, чтобы убедиться, что метод интерполяции является тем же, который вы хотите, так как вы можете использовать любую функцию для интерполяции на основе.

Зак Соусье
источник
2
Зак ... ты такой придурок ... этот музыкальный визуализатор чертовски крут!
Рафаэль
@Rafael Я сделал пару других, которые тебе могут понравиться :)
Зак
Благодарю. Color Interpolationбыло то, что мне было нужно. Я нашел несколько реализаций Swift здесь - stackoverflow.com/questions/22868182/uico...
Бен Packard
2
Ссылка выше не работает, но пост можно найти здесь для будущих читателей: переход UIColor на основе значения прогресса
Зак
23

Посмотрите на этот ответ. Как сделать данный цвет темнее или светлее?

Где вы просто берете разделенные значения каждого компонента RGB и делите значения.

Но у нас есть одна проблема, не существует только одного способа сделать цветовой переход.

введите описание изображения здесь

Первый подход даст вам кратчайший маршрут (1), но, вероятно, этот маршрут не то, что вам нужно.

Это также зависит от цветовой модели или логики. Например, в цветовой модели Lab * красный и зеленый являются дополнительными цветами, поэтому короткий маршрут на этой модели будет проходить через нейтрально-серый (3).

Если вам нужны только оттенки цвета, другой ответ - подходящий.

Рафаэль
источник
5
Мне нравится график, показывающий различные методы интерполяции
Зак
Я думаю, это означает, что должен быть способ кодификации стратегии пути.
Бао Тхиен Нго
10

Используйте смесь в Illustrator в RGB или CMYK:

  • создайте 2 фигуры, каждая из которых имеет начальный и конечный цвета (один серый и один черный в этом примере, но выберите все, что вам нужно)
  • перейдите к Object → Blend → Blend Optionsи введите, сколько Specified stepsвам нужно между (20 в моем примере ниже)
  • выберите два ваших объекта и выберите Object → Blend → Make. Это создаст смесь, которую вы можете затем преобразовать в отдельные объекты Object → Expand. Затем вы можете увидеть каждый промежуточный объект с его собственным цветовым кодом.

смешивание

Lucian
источник
5

Это дополнение к другим ответам.

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

Человеческое восприятие интенсивности света в соответствии со степенным законом, поэтому с

linear = sRGB^2.2
sRGB = linear^(1/2.2)

может быть использован для преобразования между ними. При этом используется значение гаммы 2,2, которое является значением для sRGB. Для получения дополнительной информации об этом см. Эту статью в Википедии.

Подробный анализ этой проблемы и примеры неправильных реализаций можно найти здесь . Одним из них является градиент цвета с использованием линейной интерполяции и интерполяции sRGB.

henje
источник
Это один из методов интерполяции значений sRGB, но то, что человек должен делать, зависит от того , какой эффект он хочет
Зак
Это верно, но интерполяция в линейном пространстве - это то, что происходит со светом в реальной жизни. Так что это наиболее естественно для этого.
henje
1
@ZachSaucier количество раз люди сделали интерполяцию или смешивание в SRGB из конкретного намерения это о так крошечным по сравнению с числом раз люди сделали это из - за незнания или лени (либо думают , что они будут делать это в RGB или думая (правильно или нет), что разница не важна).
Хоббс
1

Градиент в Photoshop (или, что эквивалентно, «Blend» в Ai) уже представлен как способ получения линейного цветового перехода между начальным и конечным цветами. Как получить что-то нелинейное (изогнутый путь перехода) без программирования некоторого скриптового кода?

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

Вот довольно сложный поворот. Слой «Только цель» имеет градиент, а слой «Модификатор» производит непрерывный сдвиг цвета с помощью режима наложения «Цвет». Чтобы сделать все изгибы, сам модификатор является градиентом.

Дополнительный поворот создается корректирующим слоем «Кривые», который добавляет контраст. Он имеет ту же маску слоя, что и модификатор, но это не обязательно. Любая маска в порядке, если она сплошная и черная в начале и в конце.

Существуют некоторые непрерывные режимы смешивания и кривые, которые вызывают резкий скачок. Одним из них является "Хюэ". Другая возможность испортить эффект - это «без изменений», видимая постоянная цветовая область, вызванная отсечением до всех нулей или всех 255. Я не проверял и не рассчитывал, насколько это на практике помогает использовать режим RGB с 48 битами / пиксел. Может быть, совсем нет, потому что у нас все еще есть только 24 бит / пиксель на экране.

переход

user287001
источник