与 HSL 之间的线性 RGB 转换

发布于 2024-08-05 12:01:04 字数 2298 浏览 1 评论 0原文

有谁知道如何从 LinearRGB 颜色(不是 sRGB 颜色)获取 HSL?我见过很多 sRGB<->HSL 转换,但没有看到过 LinearRGB<->HSL 的转换。不确定它是否在本质上是相同的转换,只是做了一些细微的调整,但我很感激有人对此有任何见解。

线性 RGB 与线性化 sRGB 不同(线性化 sRGB 取 [0,255] 并使其变为 [0,1])。从/到 sRGB 的线性 RGB 转换位于 http://en.wikipedia.org/wiki/SRGB。在 VBA 中,这将被表达(采用线性化 sRGB 值 [0,1]):

Public Function sRGB_to_linearRGB(value As Double)
   If value < 0# Then
      sRGB_to_linearRGB = 0#
      Exit Function
   End If
   If value <= 0.04045 Then
      sRGB_to_linearRGB = value / 12.92
      Exit Function
   End If
   If value <= 1# Then
      sRGB_to_linearRGB = ((value + 0.055) / 1.055) ^ 2.4
      Exit Function
   End If
   sRGB_to_linearRGB = 1#
End Function

Public Function linearRGB_to_sRGB(value As Double)
   If value < 0# Then
      linearRGB_to_sRGB = 0#
      Exit Function
   End If
   If value <= 0.0031308 Then
      linearRGB_to_sRGB = value * 12.92
      Exit Function
   End If
   If value < 1# Then
      linearRGB_to_sRGB = 1.055 * (value ^ (1# / 2.4)) - 0.055
      Exit Function
   End If
   linearRGB_to_sRGB = 1#
End Function

我尝试将线性 RGB 值发送到标准 RGB_to_HSL 例程并从 HSL_to_RGB 返回,但它不起作用。也许是因为当前的 HSL<->RGB 算法考虑了伽玛校正,而线性 RGB 没有伽玛校正 - 我不太清楚。我几乎没有看到任何可以做到这一点的参考文献,除了两个

  1. http://en.wikipedia.org/wiki/HSL_and_HSV#cite_note-9 (编号为10)。
  2. 一个开源的参考 项目 Grafx2 @ http://code.google.com/p/grafx2/问题/详细信息?id=63#c22 其中贡献者指出 他已经完成了 Linear RGB <-> HSL 转换并在 .diff 文件中的注释附件中提供一些 C 代码 (我无法真正阅读:()

我的意图是:

  1. 从 sRGB 发送(例如, FF99FFR=255、G=153、B=255))至 线性 RGB(<代码>R=1.0, G=0.318546778125092,B=1.0)
    • 使用上面的代码(例如, G=153 将在线性中获得 RGB 从 sRGB_to_linearRGB(153 / 255))
  2. HSL
  3. 修改/调制饱和度 350%
  4. 从HSL返回->Linear RGB->sRGB,结果将是 FF19FFR=255、G=25、B=255)。

使用 .NET 中的可用函数(例如 System.Drawing.Color 中的 .getHue)在高于任何 HSL 值 100% 调制的任何 sRGB 空间中都不起作用,因此需要发送 Linear RGB 而不是 sRGB。

Does anyone know of a way to get HSL from an linearRGB color (not an sRGB color)? I've seen a lot of sRGB<->HSL conversions, but nothing for linearRGB<->HSL. Not sure if it is fundementally the same conversion with minor tweaks, but I'd appreciate any insight someone may have on this.

Linear RGB is not the same as linearizing sRGB (which is taking [0,255] and making it [0,1]). Linear RGB transformation from/to sRGB is at http://en.wikipedia.org/wiki/SRGB. In VBA, this would be expressed (taking in linearized sRGB values [0,1]):

Public Function sRGB_to_linearRGB(value As Double)
   If value < 0# Then
      sRGB_to_linearRGB = 0#
      Exit Function
   End If
   If value <= 0.04045 Then
      sRGB_to_linearRGB = value / 12.92
      Exit Function
   End If
   If value <= 1# Then
      sRGB_to_linearRGB = ((value + 0.055) / 1.055) ^ 2.4
      Exit Function
   End If
   sRGB_to_linearRGB = 1#
End Function

