“混合两种颜色”;自然地;在javascript中

“混合两种颜色”;自然地;在javascript中,javascript,math,colors,color-scheme,Javascript,Math,Colors,Color Scheme,问题:我想在javascript中混合两种颜色,然后得到结果颜色。 有很多类似的问题,所以,但我没有发现任何实际工作的正确。我知道混合两种不同颜色的颜料(颜料)和灯光会产生非常不同的结果() 以下是我已经看到并尝试实施的问题和建议的解决方案: 1: 所以,在RGB中混合颜色。我实现了它,在某些情况下它是有效的,但在某些情况下它不是 工作示例:将红色与黄色->橙色混合。太好了 不工作示例:将蓝色与黄色->灰色混合。不太好!:) 我知道在RGB中,将蓝色与黄色混合永远不会变成绿色,我理解原因 我

问题:我想在javascript中混合两种颜色,然后得到结果颜色。 有很多类似的问题,所以,但我没有发现任何实际工作的正确。我知道混合两种不同颜色的颜料(颜料)和灯光会产生非常不同的结果()

以下是我已经看到并尝试实施的问题和建议的解决方案:

1:
所以,在RGB中混合颜色。我实现了它,在某些情况下它是有效的,但在某些情况下它不是

工作示例:
红色
黄色
->
橙色
混合。太好了

不工作示例:
蓝色
黄色
->
灰色
混合。不太好!:)
我知道在RGB中,将
蓝色
黄色
混合永远不会变成
绿色
,我理解原因

我们在这里找不到答案,让我们继续

2:

让我们尝试使用本讨论中建议的CMYK值。将
青色
黄色
混合会得到
绿色


但将
蓝色
黄色
混合会产生
黑色

->不行

3:
一个非常相似的问题。投票最多的答案建议将颜色转换为实验室颜色,这个解决方案似乎很有希望。
所以我把我的颜色转换到实验室。转换算法是正确的,我测试了它

现在我在实验室里有了这两种颜色,但是如何混合它们呢


注意我知道我可能找不到一个将
蓝色
黄色
混合的算法,它会给出完美的
绿色
,但我希望我能生成类似于绿色的东西:)

既然你有了实验室(或L*a*b*)格式的两种颜色,你可以将它们平均起来

L(result) = L(first color) + L(second color) / 2
A(result) = A(first color) + A(second color) / 2
B(result) = B(first color) + B(second color) / 2

你早就知道了,对吧?因为这是您对原始RGB颜色所做的平均值。

对于CIELAB颜色,您在实验室颜色空间中的两种颜色各有三个坐标。(顺便说一句,在这方面做得很好)。对您来说,最有效、最容易实现的方法是在实验室空间中找到连接两个点的虚拟线段的三维中点。只需对两种颜色的每个组成部分取平均值即可轻松做到这一点:平均值
L
、平均值
a
和平均值
b
。然后通过反转变换将此颜色转换回RGB空间(确保两种方式的照明空间保持相同)


新颜色可能在RGB颜色空间之外。在这种情况下,您可以决定剪裁为最接近的可见颜色。(蓝色特别容易受到此影响)。

RYB颜色模型可能是颜色混合计算的合适选择。 据介绍,它主要用于艺术和设计教育,尤其是绘画

要混合2种颜色,可以将两种颜色从RGB转换为RYB,通过添加每种颜色来混合颜色 颜色组件,并将结果颜色从RYB转换回RGB

我已经尝试了使用,结果是

  • 0000FF(蓝色)与#FFFF00(黄色)混合,得到#008000(深绿色),
  • FF0000(红色)与#FFFF00(黄色)混合得到#FF000(橙色)。
因此,这种方法产生的结果正是您所期望的

不幸的是,我找不到一个带有“随时可用”公式的参考,无法将RGB转换为RYB并返回RGB

报纸 在“2实现直观的颜色混合”一节中介绍了RYB颜色模型的总体思路

根据那篇论文,从RYB到RGB的转换是通过

困难的部分是从RGB到RYB的转换,因为它需要反转 三线性插值。 看见 了解更多信息


即使这个答案没有提供完整的计算公式,我希望它能给我们提供一些思路。

我花了3-4天的时间来回答这个问题。这是一个非常复杂的问题

