2011-05-25 174 views
26

當混合藍色和黃色顏料時,結果是某種綠色。查找其他兩種顏色的算法 - 在顏色的顏色空間中

我有兩個RGB顏色:

藍色=(0,0,255)

和黃色=(255,255,0)

什麼算法查找RGB顏色那是兩種顏色混合的結果,就像使用油漆時會出現的那樣?算法產生的顏色不一定非常精確。對於上面的例子,它只需要看起來像某種綠色。

在此先感謝。

編輯:這個函數是用Go編寫的,基於LaC的答案爲我工作。

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 Allthought這個管理混合青色和黃色,藍色和黃色之間的組合變成了黑色,這看起來不正確。我仍然在尋找一個有效的算法。

編輯#3下面是Go中使用HLS顏色空間的完整示例:http://go.pastie.org/1976031。感謝Mark Ransom。

編輯#4好像前進的道路實現更好的色彩混合是使用庫貝爾卡 - 蒙克公式

+2

這是一個很好的一個。如果有人想出來,他們可以在Wolfram找到一份工作。 http://www.wolframalpha.com/input/?i=yellow+%2B+blue – 2011-05-25 21:01:50

+1

已經回答了大部分位置:http://stackoverflow.com/questions/4235072/math-behind-the-colour-wheel – colinross 2011-05-25 21:11:48

+1

另一個重複:http://stackoverflow.com/questions/1351442/is-there-an-algorithm-for-color-mixing-that-works-like-mixing-real-colors – tylerl 2011-06-29 05:32:44

回答

12

油漆吸收。你從白光開始(255,255,255)並乘以吸收因子。

藍色油漆吸收所有擊中它的紅色和綠色光。

黃色油漆吸收所有擊中它的藍光。

在一個完美的世界裏,這意味着結合黃色和藍色油漆會導致黑色油漆,或者至多是灰色的泥濘。在實踐中,「藍色」塗料偏向於綠色,所以你會得到一個泥濘的綠色。我從來沒有見過混合黃色和藍色的例子,產生令人滿意的綠色。維基百科進入這個過程的一些複雜性:http://en.wikipedia.org/wiki/Primary_color#Subtractive_primaries

我想你真正要問的是如何沿色輪插入顏色。這應該與顏色在油漆中是吸收性的還是在RGB顯示中的發光性無關。

編輯:通過在HSL色彩空間中工作,您可以獲得所需的結果類型。以下是Python中的一些代碼,用於實現算法;平均色調是棘手的,並基於我的前一個回答for averaging angles

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) 

注意,這個答案不模擬調漆,由於上述原因說明。相反,它提供了一種直觀的顏色混合,而不是基於任何物理世界現實。

+1

使用HSL在我看來是一個很好的答案。我使用HSL解決了一些問題(例如生成隨機顏色集合),並給出了與人眼經驗非常一致的結果。 – 2011-05-26 12:17:34

+0

@Mark如果顏色不均勻 - 比如說30%紅色+ 70%藍色,你會如何調整? – glenstorey 2012-04-21 00:36:09

+1

我嘗試在我的UIColor + Mixing類中模擬真實世界的顏色。它混合RGB(電腦風格),RYB(真實世界,加法)和CMYK(真實世界,減法)。算法非常簡單,您可以調整除數(基於顏色數量)以獲得更多您喜歡的內容。沒有限制 - 玩得開心 - https://github.com/ddelruss/UIColor-Mixing享受。 – 2012-05-03 20:32:48

9

實際上,你從混合(相減),黃色和青色綠色。黃色是紅色+綠色(255,255,0),青色是綠色+藍色(0,255,255)。現在使他們的相反的顏色:藍色(0,0,255)和紅色(255,0,0)。混合它們,你會得到紫色(255,0,255)。使其相反,你得到綠色(0,255,0)。

換句話說,你可以得到一個減法混合,作爲兩種顏色相反的加法混合的反面。

4

顏色空間RBG是基於光發射,染料和顏料的顏色空間是基於光吸收

例如植物不會因綠色發光而顯得綠色,而是因爲它們吸收了所有顏色的光線,僅反射綠光。

基於此,通過從RGB到吸收性色彩空間的轉換,執行「混合」然後再返回,您應該能夠非常接近。

+0

CMYK是標準的吸收色彩空間。 – blueberryfields 2011-05-25 21:10:35

+0

CMYK是*常用的吸收顏色空間之一*,也許是最常見的。這足以解決OP問題。 – Bevan 2011-05-26 00:53:13

2

你想使用減色CMY-色(青色,洋紅色,黃色)(作爲LAC是幹什麼的,內部消除使用術語)

的來回轉換很簡單:(C,M,Y)=( -R,-G,-B)。
所以CMY(0,0,0)是白色,CMY(FF,FF,FF)是黑色。

當您添加了兩個CMY的顏色,也有不同的方法來計算新的值。您可以爲每個顏色值取平均值,最大值或其他值。例如:
例如。對於光過濾器,您始終使用最大值。對於你想要使用的油漆,更接近平均值。

由於LAC所指出的,你沒有得到從混合黃色和藍色,綠色,但是從混合黃色和青色。當以最大值混合時(如濾光片),黃色和藍色實際上會產生黑色。這就是爲什麼,您可能想要使用更接近油漆混合平均值的東西。

你不想使用CMYK,除非你要打印的東西。黑色「K」顏色主要用於打印機以節省墨水,但不需要表示顏色。

1

使用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;; 
} 
+0

從http://search.cpan.org/從http://search.cpan.org/src/PEVANS/List-UtilsBy-0.07/lib/List/UtilsBy.pm和List :: UtilsBy安裝Convert :: Color之後, /src/PEVANS/List-UtilsBy-0.07/lib/List/UtilsBy.pm, 這是我所得到的,當我運行上面的Perl腳本(添加缺少的「}」結尾): 無法識別的色彩空間名字'rgb8'在./color.pl 12行 – Alexander 2011-05-26 10:12:16

+0

嗯,那是我跑的程序。哦,我明白了,我正在運行Convert :: Color的0.08版本。檢查您的版本號。 – tchrist 2011-05-26 13:02:18

+0

一個迫使你處理Perl而不是處理手頭問題的答案不是我正在尋找的... – Alexander 2012-05-02 12:33:33