A color search algorithm between two others - in the color space of painted colors

When mixing blue and yellow paint, the result is a kind of green color.

I have two rgb colors:

blue = (0, 0, 255)

and yellow = (255, 255, 0)

What is the rgb color search algorithm that results from mixing two colors, how will they appear when using paint? The resulting colors from the algorithm need not be accurate. For the example above, it should look something like green.

Thanks in advance.

Edit: This function, written in Go, worked for me based on a response from 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} } 

Change # 2 . All this allows you to mix blue and yellow, the combination between blue and yellow turns black, which seems wrong. I am still looking for an algorithm of work.

Edit # 3 Here is a complete working example in Go using the HLS color space: http://go.pastie.org/1976031 . Thanks Mark Ransom.

Edit # 4 It seems that the way forward for even better color mixing would be to use the Kubelka-Munk equation

+26
algorithm colors go rgb
May 25 '11 at 20:38
source share
5 answers

Paint works by absorption. You start with white light (255,255,255) and multiply it by absorption coefficients.

Blue paint absorbs all the red and green light that enters it.

Yellow paint absorbs all the blue light that enters it.

In an ideal world, this means that a combination of yellow and blue paint will result in black paint or, at best, dirty gray. In practice, “blue” paint has a bias towards green, so you get dirty greens. I have never seen an example of mixing yellow and blue, which produces a satisfactory green color. Wikipedia moves on to some of the complexities of this process: http://en.wikipedia.org/wiki/Primary_color#Subtractive_primaries

I think you are really asking how to interpolate colors along the color wheel. This should be regardless of whether the colors are absorbent, like in paint, or emission, like on RGB displays.

Edit:. By working in the HSL color space, you can get the results you are looking for. Here is some Python code that implements the algorithm; averaging shades are complex and based on my previous answer 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) 

Please note that in this answer do not emulate paint mixing for the reasons stated above. Rather, it provides an intuitive color mixing that is not grounded in any physical reality of the world.

+12
May 25 '11 at 21:15
source share

In fact, you get green from mixing (subtractively) yellow and blue. Yellow red + green (255, 255, 0), blue - green + blue (0, 255, 255). Now make them the opposite colors: blue (0, 0, 255) and red (255, 0, 0). Mix them additively and you get purple (255, 0, 255). Make your opposite and you will get green (0, 255, 0).

In other words, you can get a subtractive mix, the opposite of the additive combination of the opposites of your two colors.

+9
May 25 '11 at 21:02
source share

The RBG color space is based on light emission, the color space of dyes and pigments is based on light absorption.

eg. The plant does not look green because they emit green light, but because they absorb all other colors of light that reflect only green.

Based on this, you should be close enough when doing a conversion from RGB to an absorbing color space, doing a “mix” and then back.

+4
May 25 '11 at 21:02
source share

You want to use subtractive CMY colors (cyan, magenta, yellow) (as LaC does without using the term)

Converting back and forth is simple: (C, M, Y) = (-R, -G, -B).
Thus, CMY (0,0,0) is white, and CMY (FF, FF, FF) is black.

When you add two CMY colors, there are various ways to calculate new values. You can take the average, maximum or something average between each color value.
For example. for filters you always use the maximum value. For the paint that you are using correctly, something is closer to the average.

As LaC points out, you do not get green from mixing yellow and blue, but from mixing yellow and blue. Yellow and blue actually give a black color when mixed with a maximum value (for example, filters). This is why you can use something closer to the average value of mixing paint.

You do not want to use CMYK if you do not want to print something. Black color "K" is mainly used in printers to save ink, but you do not need to represent colors.

+2
May 25 '11 at 21:48
source share

Use Convert :: Color to create this kind of output:

 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] 

When running this type of code:

 #!/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;; } 
+1
May 26 '11 at
source share



All Articles