查找哪两种颜色混合形成第三种颜色的算法(在JavaScript中)

时间:2019-06-05 04:40:25

标签: javascript algorithm colors color-theory

我正在寻找一种采用三种加色或减色的库/算法/技术,并确定两种颜色中的x的{​​{3}}中的什么。

这不是一个正确的示例(因为我对色彩理论还不太了解),但这只是为了说明这一点。假设您的颜色像是棕绿色#45512b。对于两个系统(加法和减法),要解决的问题是,将产生绿褐色的一对颜色(给定的颜色)。

因此,您具有“棕绿色” #45512b的值,并想知道哪些涂料混合在一起形成了这种颜色。也许是#fff123#bbb456相减结合形成绿褐色(只是弥补了这一点)。然后进行加性混合,找出计算模型中使用的3种基本颜色的两种阴影组合起来,形成浅绿色。

基本上只是在寻找这个东西

function additiveComponents(color) {
  return [ a, b ]
}

function subtractiveComponents(color) {
  return [ a, b ]
}

输入颜色不需要为十六进制格式,任何combination都可以使用。但是最后,我想将两个输出值转换回十六进制值。

我能想到的一种幼稚的方法是采用color spaces(将两种颜色混合成第三种颜色的算法),并尝试每种颜色的组合,直到找到正确的颜色为止。但这会导致效率极低,想知道是否有更好的方法或标准技术。

1 个答案:

答案 0 :(得分:1)

使用 RGB颜色模型。我假设您每个通道的颜色c0=(r0,g0,b0)有8位,并且想知道c1,c2混合回到c0

添加剂混合(光源)

  1. 选择一种颜色c1

    要能够混合多达c0c1必须小于或等于c0(基于每个通道)。例如,随机的较小颜色:

    r1 = Random(r0);
    g1 = Random(g0);
    b1 = Random(b0);
    
  2. 计算缺少的颜色c2

    仅使用加法逻辑:

    c0 = c1 + c2
    

    如此

    c2 = c0 - c1
    
    r2 = r0 - r1
    g2 = g0 - g1
    b2 = b0 - b1
    

主观混合(滤镜,油漆颜色)

  1. 选择一种颜色c1

    这次c1必须为c1>=c0,所以再次随机选择这样的颜色示例:

    r1 = r0 + Random(255-r0);
    g1 = g0 + Random(255-g0);
    b1 = b0 + Random(255-b0);
    
  2. 计算缺少的颜色c2

    只需使用主逻辑:

    c0 = c1 - c2
    

    如此

    c2 = c1 - c0
    
    r2 = r1 - r0
    g2 = g1 - g0
    b2 = b1 - b0
    

[Edit1]示例

我刚刚编写了一个简单的C ++ / VCL应用程序进行测试。因此,我有3个滚动条来选择目标颜色c0的RGB,然后有一些面板显示c1,c2及其混合,以可视方式验证其正常工作。这里的代码:

//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "win_main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
const int _r=0; // channel order
const int _g=1;
const int _b=2;
const int _a=3;
union color
    {
    BYTE db[4]; // channel access
    DWORD dd;   // all 32 bit of color
    TColor c;   // VCL/GDI color  (you can ignore this)
    };
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
    {
    sb_rgbChange(this);
    }
//---------------------------------------------------------------------------
void __fastcall TForm1::sb_rgbChange(TObject *Sender)
    {
    int i;
    color c0,c1,c2,c;
    Randomize();
    // get c0 color from R,G,B sliders
    c0.db[_r]=255-sb_r->Position;
    c0.db[_g]=255-sb_g->Position;
    c0.db[_b]=255-sb_b->Position;
    c0.db[_a]=0;
    pan_c0->Color=c0.c;     // just show color on some panel
    // additive
    for (i=0;i<3;i++) c1.db[i]=Random(c0.db[i]);  c1.db[_a]=0;  // generate c1 <= c0
    for (i=0;i<3;i++) c2.db[i]=c0.db[i]-c1.db[i]; c2.db[_a]=0;  // compute c2 = c0 - c1
    for (i=0;i<3;i++)  c.db[i]=c1.db[i]+c2.db[i]; c.db[_a]=0;   // verify  c  = c1 + c2
    pan_add_c1->Color=c1.c; // just show colors on some panels
    pan_add_c2->Color=c2.c;
    pan_add_c ->Color= c.c;
    // substractive
    for (i=0;i<3;i++) c1.db[i]=c0.db[i]+Random(255-c0.db[i]); c1.db[_a]=0;  // generate c1 >= c0
    for (i=0;i<3;i++) c2.db[i]=c1.db[i]-c0.db[i];             c2.db[_a]=0;  // compute c2 = c1 - c0
    for (i=0;i<3;i++)  c.db[i]=c1.db[i]-c2.db[i];              c.db[_a]=0;  // verify  c  = c1 - c2
    pan_sub_c1->Color=c1.c; // just show colors on some panels
    pan_sub_c2->Color=c2.c;
    pan_sub_c ->Color= c.c;
    }
//---------------------------------------------------------------------------

这是屏幕截图:

screenshot

代码中唯一重要的内容是sb_rgbChange事件,在3个滚动条中的任何滚动条发生任何更改时都会调用该事件。它为加法和减法逻辑计算c1,c2颜色,并将颜色输出到面板中。

它可以正常工作... btw您即使在我的Random(x)生成x的地方,因此限制应该为255(我已经修复了答案)。

这里有完整的源代码( BDS2006 C ++ / VCL / Win32 )和Win32二进制文件: