查找两种颜色之间的颜色的算法-在绘画颜色的颜色空间中

|| 当混合蓝色和黄色油漆时,结果是某种绿色。 我有两种rgb颜色: 蓝色=(0,0,255) 黄色=(255,255,0) 找到两种颜色混合使用时产生的rgb颜色的算法是什么?该算法产生的颜色不必十分精确。对于上面的示例,它只需要看起来像某种绿色即可。 提前致谢。 编辑:根据LaC的回答,用Go编写的此功能对我有用。
func paintMix(c1, c2 image.RGBAColor) image.RGBAColor { 
    r := 255 - ((255 - c1.R) + (255 - c2.R))
    g := 255 - ((255 - c1.G) + (255 - c2.G))
    b := 255 - ((255 - c1.B) + (255 - c2.B))
    return image.RGBAColor{r, g, b, 255}
}
编辑#2虽然如此,但设法将青色和黄色混合,蓝色和黄色之间的混合变为黑色,这似乎不正确。我仍在寻找有效的算法。 编辑#3这是Go中使用HLS颜色空间的完整工作示例:http://go.pastie.org/1976031。谢谢马克·兰瑟姆。 编辑#4似乎更好的混色方法是使用Kubelka-Munk方程     
已邀请:
油漆通过吸收起作用。首先从白光(255,255,255)乘以吸收系数。 蓝色油漆吸收了所有击中它的红色和绿色光。 黄色油漆吸收了所有击中它的蓝光。 在一个理想的世界中,这意味着将黄色和蓝色的油漆混合会产生黑色的油漆,或至多是浑浊的灰色。实际上,“蓝色”涂料偏向绿色,因此您会得到绿色的泥泞。我从未见过将黄色和蓝色混合产生令人满意的绿色的示例。 Wikipedia讨论了此过程的一些复杂性:http://en.wikipedia.org/wiki/Primary_color#Subtractive_primaries 我认为您真正要问的是如何沿着色轮对颜色进行插值。这应该与颜色是吸收性的(如涂料中的)还是发射性的(如RGB显示器中的)无关。 编辑:通过在HSL色彩空间中工作,您可以获得所需的结果。这是一些实现该算法的Python代码;平均色调是棘手的,并且基于我先前对平均角度的回答。
from colorsys import rgb_to_hls,hls_to_rgb
from math import sin,cos,atan2,pi

def average_colors(rgb1, rgb2):
    h1, l1, s1 = rgb_to_hls(rgb1[0]/255., rgb1[1]/255., rgb1[2]/255.)
    h2, l2, s2 = rgb_to_hls(rgb2[0]/255., rgb2[1]/255., rgb2[2]/255.)
    s = 0.5 * (s1 + s2)
    l = 0.5 * (l1 + l2)
    x = cos(2*pi*h1) + cos(2*pi*h2)
    y = sin(2*pi*h1) + sin(2*pi*h2)
    if x != 0.0 or y != 0.0:
        h = atan2(y, x) / (2*pi)
    else:
        h = 0.0
        s = 0.0
    r, g, b = hls_to_rgb(h, l, s)
    return (int(r*255.), int(g*255.), int(b*255.))

