我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
当前回答
下面是GLSL中快速、超级简单、无分支的版本:
vec3 hsl2rgb( vec3 c ) {
vec3 rgb = clamp(abs(mod(c.x*6.0 + vec3(0.0, 4.0, 2.0), 6.0)-3.0)-1.0, 0.0, 1.0);
return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));
}
没有比这更短的了~
原始概念验证的链接:https://www.shadertoy.com/view/XljGzV
(免责声明:不是我的代码!)
其他回答
我从Brandon Mathis的HSL Picker源代码中得到了这个。
它最初是用CoffeeScript编写的。我使用在线转换器将其转换为JavaScript,并拿出验证用户输入是否为有效RGB值的机制。这个答案适用于我的用例,因为我发现这篇文章上投票最多的答案不能产生有效的HSL值。
注意,它返回一个hsla值,表示不透明/透明。0是完全透明的,1是完全不透明的。
function rgbToHsl(rgb) {
var a, add, b, diff, g, h, hue, l, lum, max, min, r, s, sat;
r = parseFloat(rgb[0]) / 255;
g = parseFloat(rgb[1]) / 255;
b = parseFloat(rgb[2]) / 255;
max = Math.max(r, g, b);
min = Math.min(r, g, b);
diff = max - min;
add = max + min;
hue = min === max ? 0 : r === max ? ((60 * (g - b) / diff) + 360) % 360 : g === max ? (60 * (b - r) / diff) + 120 : (60 * (r - g) / diff) + 240;
lum = 0.5 * add;
sat = lum === 0 ? 0 : lum === 1 ? 1 : lum <= 0.5 ? diff / add : diff / (2 - add);
h = Math.round(hue);
s = Math.round(sat * 100);
l = Math.round(lum * 100);
a = parseFloat(rgb[3]) || 1;
return [h, s, l, a];
}
Unity3D c#代码来自Mohsen的回答。
以下是Mohsen用c#编写的针对Unity3D的回答。它改编自上面Alec Thilenius给出的c#答案。
using UnityEngine;
using System.Collections;
public class ColorTools {
/// <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] )**strong text**
/// Output: Color ( R: [0.0, 1.0], G: [0.0, 1.0], B: [0.0, 1.0], A: [0.0, 1.0] )
/// </summary>
/// <param name="hsl">Vector4 defining X = h, Y = s, Z = l, W = a. Ranges [0, 1.0]</param>
/// <returns>RGBA Color. Ranges [0.0, 1.0]</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(r, g, b, hsl.w);
}
// 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;
}
/// <summary>
/// Converts an RGB color value to HSL.
/// Input: Color ( R: [0.0, 1.0], G: [0.0, 1.0], B: [0.0, 1.0], A: [0.0, 1.0] )
/// 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 max = (rgba.r > rgba.g && rgba.r > rgba.b) ? rgba.r :
(rgba.g > rgba.b) ? rgba.g : rgba.b;
float min = (rgba.r < rgba.g && rgba.r < rgba.b) ? rgba.r :
(rgba.g < rgba.b) ? rgba.g : rgba.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 (rgba.r > rgba.g && rgba.r > rgba.b)
h = (rgba.g - rgba.b) / d + (rgba.g < rgba.b ? 6.0f : 0.0f);
else if (rgba.g > rgba.b)
h = (rgba.b - rgba.r) / d + 2.0f;
else
h = (rgba.r - rgba.g) / d + 4.0f;
h /= 6.0f;
}
return new Vector4(h, s, l, rgba.a);
}
}
一个hsl|的颜色值,设置在javascript,将立即 所有你需要做的是,然后访问 计算样式值
document.body.style.color = 'hsla(44, 100%, 50%, 0.8)';
console.log(window.getComputedStyle(document.body).color);
// displays: rgba(255, 187, 0, 0.8)
从技术上讲,我想,这甚至不是任何一行代码-这是 自动完成。所以,取决于你的环境,你 也许这样就能逃过一劫。并不是说没有 这里有很多深思熟虑的回复。我不知道你的 目标是。
现在,如果你想从rbg|a转换到hsl|a呢?
HSL到RGB的Typescript
以上所有选项都不能在我的代码在TS工作。
我调整了其中一个,现在它就像一个咒语:
type HslType = { h: number; s: number; l: number }
const hslToRgb = (hsl: HslType): RgbType => {
let { h, s, l } = hsl
// IMPORTANT if s and l between 0,1 remove the next two lines:
s /= 100
l /= 100
const k = (n: number) => (n + h / 30) % 12
const a = s * Math.min(l, 1 - l)
const f = (n: number) =>
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)))
return {
r: Math.round(255 * f(0)),
g: Math.round(255 * f(8)),
b: Math.round(255 * f(4)),
}
}
c++实现,性能可能比@Mohsen代码更好。它使用[0-6]范围的色调,避免除和乘6。S和L的范围为[0,1]
void fromRGBtoHSL(float rgb[], float hsl[])
{
const float maxRGB = max(rgb[0], max(rgb[1], rgb[2]));
const float minRGB = min(rgb[0], min(rgb[1], rgb[2]));
const float delta2 = maxRGB + minRGB;
hsl[2] = delta2 * 0.5f;
const float delta = maxRGB - minRGB;
if (delta < FLT_MIN)
hsl[0] = hsl[1] = 0.0f;
else
{
hsl[1] = delta / (hsl[2] > 0.5f ? 2.0f - delta2 : delta2);
if (rgb[0] >= maxRGB)
{
hsl[0] = (rgb[1] - rgb[2]) / delta;
if (hsl[0] < 0.0f)
hsl[0] += 6.0f;
}
else if (rgb[1] >= maxRGB)
hsl[0] = 2.0f + (rgb[2] - rgb[0]) / delta;
else
hsl[0] = 4.0f + (rgb[0] - rgb[1]) / delta;
}
}
void fromHSLtoRGB(const float hsl[], float rgb[])
{
if(hsl[1] < FLT_MIN)
rgb[0] = rgb[1] = rgb[2] = hsl[2];
else if(hsl[2] < FLT_MIN)
rgb[0] = rgb[1] = rgb[2] = 0.0f;
else
{
const float q = hsl[2] < 0.5f ? hsl[2] * (1.0f + hsl[1]) : hsl[2] + hsl[1] - hsl[2] * hsl[1];
const float p = 2.0f * hsl[2] - q;
float t[] = {hsl[0] + 2.0f, hsl[0], hsl[0] - 2.0f};
for(int i=0; i<3; ++i)
{
if(t[i] < 0.0f)
t[i] += 6.0f;
else if(t[i] > 6.0f)
t[i] -= 6.0f;
if(t[i] < 1.0f)
rgb[i] = p + (q - p) * t[i];
else if(t[i] < 3.0f)
rgb[i] = q;
else if(t[i] < 4.0f)
rgb[i] = p + (q - p) * (4.0f - t[i]);
else
rgb[i] = p;
}
}
}