如果你想“自然”地混合两种颜色,你可以这样做:

  • CMYK mixing:这不是一个完美的解决方案,但如果您现在需要一个解决方案,并且您不想花费数月的时间来学习主题、实验和编码,您可以查看以下内容:

  • 实施库贝尔卡·芒克理论。我花了很多时间阅读,试图理解它。如果你想要一个专业的解决方案,这应该是最好的选择,但是对于你想要混合的每种颜色,它需要6个参数(如反射率、吸收率等)。拥有R,G,B是不够的。实现这一理论并不困难,但获得每种颜色所需的参数似乎是缺少的部分。如果你知道怎么做,请告诉我:)

  • 实验性:你可以做一些ipad应用程序开发者已经做过的事情。他们手工挑选了100对流行的颜色,并用眼球测试了它们应该如何混合。了解更多关于它的信息


  • 我个人将暂时实现CMYK混音,也许稍后,如果我有时间,我会尝试制作类似于Fiftythree的东西。将看到:)

    您需要使用CMYRGB颜色模型

    为什么
    蓝色
    +
    黄色
    不能是
    灰色

    蓝色
    +
    黄色
    =(
    青色
    +
    洋红色
    )+
    黄色
    =>
    灰色
    。为什么不呢


    因此,您可以使用RGB(CMY)来混合颜色。

    我写了一篇关于CIE LCh颜色空间中的颜色混合的好文章,这篇文章产生了一种保持色调、饱和度和亮度的混合
    // CMYK colors
    colorA = [2, 90, 94, 0];
    colorB = [4, 0, 80, 0]; 
    
    colorMixC = (colorA[0] + colorB[0]) / 2;
    colorMixM = (colorA[1] + colorB[1]) / 2;
    colorMixY = (colorA[2] + colorB[2]) / 2;
    colorMixK = (colorA[3] + colorB[3]) / 2;
    
    //colorChannelA and colorChannelB are ints ranging from 0 to 255
    function colorChannelMixer(colorChannelA, colorChannelB, amountToMix){
        var channelA = colorChannelA*amountToMix;
        var channelB = colorChannelB*(1-amountToMix);
        return parseInt(channelA+channelB);
    }
    //rgbA and rgbB are arrays, amountToMix ranges from 0.0 to 1.0
    //example (red): rgbA = [255,0,0]
    function colorMixer(rgbA, rgbB, amountToMix){
        var r = colorChannelMixer(rgbA[0],rgbB[0],amountToMix);
        var g = colorChannelMixer(rgbA[1],rgbB[1],amountToMix);
        var b = colorChannelMixer(rgbA[2],rgbB[2],amountToMix);
        return "rgb("+r+","+g+","+b+")";
    }
    
    colorMixer([255,0,0], [0,0,255], 0.5);//returns "rgb(127,0,127)" (purple)
    
    var rgbA = new fabric.Color(yourColor);
    var rgbB = new fabric.Color(yourSecondColor);
    
    colorMixer(rgbA.getSource(),rgbB.getSource(),0.5);
    
    <DIV ID="SWATCH" STYLE="HEIGHT:50PX;WIDTH:50PX;"></DIV>
    
    var colourArray=['#012345','#6789AB','#CDEFED','#CBA987','#654321'];
    
    var tempString=[],convertedColourArray=[];
    for(i=0;i<colourArray.length;i++){
        for(x=1;x<=6;x++){
            var oldPigment=colourArray[i].charAt(x);
            if(oldPigment<=9)tempString.push(oldPigment);
            if(oldPigment=='A')tempString.push(10);
            if(oldPigment=='B')tempString.push(11);
            if(oldPigment=='C')tempString.push(12);
            if(oldPigment=='D')tempString.push(13);
            if(oldPigment=='E')tempString.push(14);
            if(oldPigment=='F')tempString.push(15);}
        convertedColourArray.push(tempString);
        tempString=[];}
    
    var colourTotal=0,newColour='#';
    for(i=0;i<=5;i++){
        for(x=0;x<convertedColourArray.length;x++)colourTotal+=parseFloat(convertedColourArray[x][i]);
    
        var newPigment=(Math.floor(colourTotal/colourArray.length));
        if(newPigment<=9)newColour+=newPigment;
        if(newPigment==10)newColour+='A';
        if(newPigment==11)newColour+='B';
        if(newPigment==12)newColour+='C';
        if(newPigment==13)newColour+='D';
        if(newPigment==14)newColour+='E';
        if(newPigment==15)newColour+='F';
        colourTotal=0;}
    
        document.getElementById('SWATCH').style.backgroundColor=newColour;
    
    Return Color=SubtractiveMix(Color a, Color b, percentage)
    
    Color ColorMixSub(Color a, Color b, float blend) {
        Color out;
        Color c,d,f;
    
        c=ColorInv(a);
        d=ColorInv(b);
    
        f.r=max(0,255-c.r-d.r);
        f.g=max(0,255-c.g-d.g);
        f.b=max(0,255-c.b-d.b);
    
        float cd=ColorDistance(a,b);
        cd=4.0*blend*(1.0-blend)*cd;
        out=ColorMixLin(ColorMixLin(a,b,blend),f,cd);
    
        out.a=255;
    return out;
    }
    
        c=ColorInv(a);
        d=ColorInv(b);
    
        f.r=max(0,255-c.r-d.r);
        f.g=max(0,255-c.g-d.g);
        f.b=max(0,255-c.b-d.b);
    
    float cd=ColorDistance(a,b);
    
    cd=4.0*blend*(1.0-blend)*cd;
    
    out=ColorMixLin(ColorMixLin(a,b,blend),f,cd);`