计算混合颜色的RGB代码,假设红色,蓝色和黄色为原色 [英] Calculate RGB codes of mixed colors assuming red, blue and YELLOW as primary colors

查看:1815
本文介绍了计算混合颜色的RGB代码,假设红色,蓝色和黄色为原色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

光色和油漆不匹配:物理学家会说三原色是红色,绿色和蓝色,画家会给出红色,蓝色和黄色作为原色。
事实上,当用水彩画时,你不能混合红色,绿色和蓝色的黄色,而不是混合橙色,你只会变成棕色。

There is a mismatch between light colors and paint: While a physicist will say that the three primary colors are red, green and blue, a painter will give red, blue and yellow as primary colors. Indeed, when painting with watercolors, you can't mix a yellow from red, green and blue, and instead of mixing orange you'll only get brown.

这里是我想做的:从两个给定的RGB颜色,我想计算的组合颜色的RGB代码,我想要的颜色混合像水彩在纸上。根据我的理解,计算通常如下:

Here is what I'm trying to do: From two given RGB colors I'd like to calculate the RGB code for the combined color, and I'd like the colors to blend like watercolor would on paper. As I understood the calculation normally would look like this:


  • #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),因此红色和黄色显示橙色
  • #FF0000 + #0000FF = #880088 ((FF+00)/2 = 88, (00+00)/2 = 00, (00+FF)/2 = 88), so red and blue gives purple (as it should)
  • #FF0000 + #FFFF00 = #FF8800 ((FF+FF)/2 = FF, (00+FF)/2 = 88, (00+00)/2 = 00), so red and yellow gives orange (as it should)

但是,当混合蓝色和黄色时,结果为灰色:

However, when mixing blue and yellow, the result is grey:


  • #0000FF +#FFFF00 =#888888((00 + FF)/ 2 = 88,(00 + FF)/ 2 = 88,(FF + 00)/ 2 = 88)= GRAY

在纸上,你会得到绿色(#008800),混合颜色时永远不会变灰。

while on paper you'd expect to get green (#008800) and could never get grey when mixing colors.

所以我的问题是,我怎么能用黄色作为原色交换绿色,我怎么能计算遵循油漆的法则而不是浅色的法律的混合颜色?

So my question is, how can I kind of exchange green with yellow as primary color, and how can I then calculate mixed colors which follow the laws of paint rather than those of light colors?

推荐答案

没有简单的物理模型可以做到这一点,画家的颜色与光非常精细的互动。幸运的是,我们有计算机,不限于对物理世界建模 - 我们可以让他们做任何任意的事情,我们想要的!

There's no simple physical model which will do this, the painter's colors have very elaborate interactions with light. Fortunately we have computers, which are not limited to modelling the physical world - we can make them do any arbitrary thing we'd like!

第一步是创建一个色轮与我们需要的色相分布,红色,黄色和蓝色以120度增量。网上有很多例子。我在这里创建一个只有完全饱和的颜色,以便它可以用于生成完整的RGB色域。车轮上的颜色是完全任意的;我将橙色(60°)设置为(255,160,0),因为红色和黄色之间的中点太红,我将纯蓝色(0,0,255)移动到250°而不是240°,使240°蓝色会更好看。

The first step is to create a color wheel with the hue distribution that we require, with red, yellow, and blue at 120 degree increments. There are many examples on the web. I've created one here that only has fully saturated colors so that it can be used to generate the full RGB gamut. The colors on the wheel are completely arbitrary; I've set Orange (60°) to (255,160,0) because the midpoint between Red and Yellow was too red, and I've moved pure Blue (0,0,255) to 250° instead of 240° so that the 240° Blue would look better.

记住我的童年的实验,当你混合等量的红色,黄色和蓝色,你会得到一个模糊的棕色灰色。我选择了一个合适的颜色,你可以看到在色轮的中心;在代码中我亲切地称之为泥。

Remembering the experiments of my childhood, when you mix equal amounts of Red, Yellow, and Blue together you get an indistinct brownish gray. I've chosen a suitable color which you can see at the center of the color wheel; in the code I affectionately call it "mud".

为了得到每一种可想象的颜色,你需要比红色,黄色和蓝色,你还需要混合白色和黑色。例如,你通过混合红色和白色得到粉红色,你通过混合橙色(黄色+红色)和黑色得到棕色。

To get every conceivable color you need more than Red, Yellow, and Blue, you also need to mix White and Black. For example you get Pink by mixing Red and White, and you get Brown by mixing Orange (Yellow+Red) with Black.

转换与比率, 。与真正的油漆一样,混合1份红色和1份黄色,与100份红色和100份黄色没有区别。

The conversion works with ratios, not absolute numbers. As with real paint there's no difference between mixing 1 part red and 1 part yellow, versus 100 parts red and 100 parts yellow.

代码是以Python呈现的,但它应该不能很难转换为其他语言。最棘手的部分是添加红色,黄色和蓝色以创建色相角。我使用向量加法并转换回一个角度与 atan2 。几乎所有的事情都用线性插值(lerp)完成。

The code is presented in Python but it shouldn't be hard to convert to other languages. The trickiest part is adding the Red, Yellow and Blue to create a hue angle. I use vector addition and convert back to an angle with atan2. Almost everything else is done with linear interpolation (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)

这篇关于计算混合颜色的RGB代码,假设红色,蓝色和黄色为原色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