2012-01-26 71 views
2

浅色和油漆之间存在不匹配情况:虽然物理学家会说三原色是红色,绿色和蓝色,但画家会给红色,蓝色和黄色作为原色。 事实上,用水彩画进行绘画时,不能混合红色,绿色和蓝色的黄色,而不是混合橙色,否则只会变成棕色。计算以红色,蓝色和黄色为原色的混合颜色的RGB代码

这里是我想要做的事:从给定的两个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),并且在混合颜色时不会变灰。

所以我的问题是,我该怎么样的交换黄绿为原色,我怎么可以再计算混合颜色的油漆遵循的规律,而不是那些光色?

+1

您是否看了:“[算法为RGB值添加颜色混合](http://stackoverflow.com/questions/726549/algorithm-for-additive-color-mixing-for-rgb-values)”或“[是否有一种颜色混合算法,像混合真实颜色一样工作?](http://stackoverflow.com/questions/1351442/is-there-an-algorithm-for-color-mixing-that-works-like-混合实时的颜色)“? – kmote

回答

1

如果您将红色,蓝色和黄色涂料混合在一起,您会看到一种黑褐色,而不是黑色。那是因为“红色,蓝色和黄色”并不是真正的原色。青色,品红色和黄色,这就是打印机在CMYK中工作的原因(K为黑色)。

那么你实际上问的是如何转换RGB色彩CMYK,在这种情况下any of these links会帮助你。

+0

RGB被认为是光的主要颜色,它们是http://en.wikipedia.org/wiki/Additive_color。 CMYK被认为是油漆的主要颜色,它们是http://en.wikipedia.org/wiki/Stratractive_color。了解差异将有助于您理解为什么以及何时需要在模型之间进行转换。 – dkamins

+0

染料的颜色一般遵循减色法的颜色规则(例如,将洋红与青色混合会产生蓝色,将蓝色与黄色混合会产生相当暗的颜色),但油漆颜色不会接近。将黄色油漆与非绿色蓝色(不是青色)混合,结果通常是绿色的。即使染料颜色遵守相减颜色规则可能是可疑的,除非选择死亡是因为它们具有可预测的相互作用能力。 – supercat

0

青色,洋红色和黄色是它应该是什么红色,黄色和蓝色是中世纪的习俗。

显然,这不是一个简单的开关,我在数学的中间睡着了,但这里有一个方法。

RYB RGB Conversion

5

有没有简单的物理模型,将做到这一点,画家的色彩与光线非常复杂的相互作用。幸运的是,我们有计算机,不限于物理世界的建模 - 我们可以让他们做任何我们想要的任意事情!

第一步是创建与我们所需要的色调分布,具有红色,黄色和蓝色,在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

我建议背弃初选的概念了,无论是RGB或RYB或CMY等

据我了解,你的目标是混合的颜色(即在RGB色彩空间中描述)以一种模拟油漆如何混合的方式,即减法混合。从RGB到CMY或CMYK的转换不会很有成效,因为您仍然需要处理减法混合计算,这在CMY空间中并不容易。

相反,让我建议您考虑将RGB颜色转换为光谱反射曲线。转换非常简单,一旦完成,您可以做一个真正的反射率曲线的减法混合,然后将结果转换回RGB。

还有另外一个类似的问题:https://stackoverflow.com/questions/10254022/,这个过程更详细的讨论。

+0

请尽量避免仅链接的答案。也许在答案中包含一个或两个片段 – ntzm

+1

感谢@natzim,我已经修改了我的答案并提供了更多细节。 –

相关问题