我正在寻找一个算法之间的HSL颜色转换为RGB。

在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。


当前回答

由于circuitpython不支持colorsys(或目前移植到),如果你试图在树莓派上处理这个转换,下面的工作(受制于本线程其他地方提到的舍入精度限制):

def hslToRgb (h, s, l): #in range 0-1 for h,s,l
    if s == 0:
        r = g = b = l #achromatic
    else:
        def hue2rgb(p, q, t):
            if t < 0: t += 1
            if t > 1: t -= 1
            if t < 1.0 / 6.0: return p + (q - p) * 6 * t
            if t < 1.0 / 2.0: return q
            if t < 2.0 / 3.0: return p + (q - p) * ((2.0 / 3.0) - t) * 6
            return p
        if l < 0.5:
            q = l * (1 + s)
        else:
            q = l + s - l * s
        p = 2 * l - q
        r = hue2rgb(p, q, h + 1.0/3.0)
        g = hue2rgb(p, q, h)
        b = hue2rgb(p, q, h - 1.0/3.0)
    return [round(r * 255), round(g * 255), round(b * 255)]

其他回答

找到了最简单的方法,蟒蛇来拯救:D

colorsys。Hls_to_rgb (h, l, s) 将颜色从HLS坐标转换为RGB坐标。

维基百科上关于HSL和HSV的文章包含了一些公式。计算有点棘手,所以看一下现有的实现可能会有用。

Mohsen代码的Java实现

注意,所有整数都声明为浮点数(即1f),必须是浮点数,否则您将选择灰色。

HSL到RGB

 /**
 * Converts an HSL color value to RGB. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes h, s, and l are contained in the set [0, 1] and
 * returns r, g, and b in the set [0, 255].
 *
 * @param h       The hue
 * @param s       The saturation
 * @param l       The lightness
 * @return int array, the RGB representation
 */
public static int[] hslToRgb(float h, float s, float l){
    float r, g, b;

    if (s == 0f) {
        r = g = b = l; // achromatic
    } else {
        float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
        float p = 2 * l - q;
        r = hueToRgb(p, q, h + 1f/3f);
        g = hueToRgb(p, q, h);
        b = hueToRgb(p, q, h - 1f/3f);
    }
    int[] rgb = {to255(r), to255(g), to255(b)};
    return rgb;
}
public static int to255(float v) { return (int)Math.min(255,256*v); }

/** Helper method that converts hue to rgb */
public static float hueToRgb(float p, float q, float t) {
    if (t < 0f)
        t += 1f;
    if (t > 1f)
        t -= 1f;
    if (t < 1f/6f)
        return p + (q - p) * 6f * t;
    if (t < 1f/2f)
        return q;
    if (t < 2f/3f)
        return p + (q - p) * (2f/3f - t) * 6f;
    return p;
}

RGB到HSL

/**
 * Converts an RGB color value to HSL. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes pR, pG, and bpBare contained in the set [0, 255] and
 * returns h, s, and l in the set [0, 1].
 *
 * @param pR       The red color value
 * @param pG       The green color value
 * @param pB       The blue color value
 * @return float array, the HSL representation
 */
public static float[] rgbToHsl(int pR, int pG, int pB) {
    float r = pR / 255f;
    float g = pG / 255f;
    float b = pB / 255f;

    float max = (r > g && r > b) ? r : (g > b) ? g : b;
    float min = (r < g && r < b) ? r : (g < b) ? g : b;

    float h, s, l;
    l = (max + min) / 2.0f;

    if (max == min) {
        h = s = 0.0f;
    } else {
        float d = max - min;
        s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min);

        if (r > g && r > b)
            h = (g - b) / d + (g < b ? 6.0f : 0.0f);

        else if (g > b)
            h = (b - r) / d + 2.0f;

        else
            h = (r - g) / d + 4.0f;

        h /= 6.0f;
    }

    float[] hsl = {h, s, l};
    return hsl;
}

对于所有说Garry Tan解决方案转换不正确从RGB到HSL和回来。这是因为他在代码中遗漏了数字的一部分。 我纠正了他的代码(javascript)。 对不起,俄语的链接,但在英语缺席- HSL-wiki

function toHsl(r, g, b)
{
    r /= 255.0;
    g /= 255.0;
    b /= 255.0;
    var max = Math.max(r, g, b);
    var min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2.0;

    if(max == min)
    {
        h = s = 0; 
    }
    else
    {
        var d = max - min;
        s = (l > 0.5 ? d / (2.0 - max - min) : d / (max + min));

        if(max == r && g >= b)
        {
            h = 1.0472 * (g - b) / d ;
        }
        else if(max == r && g < b)
        {
            h = 1.0472 * (g - b) / d + 6.2832;
        }
        else if(max == g)
        {
            h = 1.0472 * (b - r) / d + 2.0944;
        }
        else if(max == b)
        {
            h = 1.0472 * (r - g) / d + 4.1888;
        }
    }
    return {
        str: 'hsl(' + parseInt(h / 6.2832 * 360.0 + 0.5) + ',' + parseInt(s * 100.0 + 0.5) + '%,' + parseInt(l * 100.0 + 0.5) + '%)',
        obj: { h: parseInt(h / 6.2832 * 360.0 + 0.5), s: parseInt(s * 100.0 + 0.5), l: parseInt(l * 100.0 + 0.5) }
    };
};

来自Mohsen回答的c#代码。

下面是Mohsen用c#编写的答案代码,如果有人想要的话。注意:Color是自定义类,Vector4来自OpenTK。两者都很容易被你选择的其他东西取代。

Hsl到Rgba

/// <summary>
/// Converts an HSL color value to RGB.
/// Input: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] )
/// Output: Color ( R: [0, 255], G: [0, 255], B: [0, 255], A: [0, 255] )
/// </summary>
/// <param name="hsl">Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0]</param>
/// <returns>RGBA Color. Ranges [0, 255]</returns>
public static Color HslToRgba(Vector4 hsl)
{
    float r, g, b;

    if (hsl.Y == 0.0f)
        r = g = b = hsl.Z;

    else
    {
        var q = hsl.Z < 0.5f ? hsl.Z * (1.0f + hsl.Y) : hsl.Z + hsl.Y - hsl.Z * hsl.Y;
        var p = 2.0f * hsl.Z - q;
        r = HueToRgb(p, q, hsl.X + 1.0f / 3.0f);
        g = HueToRgb(p, q, hsl.X);
        b = HueToRgb(p, q, hsl.X - 1.0f / 3.0f);
    }

    return new Color((int)(r * 255), (int)(g * 255), (int)(b * 255), (int)(hsl.W * 255));
}

// Helper for HslToRgba
private static float HueToRgb(float p, float q, float t)
{
    if (t < 0.0f) t += 1.0f;
    if (t > 1.0f) t -= 1.0f;
    if (t < 1.0f / 6.0f) return p + (q - p) * 6.0f * t;
    if (t < 1.0f / 2.0f) return q;
    if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
    return p;
}

Rgba到Hsl

/// <summary>
/// Converts an RGB color value to HSL.
/// Input: Color ( R: [0, 255], G: [0, 255], B: [0, 255], A: [0, 255] )
/// Output: Vector4 ( X: [0.0, 1.0], Y: [0.0, 1.0], Z: [0.0, 1.0], W: [0.0, 1.0] )
/// </summary>
/// <param name="rgba"></param>
/// <returns></returns>
public static Vector4 RgbaToHsl(Color rgba)
{
    float r = rgba.R / 255.0f;
    float g = rgba.G / 255.0f;
    float b = rgba.B / 255.0f;

    float max = (r > g && r > b) ? r : (g > b) ? g : b;
    float min = (r < g && r < b) ? r : (g < b) ? g : b;

    float h, s, l;
    h = s = l = (max + min) / 2.0f;

    if (max == min)
        h = s = 0.0f;

    else
    {
        float d = max - min;
        s = (l > 0.5f) ? d / (2.0f - max - min) : d / (max + min);

        if (r > g && r > b)
            h = (g - b) / d + (g < b ? 6.0f : 0.0f);

        else if (g > b)
            h = (b - r) / d + 2.0f;

        else
            h = (r - g) / d + 4.0f;

        h /= 6.0f;
    }

    return new Vector4(h, s, l, rgba.A / 255.0f);
}