我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
当前回答
找到了最简单的方法,蟒蛇来拯救:D
colorsys。Hls_to_rgb (h, l, s) 将颜色从HLS坐标转换为RGB坐标。
其他回答
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;
}
}
}
Java版本:
/*
Converts color from HSL/A format to RGB/A format
0 <= h <= 360
0 <= s, l, a <= 1
Based on: https://en.wikipedia.org/wiki/HSL_and_HSV#:~:text=%5Bedit%5D-,HSL%20to%20RGB%5Bedit%5D,-Given%20a%20color
*/
public RGB toRGB(double h, double s, double l, Double a) {
double c = (1 - Math.abs(2 * l - 1)) * s;
double x = c * (1 - Math.abs((h / 60) % 2 - 1));
double m = l - c / 2;
int[] RGBTag = Arrays.stream(getRGBTag(c, x)).mapToInt(e -> (int)Math.round((e + m) * 255)).toArray();
return RGB(RGBTag[0], RGBTag[1], RGBTag[2], a);
}
private double[] getRGBTag(double c, double x) {
if (h < 60) {
return new double[] {c, x, 0};
} else if (h < 120) {
return new double[] {x, c, 0};
} else if (h < 180) {
return new double[] {0, c, x};
} else if (h < 240) {
return new double[] {0, x, c};
} else if (h < 300) {
return new double[] {x, 0, c};
}
return new double[] {c, 0, x};
}
维基百科上关于HSL和HSV的文章包含了一些公式。计算有点棘手,所以看一下现有的实现可能会有用。
H, S, L在[0,1]范围内:
ConvertHslToRgb: function (iHsl)
{
var min, sv, sextant, fract, vsf;
var v = (iHsl.l <= 0.5) ? (iHsl.l * (1 + iHsl.s)) : (iHsl.l + iHsl.s - iHsl.l * iHsl.s);
if (v === 0)
return { Red: 0, Green: 0, Blue: 0 };
min = 2 * iHsl.l - v;
sv = (v - min) / v;
var h = (6 * iHsl.h) % 6;
sextant = Math.floor(h);
fract = h - sextant;
vsf = v * sv * fract;
switch (sextant)
{
case 0: return { r: v, g: min + vsf, b: min };
case 1: return { r: v - vsf, g: v, b: min };
case 2: return { r: min, g: v, b: min + vsf };
case 3: return { r: min, g: v - vsf, b: v };
case 4: return { r: min + vsf, g: min, b: v };
case 5: return { r: v, g: min, b: v - vsf };
}
}
我从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];
}