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

标签 javascript algorithm colors color-theory

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

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

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

基本上只是在寻找这个:

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

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

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

我能想到的一种天真的方法是采用 reverse algorithm(将两种颜色混合成第三种颜色的算法),然后尝试每种颜色组合,直到找到正确的颜色。但这会非常低效,想知道是否有更好的方法或标准技术。

最佳答案

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

加法混合(光源)

  1. 选择一种颜色c1

    为了能够混合到 c0c1 必须小于或等于每个 channel 基础上的 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 个 sscrollbars 来选择目标颜色 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 颜色,并将颜色输出到面板中。

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

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

关于javascript - 查找哪两种颜色混合形成第三种颜色的算法(在 JavaScript 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56454340/

相关文章:

javascript - 将 JSON 对象从 JavaScript 传递到 Android

algorithm - 使用动态规划实现事件选择问题

java - 在 SD 卡上组织数据以便快速搜索的最佳方式

java - Robot 的 getPixelColor(int x, int y) 方法如何工作?

javascript - 在 Node.js 中单调增加时间

javascript - foreach() 触发 'Uncaught RangeError: Maximum call stack size exceeded'

javascript - 如何从外部访问 React 类方法?

algorithm - 找到使其覆盖二维空间中最大点的矩形位置

javascript - 在 JS 中,找到白色背景上不透明度为 0.5 的颜色?

html - 为什么 HTML 颜色名称规范中的 'green' 等同于 #008000?