問題:JavaScriptで2つの色を混ぜて、結果の色を取得したい。 SOにも同様の質問がたくさんありますが、実際に正しく機能するものは見つかりません。 2つの異なるカラーペイント(顔料)とライトを混合すると、結果が大きく異なることを知っています( http://en.wikipedia.org/wiki/Color_mixing )。
これは、私がすでに見て、実装しようとした質問と提案された解決策です:
1:2つのRGBカラーベクトルを混合して結果を得る
そのため、RGBで色を混合します。私はそれを実装しましたが、場合によっては機能しません。
使用例:red
とyellow
を混在させる-> orange
。すごい!
http://jsbin.com/afomim/1/edit
動作しない例:blue
とyellow
を混在させる-> gray
。あまりよくない! :) http://jsbin.com/afomim/5/edit
RGBでは、blue
とyellow
を混合してもgreen
が作成されないことを知っています。その理由も理解しています。
ここでは答えが見つかりません。先に進みましょう。
このディスカッションで提案されているように、CMYK値を操作してみましょう。 cyan
とyellow
を混在させると、green
が得られます。
http://jsbin.com/igaveg/1/edit
ただし、blue
とyellow
を混在させると、black
になります。
http://jsbin.com/igaveg/2/edit ->機能していません!
3:C#で「自然に」色を混ぜる方法
非常によく似た質問。最も賛成の回答は、色をLABに変換することを提案しており、このソリューションは有望であるようです。
そこで、色をLABに変換しました。変換アルゴは正しいです、私はそれをテストしました!
http://jsbin.com/oxefox/1/edit
LABに2つの色がありますが、それらをどのように混合するのですか?
[〜#〜]注[〜#〜]多分、blue
とyellow
を混合し、完全なgreen
を与えるアルゴが見つからないことを知っています、しかし私は私が緑に似たものを生成できることを願っています:)
この質問には3〜4日を費やしました。それは本当に複雑な問題です。
2つの色を「自然に」混合したい場合にできることは次のとおりです。
CMYKミキシング:これは完璧な解決策ではありませんが、今すぐ解決策が必要で、テーマについての学習、実験、コーディングに何ヶ月も費やしたくない場合は、これを確認してください: https:// github.com/AndreasSoiron/Color_mixer
Kubelka-Munk理論の実装。私はそれについて多くの時間を読み、それを理解しようとしました。これは、プロフェッショナルなソリューションが必要な場合に最適な方法ですが、混合する各色について6つのパラメーター(反射率、吸収など)が必要です。 R、G、Bがあるだけでは十分ではありません。理論の実装は難しくありませんが、各色について必要なパラメーターを取得することは、欠けている部分のようです。あなたがそれを行う方法を理解したら、私に知らせてください:)
実験的:ipadアプリの開発者が行うことを行うことができます: Paper 彼らは手動で人気のある色の100ペアを選択し、それらがどのようにブレンドすべきかを眼球でテストしました。詳しくはこちら こちら 。
個人的には今のところCMYKミキシングを実装しますが、多分後で、時間があればフィフティスリーのようなものを作ろうと思います。見るでしょう:)
RYBカラーモデルは、カラーミキシングの計算に適しています。 Wikipedia によると、これは主に芸術とデザインの教育、特に絵画で使用されています。
2つの色を混合するには、両方の色をRGBからRYBに変換し、各色成分を追加して色を混合し、結果の色をRYBからRGBに変換します。
Online Color Mixing Tool を使用してこれを試しましたが、結果は
したがって、このメソッドは期待どおりの結果を正確に生成します。
残念ながら、RGBからRYBに変換してRGBに戻すための「すぐに使える」式のリファレンスを見つけることができませんでした。
ペーパー 視覚化のためのペイントインスパイアードカラーミキシングとコンポジット-Gossett and Chen は、「2 ACHIEVING INTUTITIVE COLOR MIXING」のセクションでRYBカラーモデルの一般的な考え方を説明しています。
その論文によると、RYBからRGBへの変換は トリリニア補間 によって行われます。
トリリニア補間の反転が必要なため、難しい部分はRGBからRYBへの変換です。詳細は RGBとRYBの色空間間の変換 を参照してください。
この答えが計算の完全な公式を提供していなくても、私はそれが進む方法についていくつかのアイデアを与えることを願っています。
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);
これらの機能がお役に立てば幸いです。
CIELABカラーを使用すると、LABカラースペースの2つのカラーのそれぞれに3つの座標があります。 (ちなみに、これまでのところ素晴らしい仕事です)。 LABスペースの2つのポイントを結ぶ仮想の線分の3次元の中点を見つけることが、最も効果的で実装が最も簡単な方法です。これは、平均L
、平均a
、平均b
の2つの色の各コンポーネントを平均するだけで簡単に実行できます。次に、変換を逆にして、この色をRGB空間に変換し直します(照明空間が両方の方向で同じであることを確認してください)。
新しい色がRGB色空間外にある可能性があります。この場合、最も近い可視色にクリップすることを決定できます。 (ブルースは特にこれに対して脆弱です)。
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カラーを平均化するために行っていたためです。
ここに私がCIE-LCh色空間での色混合について書いた優れた記事があります。これは、あなたの目の知覚と一致する方法で色相、彩度、および輝度を維持する混合を生成します。
ペイントする要素を作成します。
<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;
私はこれが助けになり、それに自由に卵を投げることを自由に願っています:)
[〜#〜] cmy [〜#〜]または[〜#〜] rgb [〜#〜]カラーモデルを使用する必要があります。
Blue
+ Yellow
がGray
にならないのはなぜですか?
Blue
+ Yellow
=(Cyan
+ Magenta
)+ Yellow
=> Gray
。何故なの?
したがって、RGB(CMY)を使用して色を混合できます。