使用 "hue" 混合模式混合两种不透明的颜色
Mix two non-opaque colors with "hue" blend mode
我想实现 W3C compositing and blending spec 中描述的颜色混合。 (我在 JavaScript 中这样做,但语言对于解决我的问题应该无关紧要。)
回想起来:在回答这个问题的过程中,我意识到这可能会成为一个相当不错的独立包。如果您有兴趣,可以 grab it from npm.
到目前为止效果还不错,但我想进一步改进这些算法并添加对 alpha 通道的支持。感谢 SVG compositing spec 提供了所有需要的公式,这并不难。
但现在我坚持实施 W3C 规范描述为 non-separable 的混合模式(从 Photoshop 中得知):hue、饱和度、颜色和亮度。
遗憾的是,这些算法在 SVG 规范中不可用,我不知道如何使用这些算法。我想有一个修改版本的 the formulas provided by the W3C 用于处理我所缺少的 alpha 通道。
为了使我的问题更加直观,我将展示 Photoshop 为我提供的 hue 混合两种颜色的功能:
这也是我能够使用上述 W3C 规范中的非 alpha 算法重现的内容。
我无法重现的是当我在源颜色和背景颜色上都设置较低的 alpha 时 Photoshop 给我的结果:
有谁知道如何以编程方式实现该结果?
更新 1: 更改了插图(添加 HSVA 和 RGBA 代码)以阐明使用的颜色。
更新 2: 为了检查可能的解决方案,我将附上另外两个 Photoshop 生成的混合示例:
更新 3: 所以事实证明,除了对颜色混合一无所知之外,我还 ,这使得解决我的问题的任务更加困难.修复了未来可能的路人的示例图像。
从这里开始
Hue blending creates a color with the hue of the source color and the saturation and luminosity of the backdrop color.
我可以想出一些公式,但它们可能是垃圾,尽管它们完全复制了发布的原始数字:
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 始终匹配
第二张图片中的 Hue alpha 不 代表 alpha 颜色合成公式,而是反映 Porter Duff alpha composition Source Over as defined here 9.1.4. Source Over 并且它使用以下公式:
如果你想实现那种混合,这不是正确的色调混合,你可以在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 rgba
// B : the backdrop rgba
// aR : the union alpha (as + ab * (1 - as))
带 Alpha 通道的色调混合模式
这是使用我在 Photoshop 中创建的 alpha 颜色合成公式在背景上精确混合源的屏幕截图:
带有绿色突出显示字母的中间方块是正确的混合表示。这是 CSS Hue mix 与背景颜色中的源颜色混合,使用新的 CSS mix-blend-mode
(运行 代码片段):
.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);
}
<div id="main">
<div class="blends alpha">
<div class="backdrop alpha">
<div class="source alpha"></div>
</div>
</div>
</div>
如果您使用颜色选择器,您将获得几乎相同的值 (211, 214, 140 <> 210, 214, 140
)。这可能是由于略有不同的算法或不同的舍入方法,但这并不重要。事实上,这是使用色调混合模式混合 alpha 颜色时的正确结果。
因此,现在我们需要公式为应用于色调混合模式的 alpha 颜色合成提供正确的颜色值。我搜索了一下,在 Adobe Document management - Portable document format - Part 1: PDF 1.7 中找到了所有内容。我们可以在Blend Modes:[=26=之后的328页面找到color composition formula ]
11.3.6 Interpretation of Alpha
The colour compositing formula
这是我设法为带 alpha 通道的色相混合模式获得正确且更接近 Photoshop 匹配的公式。我在javascript:
中是这样写的
function Union(ab, as) {
return as + ab * (1 - as);
}
function colourCompositingFormula(as, ab, ar, Cs, Cb, Bbs) {
return (1 - (as / ar)) * Cb + (as / ar) * Math.floor((1 - ab) * Cs + ab * Bbs);
}
var aR = Union(B.a, S.a); // αr = Union(αb, αs) // Adobe PDF Format Part 1 - page 331
var 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 rgba
// B : the backdrop rgba
// aR : the union alpha (as + ab * (1 - as))
// Ca : the final result
body {
padding:0;
margin:0;
}
iframe {
width: 100%;
height: 200px;
border:0;
padding:0;
margin:0;
}
<iframe src="https://zikro.gr/dbg/html/blending-modes/"></iframe>
可以找到我的测试示例here。在 2.5 With Alpha(计算出的色调混合算法),您可以看到带有 alpha 的最终色调混合模式结果。它的值与 Photoshop 结果略有不同,但我在 Fireworks 中得到了完全相同的结果 (202, 205, 118
),色调混合了源颜色和背景颜色:
所有应用程序都有自己的略有不同的算法,也许我使用的公式很旧,也许有最新版本。
我想实现 W3C compositing and blending spec 中描述的颜色混合。 (我在 JavaScript 中这样做,但语言对于解决我的问题应该无关紧要。)
回想起来:在回答这个问题的过程中,我意识到这可能会成为一个相当不错的独立包。如果您有兴趣,可以 grab it from npm.
到目前为止效果还不错,但我想进一步改进这些算法并添加对 alpha 通道的支持。感谢 SVG compositing spec 提供了所有需要的公式,这并不难。
但现在我坚持实施 W3C 规范描述为 non-separable 的混合模式(从 Photoshop 中得知):hue、饱和度、颜色和亮度。
遗憾的是,这些算法在 SVG 规范中不可用,我不知道如何使用这些算法。我想有一个修改版本的 the formulas provided by the W3C 用于处理我所缺少的 alpha 通道。
为了使我的问题更加直观,我将展示 Photoshop 为我提供的 hue 混合两种颜色的功能:
这也是我能够使用上述 W3C 规范中的非 alpha 算法重现的内容。
我无法重现的是当我在源颜色和背景颜色上都设置较低的 alpha 时 Photoshop 给我的结果:
有谁知道如何以编程方式实现该结果?
更新 1: 更改了插图(添加 HSVA 和 RGBA 代码)以阐明使用的颜色。
更新 2: 为了检查可能的解决方案,我将附上另外两个 Photoshop 生成的混合示例:
更新 3: 所以事实证明,除了对颜色混合一无所知之外,我还
从这里开始
Hue blending creates a color with the hue of the source color and the saturation and luminosity of the backdrop color.
我可以想出一些公式,但它们可能是垃圾,尽管它们完全复制了发布的原始数字:
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 始终匹配
第二张图片中的 Hue alpha 不 代表 alpha 颜色合成公式,而是反映 Porter Duff alpha composition Source Over as defined here 9.1.4. Source Over 并且它使用以下公式:
如果你想实现那种混合,这不是正确的色调混合,你可以在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 rgba
// B : the backdrop rgba
// aR : the union alpha (as + ab * (1 - as))
带 Alpha 通道的色调混合模式
这是使用我在 Photoshop 中创建的 alpha 颜色合成公式在背景上精确混合源的屏幕截图:
带有绿色突出显示字母的中间方块是正确的混合表示。这是 CSS Hue mix 与背景颜色中的源颜色混合,使用新的 CSS mix-blend-mode
(运行 代码片段):
.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);
}
<div id="main">
<div class="blends alpha">
<div class="backdrop alpha">
<div class="source alpha"></div>
</div>
</div>
</div>
如果您使用颜色选择器,您将获得几乎相同的值 (211, 214, 140 <> 210, 214, 140
)。这可能是由于略有不同的算法或不同的舍入方法,但这并不重要。事实上,这是使用色调混合模式混合 alpha 颜色时的正确结果。
因此,现在我们需要公式为应用于色调混合模式的 alpha 颜色合成提供正确的颜色值。我搜索了一下,在 Adobe Document management - Portable document format - Part 1: PDF 1.7 中找到了所有内容。我们可以在Blend Modes:[=26=之后的328页面找到color composition formula ]
11.3.6 Interpretation of Alpha
The colour compositing formula
这是我设法为带 alpha 通道的色相混合模式获得正确且更接近 Photoshop 匹配的公式。我在javascript:
中是这样写的function Union(ab, as) {
return as + ab * (1 - as);
}
function colourCompositingFormula(as, ab, ar, Cs, Cb, Bbs) {
return (1 - (as / ar)) * Cb + (as / ar) * Math.floor((1 - ab) * Cs + ab * Bbs);
}
var aR = Union(B.a, S.a); // αr = Union(αb, αs) // Adobe PDF Format Part 1 - page 331
var 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 rgba
// B : the backdrop rgba
// aR : the union alpha (as + ab * (1 - as))
// Ca : the final result
body {
padding:0;
margin:0;
}
iframe {
width: 100%;
height: 200px;
border:0;
padding:0;
margin:0;
}
<iframe src="https://zikro.gr/dbg/html/blending-modes/"></iframe>
可以找到我的测试示例here。在 2.5 With Alpha(计算出的色调混合算法),您可以看到带有 alpha 的最终色调混合模式结果。它的值与 Photoshop 结果略有不同,但我在 Fireworks 中得到了完全相同的结果 (202, 205, 118
),色调混合了源颜色和背景颜色:
所有应用程序都有自己的略有不同的算法,也许我使用的公式很旧,也许有最新版本。