Public Function linearRGB_to_sRGB(value As Double)
   If value < 0# Then
      linearRGB_to_sRGB = 0#
      Exit Function
   End If
   If value <= 0.0031308 Then
      linearRGB_to_sRGB = value * 12.92
      Exit Function
   End If
   If value < 1# Then
      linearRGB_to_sRGB = 1.055 * (value ^ (1# / 2.4)) - 0.055
      Exit Function
   End If
   linearRGB_to_sRGB = 1#
End Function

I have tried sending in Linear RGB values to standard RGB_to_HSL routines and back out from HSL_to_RGB, but it does not work. Maybe because current HSL<->RGB algorithms account for gamma correction and Linear RGB is not gamma corrected - I don't know exactly. I have seen almost no references that this can be done, except for two:

  1. A reference on
    http://en.wikipedia.org/wiki/HSL_and_HSV#cite_note-9
    (numbered item 10).
  2. A reference on an open source
    project Grafx2 @
    http://code.google.com/p/grafx2/issues/detail?id=63#c22
    in which the contributor states that
    he has done Linear RGB <-> HSL
    conversion and provides some C code in an attachment to his comment in a .diff file
    (which I can't really read :( )

My intent is to:

  1. send from sRGB (for example,
    FF99FF (R=255, G=153, B=255)) to
    Linear RGB (R=1.0,
    G=0.318546778125092, B=1.0
    )

    • using the code above (for example,
      the G=153 would be obtained in Linear
      RGB from sRGB_to_linearRGB(153 /
      255)
      )
  2. to HSL
  3. modify/modulate the Saturation by
    350%
  4. send back from HSL->Linear
    RGB->sRGB, the result would be
    FF19FF (R=255, G=25, B=255).

Using available functions from .NET, such as .getHue from a System.Drawing.Color does not work in any sRGB space above 100% modulation of any HSL value, hence the need for Linear RGB to be sent in instead of sRGB.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱&纷飞 2024-08-12 12:01:04

转换为线性 RGB 没有多大意义,因为 HSL 是根据伽马编码值定义的。相反,编写您自己的函数将 sRGB 转换为 HSL,用这些值调制饱和度(允许潜在的色域外饱和度值),然后转换回 sRGB,限制超出 sRGB 范围的强度(或不允许饱和度更改)无法以 sRGB 编码)。

It doesn't make much sense to convert to linear RGB, since HSL is defined in terms of gamma encoded values. Instead, write your own function convert sRGB to HSL, modulate the saturation with those values (allowing potentially out-of-gamut saturation values), and then convert back to sRGB, clamping intensities that are out of sRGB range (or disallowing saturation changes that can't be encoded in sRGB).

绝影如岚 2024-08-12 12:01:04

System.Windows.Media.Color类允许您通过 ScA、ScR、ScG、ScB 属性获取或设置 scRGB,或通过 A、R、G、B 属性获取或设置 RGB。

因此,您可以将 RGB 转换为 HSL,对其进行操作,然后转换回 RGB 并存储在 Color 实例中。然后您可以读出转换后的 scRGB 属性。

不理想,可能会导致一些信息丢失。但这是一个选择!

The System.Windows.Media.Color class lets you get or set scRGB via ScA,ScR,ScG,ScB properties, or RGB via A,R,G,B properties.

So you could convert RGB to HSL, manipulate that, then convert back to RGB and store in a Color instance. You can then read out the converted scRGB properties.

Not ideal, and might involve some information loss. But it's an option!

悲歌长辞 2024-08-12 12:01:04

根据您此处的评论,您的问题不是进行转换不正确;而是您正在对量化值执行连续转换。换句话说,您将获取 sRGB=>RGB=>HSL=>HSL=>RGB=>sRGB 的结果,并在后续颜色操作中使用该结果。保持精度的最直接方法是始终保留原始 RGB 值并累积要应用的 HSL 空间中的变化。这样,您始终将 HSL 空间操作应用于原始颜色,而不必担心重复处理量化值。

Based on your comment here, your issue isn't doing the conversion incorrectly; it's that you are performing successive conversions on quantized values. In other words, you are taking the result of sRGB=>RGB=>HSL=>HSL=>RGB=>sRGB and using that in subsequent color operations. The most straightforward way to maintain precision is to always keep around the original RGB value and accumulate the changes in HSL space you want to apply. That way, you are always applying the HSL space operations to the original color and you don't have to worry about repeatedly processing quantized values.

疾风者 2024-08-12 12:01:04

有帮助吗?该问题中有很多有趣的链接,也许也适合您的情况......

Does this help? There are a lot of interesting links in that question, maybe something that works in your case, too...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文