为什么RGB和HLS颜色系统之间的转换不准确?

时间:2014-05-05 12:19:05

标签: python colors

对于我的一个应用程序,我需要将颜色从RGB转换为HLS颜色系统,反之亦然。我发现Python的标准库中有colorsys模块。

问题是,与this online color converter相比,转化有时有点不精确,结果略有不同。

这是一个例子,我为方便起见编写的前两个小函数:

from __future__ import division

import colorsys

def convert_rgb_to_hls(r, g, b):
    h, l, s = colorsys.rgb_to_hls(r/255, g/255, b/255)
    return "HLS(" + str(int(round(h * 359))) + ", " + str(int(round(l * 100))) + ", " + str(int(round(s * 100))) + ")"

def convert_hls_to_rgb(h, l, s):
    r, g, b = colorsys.hls_to_rgb(h/359, l/100, s/100)
    return "RGB(" + str(int(round(r * 255))) + ", " + str(int(round(g * 255))) + ", " + str(int(round(b * 255))) + ")"

根据在线颜色转换器,RGB(123,243,61)应等于HLS(100,60,88)。我使用colorsys函数得到的结果是不同的:

>>> convert_rgb_to_hls(123, 243, 61)
'HLS(99, 59, 88)'   # should be HLS(100, 60, 88)

>>> convert_hls_to_rgb(100, 60, 88)
'RGB(122, 243, 63)' # should be RGB(123, 243, 61)

我的第一印象是,这只是一个舍入问题,但看看61和63之间的区别,似乎还有另一个原因。但它是什么?是否有可能保证色彩系统之间的绝对精确转换?

1 个答案:

答案 0 :(得分:3)

from __future__ import division

import colorsys

def convert_rgb_to_hls(r, g, b):
    h, l, s = colorsys.rgb_to_hls(r/255, g/255, b/255)
    return "HLS(" + str(int(round(h * 360))) + ", " + str(int(round(l * 100))) + ", " + str(int(round(s * 100))) + ")"

def convert_hls_to_rgb(h, l, s):
    r, g, b = colorsys.hls_to_rgb(h/360, l/100, s/100)
    return "RGB(" + str(int(round(r * 255))) + ", " + str(int(round(g * 255))) + ", " + str(int(round(b * 255))) + ")"

<强>更改

  • 360而不是359,因为范围是[0,360)(wikipedia)。
  • convert_rgb_to_hls(r, g, b)上缺少两个舍入。
  • 如果您使用python 2,则添加了python 3分区。

<强>测试

>>> convert_rgb_to_hls(123, 243, 61)    
'HLS(100, 60, 88)'

>>> convert_hls_to_rgb(100, 60, 88)
'RGB(123, 243, 63)'

当你说有类似舍入的错误时,你是对的,但是61和63之间的差异是因为你在舍入时会失去精确度。不要四舍五入以获得更好的精确度:

>>> (r_orig, g_orig, b_orig) = (123, 243, 61)
>>> h,l,s = colorsys.rgb_to_hls(r_orig/255, g_orig/255, b_orig/255)
>>> r, g, b = colorsys.hls_to_rgb(h, l, s)
>>> r*255, g*255, b*255
(123.00000000000003, 242.99999999999997, 61.000000000000036)