Рассчитайте RGB-коды смешанных цветов, используя красный, синий и ЖЕЛТЫЙ в качестве основных цветов - PullRequest
2 голосов
/ 27 января 2012

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

Вот что я пытаюсь сделать: из двух заданных цветов RGB я хотел бы рассчитать код RGB для комбинированного цвета, и я бы хотел, чтобы цвета смешивались, как акварель на бумаге. Как я понял расчет обычно выглядит так:

  • # FF0000 + # 0000FF = # 880088 ((FF + 00) / 2 = 88, (00 + 00) / 2 = 00, (00 + FF) / 2 = 88), поэтому красный и синий дают фиолетовый ( как следует)
  • # FF0000 + # FFFF00 = # FF8800 ((FF + FF) / 2 = FF, (00 + FF) / 2 = 88, (00 + 00) / 2 = 00), поэтому красный и желтый дают оранжевый ( как положено)

Однако при смешивании синего и желтого цветов результат будет серым:

  • # 0000FF + # FFFF00 = # 888888 ((00 + FF) / 2 = 88, (00 + FF) / 2 = 88, (FF + 00) / 2 = 88) = СЕРЫЙ

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

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

Ответы [ 4 ]

5 голосов
/ 02 февраля 2013

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

Первый шаг - создать цветовое колесо с требуемым нам распределением оттенков., с красным, желтым и синим с шагом 120 градусов.В сети есть много примеров.Я создал один, который имеет только полностью насыщенные цвета, чтобы его можно было использовать для создания полной гаммы RGB.Цвета на колесе абсолютно произвольны;Я установил оранжевый (60 °) на (255 160,0), потому что средняя точка между красным и желтым была слишком красной, и я переместил чистый синий (0,0 255) на 250 ° вместо 240 °, чтобы 240 °Синий будет выглядеть лучше.

RYB hue color wheel

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

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

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

Код представлен на Python, но его нетрудно преобразовать в другие языки.,Самая хитрая часть - это добавление красного, желтого и синего для создания угла оттенка.Я использую векторное сложение и конвертирую обратно в угол с atan2.Почти все остальное делается с помощью линейной интерполяции (lerp).

# elementary_colors.py
from math import degrees, radians, atan2, sin, cos

red = (255, 0, 0)
orange = (255, 160, 0)
yellow = (255, 255, 0)
green = (0, 255, 0)
cyan = (0, 255, 255)
blue = (0, 0, 255)
magenta = (255, 0, 255)
white = (255, 255, 255)
black = (0, 0, 0)
mud = (94, 81, 74)

colorwheel = [(0, red), (60, orange), (120, yellow), (180, green),
              (215, cyan), (250, blue), (330, magenta), (360, red)]

red_x, red_y = cos(radians(0)), sin(radians(0))
yellow_x, yellow_y = cos(radians(120)), sin(radians(120))
blue_x, blue_y = cos(radians(240)), sin(radians(240))

def lerp(left, right, left_part, total):
    if total == 0:
        return left
    ratio = float(left_part) / total
    return [l * ratio + r * (1.0 - ratio) for l,r in zip(left, right)]

def hue_to_rgb(deg):
    deg = deg % 360
    previous_angle, previous_color = colorwheel[0]
    for angle, color in colorwheel:
        if deg <= angle:
            return lerp(previous_color, color, angle - deg, angle - previous_angle)
        previous_angle = angle
        previous_color = color

def int_rgb(rgb):
    return tuple(int(c * 255.99 / 255) for c in rgb)

def rybwk_to_rgb(r, y, b, w, k):
    if r == 0 and y == 0 and b == 0:
        rgb = white
    else:
        hue = degrees(atan2(r * red_y + y * yellow_y + b * blue_y,
                            r * red_x + y * yellow_x + b * blue_x))
        rgb = hue_to_rgb(hue)
        rgb = lerp(mud, rgb, min(r, y, b), max(r, y, b))
    gray = lerp(white, black, w, w+k)
    rgb = lerp(rgb, gray, r+y+b, r+y+b+w+k)
    return int_rgb(rgb)
1 голос
/ 30 апреля 2015

Я предлагаю отступить от понятия праймериз, будь то RGB или RYB или CMY и т. Д.

Насколько я понимаю, ваша цель состоит в том, чтобы смешивать цвета (которые описаны в цветовом пространстве RGB) таким образом, чтобы имитировать, как краска будет смешиваться, то есть смешиваться субтрактивно. Преобразование из RGB в CMY или CMYK не будет продуктивным, потому что вам все равно придется иметь дело с вычислением вычитающей смеси, что не так просто сделать в пространстве CMY.

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

Есть еще один похожий вопрос: https://stackoverflow.com/questions/10254022/,, где этот процесс обсуждается более подробно.

1 голос
/ 27 января 2012

Если вы смешаете красные, синие и желтые краски, вы получите мутный коричневый, а не черный. Это потому, что «красный, синий и желтый» не совсем точные основные цвета. Голубой, пурпурный и желтый - вот почему принтеры работают в CMYK (K - черный).

Так что вы на самом деле спрашиваете, как преобразовать цвет RGB в CMYK, и в этом случае любая из этих ссылок поможет вам.

0 голосов
/ 27 января 2012

Голубой, пурпурный и желтый - это то, что должно быть красным, желтый и синий - средневековое соглашение.

Видимо, это не просто переключение, и я уснул посреди математики, но вот один из способов.

RYB RGB Преобразование

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