我正在寻找一种采用三种加色或减色的库/算法/技术,并确定两种颜色中的x
的{{3}}中的什么。
这不是一个正确的示例(因为我对色彩理论还不太了解),但这只是为了说明这一点。假设您的颜色像是棕绿色#45512b
。对于两个系统(加法和减法),要解决的问题是,将产生绿褐色的一对颜色(给定的颜色)。
因此,您具有“棕绿色” #45512b
的值,并想知道哪些涂料混合在一起形成了这种颜色。也许是#fff123
和#bbb456
相减结合形成绿褐色(只是弥补了这一点)。然后进行加性混合,找出计算模型中使用的3种基本颜色的两种阴影组合起来,形成浅绿色。
基本上只是在寻找这个东西
function additiveComponents(color) {
return [ a, b ]
}
function subtractiveComponents(color) {
return [ a, b ]
}
输入颜色不需要为十六进制格式,任何combination都可以使用。但是最后,我想将两个输出值转换回十六进制值。
我能想到的一种幼稚的方法是采用color spaces(将两种颜色混合成第三种颜色的算法),并尝试每种颜色的组合,直到找到正确的颜色为止。但这会导致效率极低,想知道是否有更好的方法或标准技术。
答案 0 :(得分:1)
使用 RGB颜色模型。我假设您每个通道的颜色c0=(r0,g0,b0)
有8位,并且想知道c1,c2
混合回到c0
。
添加剂混合(光源)
选择一种颜色c1
要能够混合多达c0
,c1
必须小于或等于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个滚动条来选择目标颜色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
颜色,并将颜色输出到面板中。
它可以正常工作... btw您即使在我的Random(x)
生成x
的地方,因此限制应该为255(我已经修复了答案)。
这里有完整的源代码( BDS2006 C ++ / VCL / Win32 )和Win32二进制文件: