HSV到RGB颜色转换

AvZ*_*AvZ 19 python rgb pygame colors hsv

有没有办法在python中使用pygame模块将HSV颜色参数转换为RGB类型颜色参数?我尝试了以下代码,但它返回荒谬的值.

import colorsys
test_color = colorsys.hsv_to_rgb(359, 100, 100)
print(test_color)
Run Code Online (Sandbox Code Playgroud)

这段代码返回以下废话

(100, -9900.0, -9900.0)
Run Code Online (Sandbox Code Playgroud)

这显然不是RGB.我究竟做错了什么?

Cor*_*mer 26

该函数需要十进制s(饱和度)和v(值),而不是百分比.除以100.

>>> import colorsys

# Using percent, incorrect
>>> test_color = colorsys.hsv_to_rgb(359,100,100)
>>> test_color
(100, -9900.0, -9900.0)

# Using decimal, correct
>>> test_color = colorsys.hsv_to_rgb(1,1,1)
>>> test_color
(1, 0.0, 0.0)
Run Code Online (Sandbox Code Playgroud)

如果你想要非规范化的RGB元组,这里是一个包装colorsys函数的函数.

def hsv2rgb(h,s,v):
    return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h,s,v))
Run Code Online (Sandbox Code Playgroud)

示例功能

>>> hsv2rgb(0.5,0.5,0.5)
(64, 128, 128)
Run Code Online (Sandbox Code Playgroud)

  • Hue论点也应该在0-1之间变化 (3认同)

Tcl*_*cll 12

如果您喜欢性能,最好避免导入并使用您自己的优化代码

这是来自colorsys的确切代码稍加修改,以使字节代码稍微加快:

    def hsv_to_rgb(h, s, v):
        if s == 0.0: return (v, v, v)
        i = int(h*6.) # XXX assume int() truncates!
        f = (h*6.)-i; p,q,t = v*(1.-s), v*(1.-s*f), v*(1.-s*(1.-f)); i%=6
        if i == 0: return (v, t, p)
        if i == 1: return (q, v, p)
        if i == 2: return (p, v, t)
        if i == 3: return (p, q, v)
        if i == 4: return (t, p, v)
        if i == 5: return (v, p, q)
Run Code Online (Sandbox Code Playgroud)

输出:

>>> hsv_to_rgb(359,1,1)
[1, 0.0, 0.0]
Run Code Online (Sandbox Code Playgroud)

使用像上面这样的if-chain实际上比使用elif更快

使用包装器,就像在Cyber​​的答案中一样,需要一些额外的步骤让解释器执行.
另外,Cyber​​的示例中的for循环在使用时就是一个真正的性能杀手

如果你想要稍微提高性能,只需这样做:(
我不会说这是最好的性能,但它肯定更好)

    def hsv_to_rgb(h, s, v):
        if s == 0.0: v*=255; return (v, v, v)
        i = int(h*6.) # XXX assume int() truncates!
        f = (h*6.)-i; p,q,t = int(255*(v*(1.-s))), int(255*(v*(1.-s*f))), int(255*(v*(1.-s*(1.-f)))); v*=255; i%=6
        if i == 0: return (v, t, p)
        if i == 1: return (q, v, p)
        if i == 2: return (p, v, t)
        if i == 3: return (p, q, v)
        if i == 4: return (t, p, v)
        if i == 5: return (v, p, q)
Run Code Online (Sandbox Code Playgroud)

^这保证int()输出的范围为255(输入仍然相同)

>>> hsv_to_rgb(359./360.,1,1)
(255, 0, 0)
Run Code Online (Sandbox Code Playgroud)

提示:尽可能远离第三方,如果可以,请尝试直接方法.
exculus:编译的C扩展,如PIL或NumPy,或ctypes包装,如PyOpenGL(使用DLL)

  • 因为您的解决方案将色调值从0到1,但在您的示例中,您使用0到360之间的值. (2认同)
  • 如果我们谈论性能,我会远离列表并返回元组. (2认同)

小智 6

Hue论点也应该在0-1之间变化.

import colorsys
test_color = colorsys.hsv_to_rgb(359/360.0, 1, 1)
Run Code Online (Sandbox Code Playgroud)


buz*_*jwa 5

如果您正在使用 Numpy 数组,那么matplotlib.colors.hsv_to_rgb非常直接:

import numpy as np
from matplotlib.colors import hsv_to_rgb
# This will create a nice image of varying hue and value
hsv = np.zeros((512, 512, 3))
hsv[..., 0] = np.linspace(0, 1, 512)
hsv[..., 1] = 1.
hsv[..., 2] = np.linspace(0, 1, 512)[:, np.newaxis]
rgb = hsv_to_rgb(hsv)
Run Code Online (Sandbox Code Playgroud)

请注意,输入和输出图像的值在 [0, 1] 范围内。