Смешивание двух цветов "естественно" в javascript
Проблема: Я хочу смешать два цвета в javascript и получить цвет результата.
На SO есть много похожих вопросов, но я не нахожу ничего, что действительно работает правильно. Я знаю, что смешивание двух разных цветных красок (пигментов) и огней даст очень разные результаты (http://en.wikipedia.org/wiki/Color_mixing).
Вот вопросы и предлагаемые решения, которые я уже видел, и попытались реализовать:
1: Смешивание двух цветовых векторов RGB для получения результата
Итак, смешивая цвета в RGB. Я реализовал его, и в некоторых случаях он работает, в некоторых случаях это не так.
Рабочий пример: Смешивание red
с yellow
→ orange
. Отлично!
http://jsbin.com/afomim/1/edit
Не работает пример: Смешивание blue
с yellow
→ gray
. Не так здорово!:)
http://jsbin.com/afomim/5/edit
Я знаю, что при смешивании RGB blue
с yellow
никогда не будет green
, и я понимаю, почему.
Мы не найдем ответа здесь, отпустите вперед.
2: Добавление цветов (цветов) Вместе как Paint (синий + желтый = зеленый и т.д.)
Попробуйте работать с значениями CMYK, как это предлагается в этом обсуждении. Смешение cyan
с yellow
дает green
:
http://jsbin.com/igaveg/1/edit
, но перемещение blue
с yellow
приводит к black
.
http://jsbin.com/igaveg/2/edit → Не работает!
3: Как смешивать цвета и "естественно" с С#?
Очень похожий вопрос. Самый верный ответ предлагает преобразовать цвета в LAB, и это решение кажется многообещающим.
Поэтому я преобразовал свои цвета в LAB. Алгоритм преобразования правильный, я его протестировал!
http://jsbin.com/oxefox/1/edit
Теперь у меня есть два цвета в LAB, но как их смешивать?
ПРИМЕЧАНИЕ Я знаю, что, вероятно, я не найду алго, который смешивает blue
с yellow
и даст идеальный green
, но я надеюсь, что смогу сгенерировать что-то похожее на зеленый: )
Ответы
Ответ 1
Я посвятил этому вопросу 3-4 дня. Это действительно сложная проблема.
Вот что вы можете сделать, если хотите смешать два цвета "естественно":
-
Смешивание CMYK: это не идеальное решение, но если вам нужно решение сейчас, и вы не хотите тратить месяцы на изучение предмета, экспериментирования и кодирования, вы можете это проверить: https://github.com/AndreasSoiron/Color_mixer
-
Реализация теории Кубельки-Мунк. Я много времени читал об этом и пытался понять это. Это должен быть путь, если вы хотите профессионального решения, но для каждого цвета, который вы хотите смешивать, для этого необходимо 6 параметров (например, отражение, поглощение и т.д.). Недостаточно R, G, B. Внедрение теории не сложно, но получение тех параметров, которые вам нужны по каждому цвету, кажется недостающей частью. Если вы выясните, как это сделать, дайте мне знать:)
-
Экспериментальный: вы можете сделать что-то, что сделали разработчики приложения ipad: Paper. Они вручную выбрали 100 пар популярных цветов и проверены на глаз, как они должны смешиваться. Подробнее об этом .
Я лично буду применять CMYK-микширование на данный момент, а может быть, позже, если у меня будет время, я попытаюсь сделать что-то вроде парней в Fiftythree. Увидим:)
Ответ 2
Цветовая модель RYB может быть подходящим выбором для расчетов смешивания цветов.
Согласно Wikipedia, он в основном используется в искусстве и дизайне, особенно в живописи.
Чтобы смешивать 2 цвета, один преобразует оба цвета из RGB в RYB, смешивает цвета, добавляя каждый
цветной компонент и преобразует полученный цвет от RYB обратно в RGB.
Я пробовал это с помощью Online Color Mixing Tool, и результаты
-
0000FF (синий), смешанный С# FFFF00 ( желтый), дает # 008000 ( темно-зеленый),
-
FF0000 (красный), смешанный С# FFFF00 ( желтый), дает # FFA000 ( оранжевый).
Таким образом, этот метод дает точно результаты, которые вы ожидали.
К сожалению, мне не удалось найти ссылку на формулу "ready-to-use" для преобразования из RGB в RYB и обратно в RGB.
Документ
Paint Inspired Color Mixing and Compositing для визуализации - Gossett and Chen
описывает общую идею цветовой модели RYB в разделе "2 ДОСТИЖЕНИЕ ИНТУИТИВНОГО ЦВЕТОВОГО СМЕШЕНИЯ".
Согласно этой статье, преобразование из RYB в RGB выполняется
Трилинейная интерполяция.
Трудная часть - это преобразование из RGB в RYB, поскольку оно требует инверсии
трилинейная интерполяция.
См. Конверсия между цветовыми пространствами RGB и RYB
для получения дополнительной информации.
Даже если этот ответ не дает полной формулы для расчета, я надеюсь, что он дает некоторые идеи о том, как действовать.
Ответ 3
С цветами CIELAB у вас есть три координаты для каждого из двух цветов в цветовом пространстве LAB. (Кстати, отличная работа по достижению этого). То, что будет работать лучше всего и будет проще всего реализовать для вас, - это найти трехмерную середину воображаемого сегмента линии, соединяющего две точки в пространстве LAB. Вы можете сделать это легко, просто усреднив каждый из компонентов двух цветов: средний L
, средний a
и средний b
. Затем преобразуйте этот цвет обратно в пространство RGB, изменив преобразование (убедитесь, что ваше пространство освещения остается одинаковым в обоих направлениях).
Ваш новый цвет может находиться вне цветового пространства RGB. В этом случае вы можете выбрать клип с ближайшим видимым цветом. (Блюз особенно уязвим для этого).
Ответ 4
Теперь, когда у вас есть два цвета в формате LAB (или L * a * b *), вы можете усреднить их вместе.
L(result) = L(first color) + L(second color) / 2
A(result) = A(first color) + A(second color) / 2
B(result) = B(first color) + B(second color) / 2
Ты уже знал это, верно? потому что это то, что вы делали с вашими исходными цветами RGB, чтобы усреднить их.
Ответ 5
Вот хорошая статья, которую я написал о цветовом смешивании в цветовом пространстве CIE-LCh, который создает смесь, которая сохраняет оттенок, насыщенность и яркость таким образом, который соответствует восприятию вашего глаза.
Улучшенное сочетание цветов
Ответ 6
На самом деле я столкнулся с той же проблемой при попытке комбинировать 2 цвета RGB. Эти две функции работали для меня:
//colorChannelA and colorChannelB are ints ranging from 0 to 255
function colorChannelMixer(colorChannelA, colorChannelB, amountToMix){
var channelA = colorChannelA*amountToMix;
var channelB = colorChannelB*(1-amountToMix);
return parseInt(channelA+channelB);
}
//rgbA and rgbB are arrays, amountToMix ranges from 0.0 to 1.0
//example (red): rgbA = [255,0,0]
function colorMixer(rgbA, rgbB, amountToMix){
var r = colorChannelMixer(rgbA[0],rgbB[0],amountToMix);
var g = colorChannelMixer(rgbA[1],rgbB[1],amountToMix);
var b = colorChannelMixer(rgbA[2],rgbB[2],amountToMix);
return "rgb("+r+","+g+","+b+")";
}
Чтобы смешать красный ([255,0,0]) с синим ([0,0,255]) равномерно, вы можете вызвать
colorMixer([255,0,0], [0,0,255], 0.5);//returns "rgb(127,0,127)" (purple)
Это может помочь, хотя сначала нужно преобразовать каждое значение цвета в массив. Если вы используете Fabric.js для работы с элементами холста, это становится очень простым. Просто позвоните
var rgbA = new fabric.Color(yourColor);
var rgbB = new fabric.Color(yourSecondColor);
затем вызовите
colorMixer(rgbA.getSource(),rgbB.getSource(),0.5);
Надеемся, что эти функции помогут.
Ответ 7
Вам нужно использовать цветную модель CMY или RGB.
Почему Blue
+ Yellow
не может быть Gray
?
Blue
+ Yellow
= (Cyan
+ Magenta
) + Yellow
= > Gray
. Почему бы и нет?
Посмотрите на это.
Итак, вы можете использовать RGB (CMY) для смешивания цветов.
Ответ 8
Как насчет преобразования RGB в CMYK с помощью this, а затем:
// CMYK colors
colorA = [2, 90, 94, 0];
colorB = [4, 0, 80, 0];
colorMixC = (colorA[0] + colorB[0]) / 2;
colorMixM = (colorA[1] + colorB[1]) / 2;
colorMixY = (colorA[2] + colorB[2]) / 2;
colorMixK = (colorA[3] + colorB[3]) / 2;
И окончательно преобразуйте CMYK в RGB, используя this