HSL 색상을 RGB로 변환하는 JavaScript / PHP 알고리즘을 찾고 있습니다.
HSL은 널리 사용되지 않으므로 컨버터를 검색하는 데 많은 운이 없습니다.
HSL 색상을 RGB로 변환하는 JavaScript / PHP 알고리즘을 찾고 있습니다.
HSL은 널리 사용되지 않으므로 컨버터를 검색하는 데 많은 운이 없습니다.
답변:
Garry Tan은 자신의 블로그 에 Javascript 솔루션을 게시했습니다 (그는 현재 없어진 mjijackson.com의 속성 이지만 여기에 보관 되어 있으며 원저자에게는 user2441511 덕분입니다).
코드는 아래에 다시 게시됩니다.
/**
* 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 {number} h The hue
* @param {number} s The saturation
* @param {number} l The lightness
* @return {Array} The RGB representation
*/
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
var hue2rgb = function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* @param {number} r The red color value
* @param {number} g The green color value
* @param {number} b The blue color value
* @return {Array} The HSL representation
*/
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
Math.round
하면 스케일의 하한 및 상한 (0 및 255 값)에 작은 부정확성이 도입 된다는 점을 지적하고 싶습니다 . 범위의 끝에없는 값은 값에 도달하기 위해 올림 또는 내림 할 수 있지만 값은 0 또는 255로 올림 만 할 수 있습니다. 이는 0과 255에 매핑되는 값의 범위가 정확히 다른 값에 대한 것의 절반. 이 문제를 해결하려면 다음 공식을 대신 사용하십시오 min(floor(val*256),255)
. 이것은 매핑을 거의 완벽하게 만듭니다.
h + 1/3
와 h - 1/3
. 많은 언어에서 정수 나누기를 사용 1/3
합니다. 여기서 0은 0입니다. 올바른 결과를 얻으려면 대신 float 리터럴을 사용하십시오 h + 1.0/3.0
.
가장 쉬운 방법, 파이썬을 구출 하는 방법을 찾았습니다 . : D
colorsys.hls_to_rgb(h, l, s)
HLS 좌표에서 RGB 좌표로 색상을 변환하십시오.
Color::HSL.new(40,50,60).to_rgb
모든 정수는 float (즉, 1f)로 선언되고 float이어야합니다. 그렇지 않으면 회색 색상이 선택됩니다.
/**
* 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;
}
/**
* 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;
}
Wikipedia의 HSL 및 HSV에 대한 기사 에는 몇 가지 수식이 포함되어 있습니다. 계산은 약간 까다롭기 때문에 기존 구현을 살펴 보는 것이 좋습니다 .
HSL 및 RGB에 대한 CSS 의미를 확실히 준수하는 것을 찾고 있다면 CSS 3 사양에 지정된 알고리즘을 사용할 수 있습니다 .
HOW TO RETURN hsl.to.rgb(h, s, l):
SELECT:
l<=0.5: PUT l*(s+1) IN m2
ELSE: PUT l+s-l*s IN m2
PUT l*2-m2 IN m1
PUT hue.to.rgb(m1, m2, h+1/3) IN r
PUT hue.to.rgb(m1, m2, h ) IN g
PUT hue.to.rgb(m1, m2, h-1/3) IN b
RETURN (r, g, b)
HOW TO RETURN hue.to.rgb(m1, m2, h):
IF h<0: PUT h+1 IN h
IF h>1: PUT h-1 IN h
IF h*6<1: RETURN m1+(m2-m1)*h*6
IF h*2<1: RETURN m2
IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6
RETURN m1
나는 이것이 다른 대답 중 일부의 출처라고 생각합니다.
다른 사람이 원한다면 C #의 Mohsen의 답변 코드는 다음과 같습니다. 참고 : Color
사용자 정의 클래스이며 Vector4
OpenTK에서 제공됩니다. 둘 다 당신이 선택한 다른 것으로 쉽게 대체 할 수 있습니다.
/// <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;
}
/// <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);
}
또한 여기 에서 그 수학을 매우 잘 설명합니다.
이것은 기본적으로 HSL (Hue Saturation Lightness)과의 변환 기능입니다
PHP 5.6.15에서 테스트 및 작업
TL; DR : 전체 코드는 Pastebin 에서 찾을 수 있습니다 .
입력 : 16 진수 색상 형식 : [#] 0f4 또는 [#] 00ff44 (파운드 기호 옵션)
출력 : HSL (도, 백분율, 백분율)
/**
* Input: hex color
* Output: hsl(in ranges from 0-1)
*
* Takes the hex, converts it to RGB, and sends
* it to RGBToHsl. Returns the output.
*
*/
function hexToHsl($hex) {
$r = "";
$g = "";
$b = "";
$hex = str_replace('#', '', $hex);
if (strlen($hex) == 3) {
$r = substr($hex, 0, 1);
$r = $r . $r;
$g = substr($hex, 1, 1);
$g = $g . $g;
$b = substr($hex, 2, 1);
$b = $b . $b;
} elseif (strlen($hex) == 6) {
$r = substr($hex, 0, 2);
$g = substr($hex, 2, 2);
$b = substr($hex, 4, 2);
} else {
return false;
}
$r = hexdec($r);
$g = hexdec($g);
$b = hexdec($b);
$hsl = rgbToHsl($r,$g,$b);
return $hsl;
}
입력 : 0-255 범위의 RGB 출력 : HSL (도, 백분율, 백분율).
/**
*
*Credits:
* /programming/4793729/rgb-to-hsl-and-back-calculation-problems
* http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/
*
* Called by hexToHsl by default.
*
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/.
* Assumes r, g, and b are contained in the range [0 - 255] and
* returns h, s, and l in the format Degrees, Percent, Percent.
*
* @param Number r The red color value
* @param Number g The green color value
* @param Number b The blue color value
* @return Array The HSL representation
*/
function rgbToHsl($r, $g, $b){
//For the calculation, rgb needs to be in the range from 0 to 1. To convert, divide by 255 (ff).
$r /= 255;
$g /= 255;
$b /= 255;
$myMax = max($r, $g, $b);
$myMin = min($r, $g, $b);
$maxAdd = ($myMax + $myMin);
$maxSub = ($myMax - $myMin);
//luminence is (max + min)/2
$h = 0;
$s = 0;
$l = ($maxAdd / 2.0);
//if all the numbers are equal, there is no saturation (greyscale).
if($myMin != $myMax){
if ($l < 0.5) {
$s = ($maxSub / $maxAdd);
} else {
$s = (2.0 - $myMax - $myMin); //note order of opperations - can't use $maxSub here
$s = ($maxSub / $s);
}
//find hue
switch($myMax){
case $r:
$h = ($g - $b);
$h = ($h / $maxSub);
break;
case $g:
$h = ($b - $r);
$h = ($h / $maxSub);
$h = ($h + 2.0);
break;
case $b:
$h = ($r - $g);
$h = ($h / $maxSub);
$h = ($h + 4.0);
break;
}
}
$hsl = hslToDegPercPerc($h, $s, $l);
return $hsl;
}
수학 계산의 경우 HSL은 0-1 범위에서 다루기가 더 쉽지만 사람이 쉽게 읽을 수 있도록도, 백분율, 백분율이 더 쉽습니다. 이 함수는 0-1 범위의 HSL을 가져와도, 백분율, 백분율로 HSL을 반환합니다.
/**
* Input: HSL in ranges 0-1.
* Output: HSL in format Deg, Perc, Perc.
*
* Note: rgbToHsl calls this function by default.
*
* Multiplies $h by 60, and $s and $l by 100.
*/
function hslToDegPercPerc($h, $s, $l) {
//convert h to degrees
$h *= 60;
if ($h < 0) {
$h += 360;
}
//convert s and l to percentage
$s *= 100;
$l *= 100;
$hsl['h'] = $h;
$hsl['s'] = $s;
$hsl['l'] = $l;
return $hsl;
}
이 기능은 더 쉬운 계산을 위해 Degrees, Percent, Percent 형식의 HSL을 0-1 범위로 변환합니다.
/**
* Input: HSL in format Deg, Perc, Perc
* Output: An array containing HSL in ranges 0-1
*
* Divides $h by 60, and $s and $l by 100.
*
* hslToRgb calls this by default.
*/
function degPercPercToHsl($h, $s, $l) {
//convert h, s, and l back to the 0-1 range
//convert the hue's 360 degrees in a circle to 1
$h /= 360;
//convert the saturation and lightness to the 0-1
//range by multiplying by 100
$s /= 100;
$l /= 100;
$hsl['h'] = $h;
$hsl['s'] = $s;
$hsl['l'] = $l;
return $hsl;
}
입력 : HSL 형식의도, 백분율, 백분율 출력 : 형식의 RGB 255, 255, 255
.
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/.
* Assumes h, s, and l are in the format Degrees,
* Percent, Percent, and returns r, g, and b in
* the range [0 - 255].
*
* Called by hslToHex by default.
*
* Calls:
* degPercPercToHsl
* hueToRgb
*
* @param Number h The hue value
* @param Number s The saturation level
* @param Number l The luminence
* @return Array The RGB representation
*/
function hslToRgb($h, $s, $l){
$hsl = degPercPercToHsl($h, $s, $l);
$h = $hsl['h'];
$s = $hsl['s'];
$l = $hsl['l'];
//If there's no saturation, the color is a greyscale,
//so all three RGB values can be set to the lightness.
//(Hue doesn't matter, because it's grey, not color)
if ($s == 0) {
$r = $l * 255;
$g = $l * 255;
$b = $l * 255;
}
else {
//calculate some temperary variables to make the
//calculation eaisier.
if ($l < 0.5) {
$temp2 = $l * (1 + $s);
} else {
$temp2 = ($l + $s) - ($s * $l);
}
$temp1 = 2 * $l - $temp2;
//run the calculated vars through hueToRgb to
//calculate the RGB value. Note that for the Red
//value, we add a third (120 degrees), to adjust
//the hue to the correct section of the circle for
//red. Simalarly, for blue, we subtract 1/3.
$r = 255 * hueToRgb($temp1, $temp2, $h + (1 / 3));
$g = 255 * hueToRgb($temp1, $temp2, $h);
$b = 255 * hueToRgb($temp1, $temp2, $h - (1 / 3));
}
$rgb['r'] = $r;
$rgb['g'] = $g;
$rgb['b'] = $b;
return $rgb;
}
이 함수는 색조를 별도의 RGB 값으로 변환하기 위해 hslToRgb에 의해 호출됩니다.
/**
* Converts an HSL hue to it's RGB value.
*
* Input: $temp1 and $temp2 - temperary vars based on
* whether the lumanence is less than 0.5, and
* calculated using the saturation and luminence
* values.
* $hue - the hue (to be converted to an RGB
* value) For red, add 1/3 to the hue, green
* leave it alone, and blue you subtract 1/3
* from the hue.
*
* Output: One RGB value.
*
* Thanks to Easy RGB for this function (Hue_2_RGB).
* http://www.easyrgb.com/index.php?X=MATH&$h=19#text19
*
*/
function hueToRgb($temp1, $temp2, $hue) {
if ($hue < 0) {
$hue += 1;
}
if ($hue > 1) {
$hue -= 1;
}
if ((6 * $hue) < 1 ) {
return ($temp1 + ($temp2 - $temp1) * 6 * $hue);
} elseif ((2 * $hue) < 1 ) {
return $temp2;
} elseif ((3 * $hue) < 2 ) {
return ($temp1 + ($temp2 - $temp1) * ((2 / 3) - $hue) * 6);
}
return $temp1;
}
입력 : HSL 형식의도, 백분율, 백분율 출력 : 16 진수 형식 00ff22
(파운드 기호 없음).
RGB로 변환 한 다음 별도로 16 진수로 변환합니다.
/**
* Converts HSL to Hex by converting it to
* RGB, then converting that to hex.
*
* string hslToHex($h, $s, $l[, $prependPound = true]
*
* $h is the Degrees value of the Hue
* $s is the Percentage value of the Saturation
* $l is the Percentage value of the Lightness
* $prependPound is a bool, whether you want a pound
* sign prepended. (optional - default=true)
*
* Calls:
* hslToRgb
*
* Output: Hex in the format: #00ff88 (with
* pound sign). Rounded to the nearest whole
* number.
*/
function hslToHex($h, $s, $l, $prependPound = true) {
//convert hsl to rgb
$rgb = hslToRgb($h,$s,$l);
//convert rgb to hex
$hexR = $rgb['r'];
$hexG = $rgb['g'];
$hexB = $rgb['b'];
//round to the nearest whole number
$hexR = round($hexR);
$hexG = round($hexG);
$hexB = round($hexB);
//convert to hex
$hexR = dechex($hexR);
$hexG = dechex($hexG);
$hexB = dechex($hexB);
//check for a non-two string length
//if it's 1, we can just prepend a
//0, but if it is anything else non-2,
//it must return false, as we don't
//know what format it is in.
if (strlen($hexR) != 2) {
if (strlen($hexR) == 1) {
//probably in format #0f4, etc.
$hexR = "0" . $hexR;
} else {
//unknown format
return false;
}
}
if (strlen($hexG) != 2) {
if (strlen($hexG) == 1) {
$hexG = "0" . $hexG;
} else {
return false;
}
}
if (strlen($hexB) != 2) {
if (strlen($hexB) == 1) {
$hexB = "0" . $hexB;
} else {
return false;
}
}
//if prependPound is set, will prepend a
//# sign to the beginning of the hex code.
//(default = true)
$hex = "";
if ($prependPound) {
$hex = "#";
}
$hex = $hex . $hexR . $hexG . $hexB;
return $hex;
}
rgbToHsl
. PHP 코드를 업데이트하고 싶을 수도 있습니다. 코드에 버그가있었습니다. rgbToHsl에서 () s = maxSub / (2 - maxSub)
해야한다s = maxSub / (2 - maxAdd)
(2 - maxSub) = 1.7333333333333334
두 번째 링크 예에서와 같이 사용해야합니다 ( 2 - max - min ) = 0.6352941176470588
. 를 사용하면 2 - maxAdd
포토샵 출력에 일관되게 가깝게 도달 하여 올바른 것으로 가정했습니다.
이것이 내가 기억하기 쉬운 방법은 RGB를 120도 떨어진 바퀴에 세 개의 스포크로 생각하는 것입니다.
H = hue (0-360)
S = saturation (0-1)
L = luminance (0-1)
R1 = SIN( H ) * L
G1 = SIN( H + 120 ) * L
B1 = SIN( H + 240 ) * L
까다로운 부분은 채도이며, 이는 세 가지의 평균으로 축소됩니다.
AVERAGE = (R1 + G1 + B1) / 3
R2 = ((R1 - AVERAGE) * S) + AVERAGE
G2 = ((G1 - AVERAGE) * S) + AVERAGE
B2 = ((B1 - AVERAGE) * S) + AVERAGE
RED = R2 * 255
GREEN = G2 * 255
BLUE = B2 * 255
+
, -
, *
, 및 /
의 도움으로 그들을 표현하는 - 같은 색상 변환에 대한 정의에 사용되는 -) sine
같은 독립 (입력) 변수와 기능을합니다. 그럼에도 불구하고 원칙 을 이해하는 것은 좋지만 변환을 수행하는 것은 아닙니다 .
(R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]
와 동일하다는 것입니다 .-이제 우리 sin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)
는 처음 두 가지 죄에 대한 공식 을 사용 하면 다음 AVERAGE=L*( sin(h+60) + sin(h+240) )
과 같은 결과를 얻습니다 AVERAGE= L*2*sin(h+150)*cos(-180/2) = 0
. 따라서 채도 계산이 잘못되었으며 실제로 채도는 휘도로 작동합니다.
다음은 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
(면책 조항 : 내 코드가 아닙니다!)
다음은 수정 된 자바 스크립트 함수입니다. 설정된 0-360 도의 색조를 출력합니다.
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d ; break;
case g: h = 2 + ( (b - r) / d); break;
case b: h = 4 + ( (r - g) / d); break;
}
h*=60;
if (h < 0) h +=360;
}
return([h, s, l]);
}
alert(rgbToHsl(125,115,145));
Brandon Mathis의 HSL Picker 소스 코드 에서 이것을 얻었습니다 .
그것은 한 원래 커피 스크립트로 작성 . 온라인 변환기를 사용하여 JavaScript로 변환하고 사용자 입력이 유효한 RGB 값인지 확인하는 메커니즘을 사용했습니다. 이 답변은이 게시물에서 가장 많이 투표 된 답변으로 유효한 HSL 값을 생성하지 못하는 것으로 나타났습니다.
불투명도 / 투명도 hsla
를 a
나타내는 값을 반환합니다 . 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];
}
HSV에서 RGB로 또는 그 반대로 RGB가 필요한 경우 :
function rgbToHsv(r, g, b)
{
r /= 255, g /= 255, b /= 255;
var min = Math.min(r, g, b),
max = Math.max(r, g, b),
delta = max - min,
h = 0, s = 0, v = max;
if (min != max)
{
s = (delta / max);
switch (max)
{
case r: h = (g - b) / delta + (g < b ? 6 : 0); break;
case g: h = (b - r) / delta + 2; break;
case b: h = (r - g) / delta + 4; break;
}
h /= 6;
}
return [h, s, v];
}
function hsvToRgb(h, s, v)
{
var step = h / (1 / 6),
pos = step - Math.floor(step), // the hue position within the current step
m = (Math.floor(step) % 2) ? (1 - pos) * v : pos * v, // mix color value adjusted to the brightness(v)
max = 1 * v,
min = (1 - s) * v,
med = m + ((1 - s) * (v - m)),
r, g, b;
switch (Math.floor(step))
{
case 0:
r = max;
g = med;
b = min;
break;
case 1:
r = med;
g = max;
b = min;
break;
case 2:
r = min;
g = max;
b = med;
break;
case 3:
r = min;
g = med;
b = max;
break;
case 4:
r = med;
g = min;
b = max;
break;
case 5:
r = max;
g = min;
b = med;
break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
Mohsen의 답변의 Unity3D C # 코드.
Unity3D를 대상으로하는 C #의 Mohsen의 답변 코드는 다음과 같습니다. 위의 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);
}
}
Garry Tan 솔루션이 RGB에서 HSL로 잘못 변환한다고 말합니다. 코드에서 숫자의 일부를 생략했기 때문입니다. 그의 코드 (자바 스크립트)를 수정했습니다. 러시아어로 된 링크에 대해 죄송하지만 영어가없는 경우-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) }
};
};
자바 스크립트에서 설정 한 hsl | a 색상 값은 즉시 rgb로 변환됩니다 | 그런 다음 계산 된 스타일 값에 액세스하기 만하면됩니다.
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로 변환하려면 어떻게해야합니까?
@Mohsen 코드보다 성능이 더 좋은 C ++ 구현. 색조에 대해 [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;
}
}
}
[0,1] 범위에서 H, S 및 L 사용시 :
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 };
}
}
나는 정말로 가벼운 무게가 필요했습니다 .100 %는 아니지만 일부 유스 케이스에는 충분히 가까워졌습니다.
float3 Hue(float h, float s, float l)
{
float r = max(cos(h * 2 * UNITY_PI) * 0.5 + 0.5, 0);
float g = max(cos((h + 0.666666) * 2 * UNITY_PI) * 0.5 + 0.5, 0);
float b = max(cos((h + 0.333333) * 2 * UNITY_PI) * 0.5 + 0.5, 0);
float gray = 0.2989 * r + 0.5870 * g + 0.1140 * b;
return lerp(gray, float3(r, g, b), s) * smoothstep(0, 0.5, l) + 1 * smoothstep(0.5, 1, l);
}
다시 게시해서 죄송합니다. 그러나 실제로 필요한 품질을 제공하는 다른 구현을 보지 못했습니다.
/**
* 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 {number} h The hue
* @param {number} s The saturation
* @param {number} l The lightness
* @return {Array} The RGB representation
*/
function hue2rgb($p, $q, $t){
if($t < 0) $t += 1;
if($t > 1) $t -= 1;
if($t < 1/6) return $p + ($q - $p) * 6 * $t;
if($t < 1/2) return $q;
if($t < 2/3) return $p + ($q - $p) * (2/3 - $t) * 6;
return $p;
}
function hslToRgb($h, $s, $l){
if($s == 0){
$r = $l;
$g = $l;
$b = $l; // achromatic
}else{
$q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
$p = 2 * $l - $q;
$r = hue2rgb($p, $q, $h + 1/3);
$g = hue2rgb($p, $q, $h);
$b = hue2rgb($p, $q, $h - 1/3);
}
return array(round($r * 255), round($g * 255), round($b * 255));
}
/* Uncomment to test * /
for ($i=0;$i<360;$i++) {
$rgb=hslToRgb($i/360, 1, .9);
echo '<div style="background-color:rgb(' .$rgb[0] . ', ' . $rgb[1] . ', ' . $rgb[2] . ');padding:2px;"></div>';
}
/* End Test */