web-dev-qa-db-ja.com

JavaScriptで「自然に」2色を混ぜる

問題:JavaScriptで2つの色を混ぜて、結果の色を取得したい。 SOにも同様の質問がたくさんありますが、実際に正しく機能するものは見つかりません。 2つの異なるカラーペイント(顔料)とライトを混合すると、結果が大きく異なることを知っています( http://en.wikipedia.org/wiki/Color_mixing )。

これは、私がすでに見て、実装しようとした質問と提案された解決策です:

1:2つのRGBカラーベクトルを混合して結果を得る
そのため、RGBで色を混合します。私はそれを実装しましたが、場合によっては機能しません。

使用例:redyellowを混在させる-> orange。すごい!
http://jsbin.com/afomim/1/edit

動作しない例:blueyellowを混在させる-> gray。あまりよくない! :) http://jsbin.com/afomim/5/edit
RGBでは、blueyellowを混合してもgreenが作成されないことを知っています。その理由も理解しています。

ここでは答えが見つかりません。先に進みましょう。

2:塗料(青+黄=緑など)のように色(色)を一緒に追加する

このディスカッションで提案されているように、CMYK値を操作してみましょう。 cyanyellowを混在させると、greenが得られます。
http://jsbin.com/igaveg/1/edit
ただし、blueyellowを混在させると、blackになります。
http://jsbin.com/igaveg/2/edit ->機能していません!

3:C#で「自然に」色を混ぜる方法
非常によく似た質問。最も賛成の回答は、色をLABに変換することを提案しており、このソリューションは有望であるようです。
そこで、色をLABに変換しました。変換アルゴは正しいです、私はそれをテストしました!

http://jsbin.com/oxefox/1/edit

LABに2つの色がありますが、それらをどのように混合するのですか?

[〜#〜]注[〜#〜]多分、blueyellowを混合し、完全なgreenを与えるアルゴが見つからないことを知っています、しかし私は私が緑に似たものを生成できることを願っています:)

30
Tamás Pap

この質問には3〜4日を費やしました。それは本当に複雑な問題です。

2つの色を「自然に」混合したい場合にできることは次のとおりです。

  1. CMYKミキシング:これは完璧な解決策ではありませんが、今すぐ解決策が必要で、テーマについての学習、実験、コーディングに何ヶ月も費やしたくない場合は、これを確認してください: https:// github.com/AndreasSoiron/Color_mixer

  2. Kubelka-Munk理論の実装。私はそれについて多くの時間を読み、それを理解しようとしました。これは、プロフェッショナルなソリューションが必要な場合に最適な方法ですが、混合する各色について6つのパラメーター(反射率、吸収など)が必要です。 R、G、Bがあるだけでは十分ではありません。理論の実装は難しくありませんが、各色について必要なパラメーターを取得することは、欠けている部分のようです。あなたがそれを行う方法を理解したら、私に知らせてください:)

  3. 実験的:ipadアプリの開発者が行うことを行うことができます: Paper 彼らは手動で人気のある色の100ペアを選択し、それらがどのようにブレンドすべきかを眼球でテストしました。詳しくはこちら こちら

個人的には今のところCMYKミキシングを実装しますが、多分後で、時間があればフィフティスリーのようなものを作ろうと思います。見るでしょう:)

33
Tamás Pap

RYBカラーモデルは、カラーミキシングの計算に適しています。 Wikipedia によると、これは主に芸術とデザインの教育、特に絵画で使用されています。

2つの色を混合するには、両方の色をRGBからRYBに変換し、各色成分を追加して色を混合し、結果の色をRYBからRGBに変換します。

Online Color Mixing Tool を使用してこれを試しましたが、結果は

  • 0000FF(blue)を#FFFF00(yellow)と混合すると、#008000になります。 (濃い緑)、

  • FF0000(red)を#FFFF00(yellow)と混合すると、#FFA000が得られます(orange)。

したがって、このメソッドは期待どおりの結果を正確に生成します。

残念ながら、RGBからRYBに変換してRGBに戻すための「すぐに使える」式のリファレンスを見つけることができませんでした。

ペーパー 視覚化のためのペイントインスパイアードカラーミキシングとコンポジット-Gossett and Chen は、「2 ACHIEVING INTUTITIVE COLOR MIXING」のセクションでRYBカラーモデルの一般的な考え方を説明しています。

その論文によると、RYBからRGBへの変換は トリリニア補間 によって行われます。

トリリニア補間の反転が必要なため、難しい部分はRGBからRYBへの変換です。詳細は RGBとRYBの色空間間の変換 を参照してください。

この答えが計算の完全な公式を提供していなくても、私はそれが進む方法についていくつかのアイデアを与えることを願っています。

12
Martin R

2つのRGBカラーを混ぜようとしたときに、実際に同じ問題が発生しました。これらの2つの機能は私のために働きました:

//colorChannelA and colorChannelB are ints ranging from 0 to 255
function colorChannelMixer(colorChannelA, colorChannelB, amountToMix){
    var channelA = colorChannelA*amountToMix;
    var channelB = colorChannelB*(1-amountToMix);
    return parseInt(channelA+channelB);
}
//rgbA and rgbB are arrays, amountToMix ranges from 0.0 to 1.0
//example (red): rgbA = [255,0,0]
function colorMixer(rgbA, rgbB, amountToMix){
    var r = colorChannelMixer(rgbA[0],rgbB[0],amountToMix);
    var g = colorChannelMixer(rgbA[1],rgbB[1],amountToMix);
    var b = colorChannelMixer(rgbA[2],rgbB[2],amountToMix);
    return "rgb("+r+","+g+","+b+")";
}