>>> average_colors((255,255,0),(0,0,255))
(0, 255, 111)
>>> average_colors((255,255,0),(0,255,255))
(0, 255, 0)
请注意,由于上述原因,该答案并不模拟涂料混合。而是提供直观的颜色混合,这是任何现实世界中都不存在的。     
实际上,通过将黄色和青色(相减)混合可以得到绿色。黄色是红色+绿色(255、255、0),青色是绿色+蓝色(0、255、255)。现在使用相反的颜色:蓝色(0,0,255)和红色(255,0,0)。将它们相加混合即可得到紫色(255、0、255)。相反,变成绿色(0、255、0)。 换句话说,您可以将减色混合作为两种颜色相反的加性混合的相反。     
色空间RBG基于发光,染料和颜料的色空间基于光吸收。 例如植物的外观不是绿色的,因为它们发出绿光,而是因为它们吸收了所有其他颜色的光,仅反射绿色。 基于此,您应该能够完成从RGB到吸收性色彩空间的转换,进行“混合”,然后再次返回,就可以非常接近了。     
您想使用减色CMY颜色(青色,品红色,黄色)(如LaC所做的那样,而未使用该术语) 来回转换很简单:(C,M,Y)=(-R,-G,-B)。 因此CMY(0,0,0)是白色,而CMY(FF,FF,FF)是黑色。 添加两种CMY颜色时,有不同的方法来计算新值。您可以为每个颜色值取平均值,最大值或介于两者之间的值。 例如。对于滤光器,您始终使用最大值。对于您要正确使用的油漆,它接近平均值。 正如LaC所指出的,混合黄色和蓝色不会得到绿色,而是将黄色和青色混合得到绿色。当以最大值混合时(例如,滤光器),黄色和蓝色实际上给出黑色。这就是为什么您可能要使用更接近平均值的油漆混合的原因。 您不想使用CMYK,除非您要打印一些东西。黑色的“ K”颜色主要用于打印机中以节省墨水,但不需要代​​表颜色。     
使用Convert :: Color产生这种输出:
mauve        is 0xE0B0FF  sRGB=[224,176,255]  HSV=[276, 31,100] 
vermilion    is 0xE34234  sRGB=[227, 66, 52]  HSV=[  5, 77, 89] 
mix          is 0xE2799A  sRGB=[226,121,154]  HSV=[341, 46, 89] 

red          is 0xFF0000  sRGB=[255,  0,  0]  HSV=[  0,100,100] 
blue         is 0x0000FF  sRGB=[  0,  0,255]  HSV=[240,100,100] 
red+blue     is 0x800080  sRGB=[128,  0,128]  HSV=[300,100, 50] 

black        is 0xFFFFFF  sRGB=[255,255,255]  HSV=[  0,  0,100] 
white        is 0x000000  sRGB=[  0,  0,  0]  HSV=[  0,  0,  0] 
grey         is 0x808080  sRGB=[128,128,128]  HSV=[  0,  0, 50] 

dark red     is 0xFF8080  sRGB=[255,128,128]  HSV=[  0, 50,100] 
light red    is 0x800000  sRGB=[128,  0,  0]  HSV=[  0,100, 50] 

pink         is 0x800080  sRGB=[128,  0,128]  HSV=[300,100, 50] 
deep purple  is 0xBF80FF  sRGB=[191,128,255]  HSV=[270, 50,100] 
运行此类代码时:
#!/usr/bin/env perl
use strict;
use warnings;

use Convert::Color;

main();
exit;

sub rgb($$$) {
    my($r, $g, $b) = @_;
    return new Convert::Color:: \"rgb8:$r,$g,$b\";
}

sub show($$) {
    my ($name, $color) = @_;
    printf \"%-12s is 0x%6s\", $name,  uc $color->hex;
    printf \"  sRGB=[%3d,%3d,%3d] \",     $color->rgb8;

    my ($h,$s,$v) = $color->as_hsv->hsv;
    for ($s, $v) { $_ *= 100 }
    printf \" HSV=[%3.0f,%3.0f,%3.0f] \",  $h, $s, $v;
    print \"\\n\";
}

sub main {
    my $vermilion = rgb 227,  66,  52;
    my $mauve     = rgb 224, 176, 255;
    show mauve      => $mauve;
    show vermilion  => $vermilion;

    my $mix = alpha_blend $mauve $vermilion;
    show mix => $mix;
    print \"\\n\";

    my $red   = rgb 255,   0,   0;
    my $blue  = rgb   0,   0, 255;
    show red  => $red;
    show blue => $blue;

    $mix = alpha_blend $red $blue;
    show \"red+blue\" => $mix;
    print \"\\n\";

    my $black = rgb 255, 255, 255;
    my $white = rgb 0,     0,   0;
    show black => $black;
    show white => $white;

    my $grey  = alpha_blend $black $white;
    show grey  => $grey;
    print \"\\n\";

    my $dark_red  = alpha_blend $red $black;
    my $light_red = alpha_blend $red $white;

    show \"dark red\"  => $dark_red;
    show \"light red\" => $light_red;
    print \"\\n\";

    my $magenta = rgb 255, 0, 255;
    my $violet  = rgb 127, 0, 255;

    my $pink        = alpha_blend $magenta $white;
    my $deep_purple = alpha_blend $violet  $black;

    show pink          => $pink;
    show \"deep purple\" => $deep_purple;;
}
    

要回复问题请先登录注册