我正在寻找一种库/算法/技术来获取 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
.
加法混合(光源)
选择一种颜色
c1
为了能够混合到
c0
,c1
必须小于或等于每个 channel 基础上的c0
。因此,例如随机较小的颜色:r1 = Random(r0); g1 = Random(g0); b1 = Random(b0);
计算缺失的颜色
c2
简单地使用加法逻辑:
c0 = c1 + c2
所以
c2 = c0 - c1 r2 = r0 - r1 g2 = g0 - g1 b2 = b0 - b1
减法混合(滤镜、油漆颜色)
选择一种颜色
c1
这次
c1
必须是c1>=c0
所以再次随机这样的颜色示例:r1 = r0 + Random(255-r0); g1 = g0 + Random(255-g0); b1 = b0 + Random(255-b0);
计算缺失的颜色
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;
}
//---------------------------------------------------------------------------
这里是截图:
代码中唯一重要的东西是 sb_rgbChange
事件,它会在 3 个滚动条中的任何一个发生变化时调用。它计算加法和减法逻辑的 c1,c2
颜色,并将颜色输出到面板中。
它没有任何问题......顺便说一句,即使我的 Random(x)
生成 x
所以限制应该是 255(我已经修复了答案) .
这里是完整的源代码(BDS2006 C++/VCL/Win32)和Win32二进制文件:
关于javascript - 查找哪两种颜色混合形成第三种颜色的算法(在 JavaScript 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56454340/