Почему моя функция смешивания цветов не работает должным образом? - PullRequest
0 голосов
/ 21 ноября 2011

У меня есть эта функция, которая принимает два аргумента. Это массивы в формате [r, g, b].

function mix(color1, color2) 
{
    var r = Math.round((color1[0] + color2[0])/2);
    var g = Math.round((color1[1] + color2[1])/2);
    var b = Math.round((color1[2] + color2[2])/2);

    return [r, g, b];
}

Если я попытаюсь смешать красный (255, 0, 0) и синий (0, 0, 255), tt даст мне [128,0,128], что фиолетового цвета. Но если я попытаюсь смешать синий (0, 0, 255) и желтый (255, 255, 0)

console.log(mix([255,0,0], [0,0,255]));
console.log(mix([255,255,0], [0,0,255]));

это дает мне серый [128, 128, 128] вместо зеленого. Почему это происходит?

Ответы [ 5 ]

4 голосов
/ 21 ноября 2011

Вам необходимо преобразовать свои цвета в цветовые модели HSL или HSV (множество образцов здесь или в Google, например, например эта страница ).

Затем вы выполняете усреднение с помощьюПолученные числа, а затем преобразовать обратно в RGB.

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

Использованиебиблиотека, связанная выше:

function mix(color1, color2, amount) 
{
    if (typeof amount === "undefined") {
        amount = 0.5;
    }

    var hsl1 = rgbToHsl.apply(this, color1);
    var hsl2 = rgbToHsl.apply(this, color2);

    var h = amount * hsl1[0] + (1 - amount) * hsl2[0];
    var s = amount * hsl1[1] + (1 - amount) * hsl2[1];
    var l = amount * hsl1[2] + (1 - amount) * hsl2[2];

   return hslToRgb(h, s, l);
}

Примечание: это непроверенный код (алгоритм верен, я просто еще не бросил его в интерпретатор), и результаты, возможно, должны быть округлены.Однако для бонусных баллов также можно указать пропорцию микширования, отличную от 50/50.

2 голосов
/ 13 ноября 2012

2 основных вопроса здесь:

добавка к вычитающему смешиванию - это легко прочитать о

Но я думаю, главная проблема заключалась в том, что сине-желтая краска делаетне делать зеленый.Тип синего цвета, о котором вы бы подумали, на самом деле не синий: скорее синий или, по крайней мере, синий с некоторым зеленым сдвигом.

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

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

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

Однако имейте в виду, что аддитивное смешивание несколько нелогично - вместо того, чтобы ваша субтрактивная краска синего / желтого цвета давала нейтральный серый (черный в теории) фактически с огнями, вы могли бы получить белый цвет .... (по-прежнему)не зеленый!).

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

2 голосов
/ 21 ноября 2011

Поскольку вы рассчитываете результирующий цвет как среднее арифметическое двух основных цветов.

Цвета работают по-разному в зависимости от того, что вы смешиваете.Если вы смешаете краски разных цветов, результат будет темным, почти черным.Но если бы вы смешали огни разных цветов, результат был бы почти белым.Сначала определите процесс, который вы хотите смоделировать - держу пари, что он похож на смешивание красок, верно?

Два основных метода смешивания цветов:

  • вычитающее смешение, которое выглядит так:

    enter image description here

  • аддитивное смешение, которое выглядит так:

    enter image description here

Вам нужно вычитающее смешение цветов, вывод которого должен быть в RGB обозначении.

1 голос
/ 21 ноября 2011

Чтобы получить то, что вы ожидаете, вам нужно работать в пространстве CMY вместо пространства RGB.

Вот простой конвертер RGB в CMY:

function rgb2cmy (r, g, b) {
  var c = 255-r;
  var m = 255-g;
  var y = 255-b;
  return [c,m,y];
}

И просто обратный процесс для преобразования обратно в RGB:

function cmy2rgb (c, m, y) {
  var r = 255-c;
  var g = 255-m;
  var b = 255-y;
  return [r,g,b];
}

(если вы обратили внимание, вы поймете, что обе функции выполняют одно и то же)

0 голосов
/ 21 ноября 2011

Я думаю, что ваша формула работает нормально, это то, что, скажем, сделал бы фотошоп, если бы вы поместили синий цвет рядом с желтым и применили размытие ... вы бы получили серый цвет посередине.Синий и желтый не смешиваются, чтобы сделать зеленый.Красный, зеленый и синий - основные цвета на компьютерных мониторах, пленке камеры и человеческом глазу.

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

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

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