Algorithme pour trouver la couleur entre deux autres - dans l'espace des couleurs peintes
en mélangeant du bleu et du jaune, le résultat est une sorte de vert.
j'ai deux couleurs rgb:
Bleu = (0, 0, 255)
et jaune = (255, 255, 0)
Quel est l'algorithme pour trouver la couleur RVB qui est le résultat du mélange des deux couleurs, comme ils apparaissent lors de l'utilisation de la peinture? Les couleurs résultantes de l'algorithme ne doit pas être terriblement exacte. Pour l'exemple ci-dessus ne devrait plus ressembler à une sorte de vert.
Merci d'avance.
modifier: cette fonction, écrite en Go, a fonctionné pour moi, d'après la réponse de bac.
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}
}
Edit #2 Allthought cela arrive à mélanger le cyan et le jaune, le mélange entre le bleu et le jaune devient noir, ce qui ne semble pas juste. Je cherche toujours un algorithme qui fonctionne.
Edit #3 voici un exemple de travail complet dans Go, en utilisant le colorspace HLS: http://go.pastie.org/1976031 . Merci Mark Ransom.
Edit #4 Il semble que la voie à suivre, même pour un meilleur mélange des couleurs serait d'utiliser la Kubelka-Munk équation
5 réponses
peinture fonctionne par absorption. On commence avec la lumière blanche (255,255,255) et on la multiplie par les facteurs d'absorption.
la peinture bleue absorbe toute la lumière rouge et verte qui la frappe.
la peinture jaune absorbe toute la lumière bleue qui la frappe.
dans un monde parfait, cela signifie que la combinaison de la peinture jaune et bleue résulterait en une peinture noire, ou au mieux un gris boueux. En pratique, la peinture "bleue" a un penchant pour le vert, donc vous prends un vert boueux. Je n'ai jamais vu un exemple de mélange de jaune et de bleu qui produit satisfaisant vert. Wikipedia entre dans certaines des complexités de ce processus: http://en.wikipedia.org/wiki/Primary_color#Subtractive_primaries
je pense que ce que vous demandez vraiment est comment interpoler les couleurs le long d'une roue de couleur. Cela devrait être indépendant de si les couleurs sont absorbantes comme dans la peinture, ou émissive comme dans les écrans RVB.
Edit: en travaillant dans l'espace couleur HSL vous pouvez obtenir le genre de résultats que vous recherchez. Voici un code en Python qui implémente l'algorithme; la moyenne des teintes est délicate, et est basée sur une réponse précédente de la mienne pour la moyenne des 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)
notez que cette réponse n'est pas émule le mélange de peinture, pour les raisons indiquées ci-dessus. Il donne plutôt un mélange intuitif de des couleurs qui ne sont pas ancrées dans la réalité physique du monde.
en fait, on obtient du vert en mélangeant (soustractivement) du jaune et du cyan. Le jaune est rouge + vert (255, 255, 0), le cyan est vert + bleu (0, 255, 255). Maintenant faire leurs couleurs opposées: bleu (0, 0, 255) et rouge (255, 0, 0). Mélangez-les additivement et vous obtenez pourpre (255, 0, 255). Faites son contraire et vous obtenez Vert (0, 255, 0).
En d'autres termes, vous pouvez obtenir un mélange soustractif comme le contraire de l'additif mélange des contraires de vos deux couleurs.
L'espace de couleur RBG est basé sur la lumière émission , l'espace de couleur des colorants et des pigments est basé sur la lumière absorption .
p.ex. les végétaux n'ont pas l'air vert parce qu'ils émettent de la lumière verte, mais parce qu'ils absorbent toutes les couleurs de lumière autres , réfléchissant uniquement le vert.
basé sur cela, vous devriez être en mesure d'obtenir assez proche en faisant une conversion de RGB à un espace de couleur absorbant, en faisant le "mélange" puis de nouveau.
Tu veux utiliser soustractive CMY-couleurs (Cyan, Magenta, Jaune) (que le LaC est en train de faire, sans utiliser le terme)
la conversion en va-et-vient est simple: (C,M,Y) = (- R, - G, - B).
Donc CMY (0,0) est blanc et CMY (FF,FF,FF) est noir.
lorsque vous ajoutez deux couleurs CMY, il y a différentes façons de calculer les nouvelles valeurs. Vous pouvez prendre la moyenne, max ou quelque chose entre pour chaque valeur de couleur.
Par exemple. pour les filtres de lumière, vous utilisez toujours la valeur max. Pour la peinture que vous voulez utiliser correctement, quelque chose plus proche de la valeur moyenne.
comme le souligne LaC, on n'obtient pas le vert en mélangeant le jaune et le bleu, mais en mélangeant le jaune et le cyan. Le jaune et le bleu donnent en fait noir, lorsque le mélange par la valeur max (par exemple. la lumière des filtres). C'est pourquoi, vous pourriez vouloir utiliser quelque chose de plus proche de la valeur moyenne pour mélanger la peinture.
vous ne voulez pas utiliser CMYK, à moins que vous voulez imprimer quelque chose. La couleur Noire "K" est principalement utilisée dans les imprimantes pour économiser l'encre, mais elle n'est pas nécessaire pour représenter les couleurs.
utiliser convertir:: couleur pour produire ce genre de sortie:
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]
lors de l'exécution de ce type de 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;;
}