【问题标题】:Algorithm to find which two colors mix to form a third color (in JavaScript)找出哪两种颜色混合形成第三种颜色的算法(在 JavaScript 中)
【发布时间】:2019-10-20 14:25:42
【问题描述】:

我正在寻找一个库/算法/技术来获取 3 种加法或减法颜色,并确定两种颜色中的 combination 中的哪一种颜色 x

这不是一个正确的例子(因为我对色彩理论还不太了解),但这是为了说明这一点。假设你有一种像绿棕色#45512b 这样的颜色。要解决的问题是找出 - 对于两个系统(加法和减法) - 将生成绿棕色(给定颜色)的颜色对。

所以你有值“绿褐色”#45512b,并且想知道什么颜料混合在一起形成这种颜色。也许是#fff123#bbb456 减法结合形成绿褐色(只是弥补)。然后进行加色混合,找出计算模型中使用的 3 种基色光的两种光度,它们结合起来形成绿棕色。

基本上就是在找这个:

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

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

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

我可以想象的一种天真的方法是采用reverse algorithm(将两种颜色混合为第三种颜色的算法),并尝试每种颜色组合,直到找到合适的颜色。但这将是超级低效的,想知道是否有更好的方法或标准技术。

【问题讨论】:

  • 我是否遗漏了一些东西,但难道没有多种颜色可以添加到单一颜色中吗?
  • 无论如何 - xolor 对你有用吗?
  • 我不知道大声笑,但我可以看到。
  • 不错!它有:“ xolorObject.add(otherColor) - 返回两种颜色的加法混合。xolorObject.subtractive(otherColor) - 返回两种颜色的减法混合。”但是,仍然是同样的问题,如何进行该操作的reverse
  • 唉,它没有我要找的功能:/

标签: javascript algorithm colors color-theory


【解决方案1】:

使用 RGB 颜色模型。我假设您每个通道颜色为 8 位 c0=(r0,g0,b0) 并想知道 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;
    }
//---------------------------------------------------------------------------

这里是截图:

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

它没有任何问题......顺便说一句,即使我的Random(x) 生成x,所以限制应该是 255(我已经修复了答案)。

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

【讨论】:

  • 天哪,我不认为这是可能的!我要花一点时间来消化这个!谢谢。
  • 想知道你是否可以在更高的层次上解释它是如何工作的:)。所以这就是说你可以混合任何两种颜色,它会形成第三种颜色?
  • @LancePollard 其简单的线性方程 ...A + B = CA - B = C 的概念是 A,B,C 不能为负,这就是为什么您需要选择 A 作为较低或较大的颜色比目标一C。 Appart 您可以选择任何 A 并计算 B,以便它们结合到 C。
  • 想知道我是否做对了:jsfiddle.net/oh3bpcgw/1。主要想知道使用 255 而不是 256 是否是正确的选择。
  • 我也想知道我是否可以说,“好的,我想弄清楚是什么 2 种颜色生成 x,我希望其中一个组件/颜色是这个特定的蓝色,所以另一个必须是 y ",或者只有我可以选择的颜色子集(即startingWith 值)。
猜你喜欢
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 2023-01-10
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
相关资源
最近更新 更多