【问题标题】:Office Open XML satMod results in more than 100% saturationOffice Open XML satMod 导致超过 100% 的饱和度
【发布时间】:2011-07-26 15:20:56
【问题描述】:

我正在尝试计算类似以下内容的 satMod(饱和调制):

<a:srgbClr val="58CAFF">
    <a:satMod="300000"/>
</a:srgbClr>

EMCA-376 规范的第 20.1.2.3.27 节提到了 元素:“该元素指定输入颜色,其饱和度由给定百分比调制。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。对我来说还没有解决问题。

【问题讨论】:

    标签: excel ms-office openxml drawingml


    【解决方案1】:

    那是我提出最初的问题。从那以后我就明白了。对于单一颜色转换(satModredModlumMod 等),您必须将值限制在 sRGB 0,0,0 或 255,255,255(或 1.0,1.0,1.0)内。这意味着如果您的satMod 将您的颜色修改了 300% 并且结果是颜色值高于 255,则将其限制为 255(或 1.0)。使用生成的颜色,如果它们在您的颜色 srgbClr 或其他颜色空间中,您可以应用其他颜色变换。

    这就是我在像你这样的例子中所做的。

    1. 将颜色转换为 HSL 空间(这些类型的 RGB->HSL 例程在 Bing/Google 上很常见)。

    2. 将该颜色和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
      
    3. 在此例程结束时,您会注意到两个调用 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。我在类级别字段中同时维护 RBG 和 HSL 空间(RGB 在 0-1 空间中),这就是为什么您会在该例程的末尾看到 sRGB_To_HSL(Red, Green, Blue)

    现在这是用于在 PowerPoint 中显示的 DrawingML。 Excel 可能有所不同(有一个冗长的线程here 处理可能也有您的答案的图表)。请记住,根据您编写程序的方式,修改饱和度也可以修改亮度。如果是这种情况,在从 HSL 转换回 RGB 时,您需要使用原始亮度。

    如果这些都不适合您,您能否将示例 XLSX 放在 DropBox 指出正在发生的事情、您的期望等?

    【讨论】:

    • 很好的分析。除了规范之外,有时(尽管在这种特殊情况下不是)有用的是微软的实施者说明,可在此处获得:msdn.microsoft.com/en-us/library/ee908652.aspx
    • @0xA3:完全同意,这是一个很好的资源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    相关资源
    最近更新 更多