我正在尝试计算satMod(饱和度调制),如下所示:
<a:srgbClr val="58CAFF">
<a:satMod="300000"/>
</a:srgbClr>
EMCA-376规范的第20.1.2.3.27节说&lt; satMod&gt; element:“此元素指定输入颜色,其饱和度由给定百分比调制.50%饱和度调制将饱和度降低一半.200%饱和度调制使饱和度加倍。”
我遇到的问题是,许多颜色已经足够饱和,使饱和度增加300%(其中300000对应于300%)超出了0-100%的范围。我一直只是将饱和度限制在100%,但我的结果与Excel的结果非常不同。
在饱和度应该溢出的情况下,似乎有一些特殊的魔法发生。有人知道Office / Excel在这种情况下做了什么吗?
我在这里找到了基本相同的问题:http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/040e0a1f-dbfe-4ce5-826b-38b4b6f6d3f7
答案表明srgb颜色首先应转换为线性rgb,然后在修改饱和度之前转换为hsl。对我来说还没有解决问题。
答案 0 :(得分:2)
那是我问过这个原始问题。我已经弄清楚了。使用单一颜色转换(satMod
,redMod
,lumMod
等),您必须将值限制在sRGB 0,0,0或255,255,255(或1.0,1.0, 1.0)。这意味着如果您的satMod
将颜色修改了300%并且结果的颜色值大于255,则将其钳制为255(或1.0)。使用生成的颜色,您可以应用其他颜色变换(如果它们位于您的颜色srgbClr
或其他颜色空间中。
这就是我在像你这样的例子中所做的。
将颜色转换为HSL空间(这些RGB-&gt; HSL例程在Bing / Google上常见)。
以这种颜色发送,satMod
发送到这样的例程:
Public Sub modulateHSL(ByVal c As HSL, ByVal val As System.Double)
Select Case c
Case HSL.Hue
Hue = Hue * val
If Hue = 0.0 Then
If val >= 1.0 Then
Hue = val - Fix(val)
End If
Else
Hue = Hue - Fix(Hue)
End If
Case HSL.Saturation
Saturation = Saturation * val
Case HSL.Luminance
Luminance = Luminance * val
End Select
HSL_To_sRGB(Hue, Saturation, Luminance)
Clamp_sARGB()
End Sub
在此例程结束时,您会注意到两个电话:1)HSL_To_sRGB(Hue, Saturation, Luminance)
和2)Clamp_sARGB()
。第一个转换回sRGB空间,第二个转换RGB值,如下所示:
Public Sub Clamp_sARGB()
If Red <= 0.0 Then Red = 0.0 Else If Red >= 1.0 Then Red = 1.0
If Green <= 0.0 Then Green = 0.0 Else If Green >= 1.0 Then Green = 1.0
If Blue <= 0.0 Then Blue = 0.0 Else If Blue >= 1.0 Then Blue = 1.0
If Alpha <= 0.0 Then Alpha = 0.0 Else If Alpha >= 1.0 Then Alpha = 1.0
sRGB_To_HSL(Red, Green, Blue)
End Sub
请注意,在仅修改饱和度的情况下,无需使用线性RGB。我在类级别字段(0-1空间中的RGB)中维护RBG和HSL空间,这就是为什么在该例程结束时看到sRGB_To_HSL(Red, Green, Blue)
的原因。
现在这适用于PowerPoint中出现的DrawingML。 Excel可能有所不同(有一个很长的线程here处理可能也有你的答案的图表)。请记住,修改饱和度还可以根据您对例程的编码方式修改亮度。如果是这种情况,则在从HSL转换回RGB时,您将需要使用原始亮度。
如果这些都不适合您,您可以在上面放一个示例XLSX吗? DropBox指出正在发生的事情,你期待的事情等等?