赤([255,0,0])と青([0,0,255])を均等に混ぜるには、

colorMixer([255,0,0], [0,0,255], 0.5);//returns "rgb(127,0,127)" (purple)

最初に各カラー値を配列に変換する必要がありますが、これは役立つ場合があります。 Fabric.jsを使用してキャンバス要素を操作する場合、これは非常に簡単になります。電話するだけ

var rgbA = new fabric.Color(yourColor);
var rgbB = new fabric.Color(yourSecondColor);

次に電話します

colorMixer(rgbA.getSource(),rgbB.getSource(),0.5);

これらの機能がお役に立てば幸いです。

6
Aaron Harris

CIELABカラーを使用すると、LABカラースペースの2つのカラーのそれぞれに3つの座標があります。 (ちなみに、これまでのところ素晴らしい仕事です)。 LABスペースの2つのポイントを結ぶ仮想の線分の3次元の中点を見つけることが、最も効果的で実装が最も簡単な方法です。これは、平均L、平均a、平均bの2つの色の各コンポーネントを平均するだけで簡単に実行できます。次に、変換を逆にして、この色をRGB空間に変換し直します(照明空間が両方の方向で同じであることを確認してください)。

新しい色がRGB色空間外にある可能性があります。この場合、最も近い可視色にクリップすることを決定できます。 (ブルースは特にこれに対して脆弱です)。

4
Plynx

LAB(またはL * a * b *)形式の2つの色が揃ったので、それらを一緒に平均化できます。

L(result) = L(first color) + L(second color) / 2
A(result) = A(first color) + A(second color) / 2
B(result) = B(first color) + B(second color) / 2

もう知ってますよね?これは、元のRGBカラーを平均化するために行っていたためです。

3
Quuxplusone

this を使用してRGBをCMYKに変換し、次に:

// CMYK colors
colorA = [2, 90, 94, 0];
colorB = [4, 0, 80, 0]; 

colorMixC = (colorA[0] + colorB[0]) / 2;
colorMixM = (colorA[1] + colorB[1]) / 2;
colorMixY = (colorA[2] + colorB[2]) / 2;
colorMixK = (colorA[3] + colorB[3]) / 2;

そして最後に this を使用してCMYKをRGBに変換します

1
Jordan

ここに私がCIE-LCh色空間での色混合について書いた優れた記事があります。これは、あなたの目の知覚と一致する方法で色相、彩度、および輝度を維持する混合を生成します。

改善されたカラーブレンディング

1
Stu

ペイントする要素を作成します。

<DIV ID="SWATCH" STYLE="HEIGHT:50PX;WIDTH:50PX;"></DIV>

組み合わせたいRGBカラーを配列に配置します(好きなだけ):

var colourArray=['#012345','#6789AB','#CDEFED','#CBA987','#654321'];

次に、文字を数字に変換し、順番にトラップします。

var tempString=[],convertedColourArray=[];
for(i=0;i<colourArray.length;i++){
    for(x=1;x<=6;x++){
        var oldPigment=colourArray[i].charAt(x);
        if(oldPigment<=9)tempString.Push(oldPigment);
        if(oldPigment=='A')tempString.Push(10);
        if(oldPigment=='B')tempString.Push(11);
        if(oldPigment=='C')tempString.Push(12);
        if(oldPigment=='D')tempString.Push(13);
        if(oldPigment=='E')tempString.Push(14);
        if(oldPigment=='F')tempString.Push(15);}
    convertedColourArray.Push(tempString);
    tempString=[];}

次に、各インデックス位置番号を一緒に追加します。

var colourTotal=0,newColour='#';
for(i=0;i<=5;i++){
    for(x=0;x<convertedColourArray.length;x++)colourTotal+=parseFloat(convertedColourArray[x][i]);

最後に、新しい数値を取得して、一致する文字に変換し、newColour変数に追加します。

    var newPigment=(Math.floor(colourTotal/colourArray.length));
    if(newPigment<=9)newColour+=newPigment;
    if(newPigment==10)newColour+='A';
    if(newPigment==11)newColour+='B';
    if(newPigment==12)newColour+='C';
    if(newPigment==13)newColour+='D';
    if(newPigment==14)newColour+='E';
    if(newPigment==15)newColour+='F';
    colourTotal=0;}

これで、新しい色で好きなようにペイントできます。

    document.getElementById('SWATCH').style.backgroundColor=newColour;

私はこれが助けになり、それに自由に卵を投げることを自由に願っています:)

0
Howard

[〜#〜] cmy [〜#〜]または[〜#〜] rgb [〜#〜]カラーモデルを使用する必要があります。

Blue + YellowGrayにならないのはなぜですか?

Blue + Yellow =(Cyan + Magenta)+ Yellow => Gray。何故なの?

これを見てください。

したがって、RGB(CMY)を使用して色を混合できます。

0
Pylyp