将两种不透明的颜色混合在一起" hue"混合模式

时间:2016-11-25 02:26:04

标签: algorithm colors blending

我想实现W3C compositing and blending spec中描述的颜色混合。 (我在JavaScript中这样做,但语言不应该对解决我的问题非常重要。)

回想起来:在实现这个问题的答案期间,我意识到这可能会成为一个非常好的独立软件包。如果您有兴趣,可以grab it from npm

到目前为止效果还不错,但我想进一步采用这些算法并增加对alpha通道的支持。感谢SVG compositing spec提供了所有必需的公式,这些公式并不太难。

但是现在我仍然坚持实施W3C规范描述为non-separable的混合模式(从Photoshop中已知): hue 饱和度< / em>,颜色发光度

可悲的是,SVG规范中没有这些算法的算法,我不知道如何使用这些算法。我想有一个the formulas provided by the W3C的修改版本用于处理我错过的alpha通道。

为了使我的问题更具视觉效果,我将展示Photoshop为我提供的混合两种颜色 hue 的内容:

Photoshop hue blending example of two opaque colors

这也是我能够使用上述W3C规范中的非alpha算法重现的。

我能够重现的是当我在源和背景颜色上放置较低的alpha时Photoshop给我的结果:

Photoshop hue blending example of two colors with 60% opacity each

有谁知道如何以编程方式实现该结果?

更新1:更改插图(添加HSVA和RGBA代码)以澄清使用的颜色。

更新2:要检查可能的解决方案,我将附上另外两个Photoshop生成的混合示例:

Photoshop hue blending example of two colors with different opacity combinations

Photoshop hue blending example of two colors with different opacity combinations

更新3:事实证明,除了没有关于颜色混合的线索之外我还messed up my Photoshop settings,让任务更难以解决我的问题。修复了未来可能的路人的示例图片。

2 个答案:

答案 0 :(得分:11)

您在第二张图片中使用的Hue alpha不代表Alpha颜色合成公式,而是反映Porter Duff alpha composition Source Over ,如此处9.1.4. Source Over所定义的那样使用以下公式:

Source Over Formula

如果你想实现那种不适当的色调混合,你可以在javascript中使用以下公式:

PDso = { // Ported Duff Source Over
    r: ((S.r * S.a) + (B.r * B.a) * (1 - S.a)) / aR,
    g: ((S.g * S.a) + (B.g * B.a) * (1 - S.a)) / aR,
    b: ((S.b * S.a) + (B.b * B.a) * (1 - S.a)) / aR,
};

// where
// S : the source rgb
// B : the backdrop rgb
// aR : the union alpha (as + ab * (1 - as))

带Alpha通道的Hue混合模式

以下是使用我在Photoshop中创建的Alpha颜色合成公式在背景上的精确色调混合源的屏幕截图:

Photoshop Hue Blend Mode

带有绿色突出显示字母的中间正方形是正确的混合表示。以下是使用新CSS mix-blend-mode运行代码段)的CSS Hue混合与背景颜色中的源颜色混合:

&#13;
&#13;
.blends div {
    width:140px;
    height:140px;
}

.source {
    mix-blend-mode: hue;
}

.backdrop.alpha {
    background-color: rgba(141, 214, 214, .6);
    isolation: isolate;
}

.source.alpha {
    background-color: rgba(255, 213, 0, .6);
}
&#13;
<div id="main">
 
 <div class="blends alpha">
  <div class="backdrop alpha">
   <div class="source alpha"></div>
  </div>
 </div>

</div>
&#13;
&#13;
&#13;

如果您使用颜色选择器,您将获得几乎相同的值(211, 214, 140 <> 210, 214, 140)。这可能是由于略有不同的算法或不同的舍入方法,但它并不重要。事实是,这是将alpha颜色与色调混合模式混合时的正确结果。

因此,现在我们需要公式为应用于我们的色调混合模式的alpha颜色合成具有正确的颜色值。我搜索了一下,我在Adobe Document management - Portable document format - Part 1: PDF 1.7内找到了所有内容。我们可以在混合模式之后的 328 页面找到颜色合成公式

  

11.3.6解释Alpha

     

颜色合成公式

     

enter image description here

这是我设法通过alpha通道为Hue混合模式获得正确且更接近Photoshop匹配的公式。我在javascript中写了这样的话:

var

Union = function(ab, as) {
    return as + ab * (1 - as);
},

colourCompositingFormula = function(as, ab, ar, Cs, Cb, Bbs) {
    return (1 - (as / ar)) * Cb + (as / ar) * Math.floor((1 - ab) * Cs + ab * Bbs);
},

aR = Union(B.a, S.a), //αr = Union(αb, αs) // Adobe PDF Format Part 1 - page 331

Ca = {
    // Adobe PDF Format Part 1 - page 328
    r: colourCompositingFormula(S.a, B.a, aR, S.r, B.r, C.r),
    g: colourCompositingFormula(S.a, B.a, aR, S.g, B.g, C.g),
    b: colourCompositingFormula(S.a, B.a, aR, S.b, B.b, C.b)
}

// where
// C : the hue blend mode result rgb
// S : the source rgb
// B : the backdrop rgb
// aR : the union alpha (as + ab * (1 - as))
// Ca : the final result

&#13;
&#13;
body {
  padding:0;
  margin:0;
}

iframe {
  width: 100%;
  height: 200px;
  border:0;
  padding:0;
  margin:0;
}
&#13;
<iframe src="http://zikro.gr/dbg/html/blending-modes/"></iframe>
&#13;
&#13;
&#13;

我的测试示例可以找到here。在 2.5 with Alpha(Hue Blending Algorithm Computed),你可以看到最终的色调混合模式结果与alpha。它的值与Photoshop结果略有不同,但我在Fireworks中获得了完全相同的结果(202, 205, 118),色调混合了源和背景颜色:

Fireworks same result

所有应用程序都有自己略有不同的算法,也许我使用的公式相当陈旧,可能有最新版本。

答案 1 :(得分:2)

从这里开始

  

色调混合使用源颜色的色调以及背景色的饱和度和亮度创建颜色。

我可以提出一些公式,但它们可能是垃圾,尽管它们完全重现了发布的原始数字:

h :hSource + deltaH *(1 - aSrouce)* aBackdrop * 0.41666666 = 50; 63

s :sBackdrop * 0.9 + deltaS *(1 - aBackdrop)* aSource * 0.20833333 = 45; 47.5

l :lBackdrop * 0.957142857 + deltaL *(1 - aBackdrop)* aSource * 0.77 = 67; 63.3

a:1 - (1 - aSource)^ 2 始终匹配