Saya mencari algoritma JavaScript / PHP untuk mengkonversi antara warna HSL ke RGB.
Sepertinya saya bahwa HSL tidak banyak digunakan sehingga saya tidak memiliki banyak keberuntungan mencari konverter.
Saya mencari algoritma JavaScript / PHP untuk mengkonversi antara warna HSL ke RGB.
Sepertinya saya bahwa HSL tidak banyak digunakan sehingga saya tidak memiliki banyak keberuntungan mencari konverter.
Jawaban:
Garry Tan memposting solusi Javascript di blog-nya (yang ia atribut untuk mjijackson.com sekarang sudah tidak berfungsi, tetapi diarsipkan di sini dan penulis aslinya memiliki intisari - terima kasih kepada user2441511).
Kode ini diposting ulang di bawah ini:
/**
* 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
memperkenalkan ketidakakuratan kecil pada ujung rendah dan tinggi (nilai 0 dan 255) dari skala. Nilai yang berada di ujung rentang dapat membulatkan ke atas atau ke bawah untuk mencapai nilainya, tetapi nilai hanya dapat dibulatkan ke 0, atau hingga 255. Ini berarti bahwa kisaran nilai yang dipetakan ke 0 dan 255 persis setengah dari mereka untuk nilai-nilai lain. Untuk mengatasinya, gunakan rumus ini sebagai gantinya: min(floor(val*256),255)
. Ini membuat pemetaan hampir sempurna.
h + 1/3
dan h - 1/3
. Dalam banyak bahasa, ini menggunakan pembagian integer, di mana 1/3
nol. untuk mendapatkan hasil yang benar, gunakan liter float sebagai gantinya, yaitu h + 1.0/3.0
. : .
Menemukan cara termudah, python untuk menyelamatkan : D
colorsys.hls_to_rgb(h, l, s)
Ubah warna dari koordinat HLS ke koordinat RGB.
Color::HSL.new(40,50,60).to_rgb
Perhatikan bahwa semua bilangan bulat dinyatakan sebagai float (yaitu 1f) dan harus float, jika tidak, Anda akan memilih warna abu-abu.
/**
* 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;
}
Artikel untuk HSL dan HSV di wikipedia berisi beberapa rumus. Perhitungannya agak rumit, jadi mungkin berguna untuk melihat implementasi yang ada .
Jika Anda mencari sesuatu yang pasti sesuai dengan semantik CSS untuk HSL dan RGB, Anda bisa menggunakan algoritma yang ditentukan dalam spesifikasi CSS 3 , yang berbunyi:
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
Saya percaya ini adalah sumber untuk beberapa jawaban lain di sini.
Ini adalah kode dari jawaban Mohsen di C # jika orang lain menginginkannya. Catatan: Color
adalah kelas khusus dan Vector4
dari OpenTK. Keduanya mudah diganti dengan yang lain yang Anda pilih.
/// <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);
}
Juga dari sini , yang menjelaskan matematika dengan sangat baik.
Ini pada dasarnya adalah sekelompok fungsi untuk mengkonversi ke dan dari HSL (Hue Saturation Lightness)
Diuji dan bekerja pada PHP 5.6.15
TL; DR : Kode lengkap dapat ditemukan di sini di Pastebin .
Input: Warna hex dalam format: [#] 0f4 atau [#] 00ff44 (tanda pound opsional)
Output: HSL dalam Derajat, Persen, Persen
/**
* 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;
}
Input: RGB dalam kisaran 0-255 Output: HSL dalam Derajat, Persen, Persen.
/**
*
*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;
}
Untuk perhitungan matematika, HSL lebih mudah ditangani dalam kisaran 0-1, tetapi untuk keterbacaan manusia, lebih mudah dalam Derajat, Persen, Persen. Fungsi ini mengambil HSL dalam rentang 0-1, dan mengembalikan HSL dalam Derajat, Persen, Persen.
/**
* 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;
}
Fungsi ini mengubah HSL dalam format Derajat, Persen, Persen, ke rentang 0-1 untuk komputasi yang lebih mudah.
/**
* 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;
}
Input: HSL dalam format Derajat, Persen, Persen Output: RGB dalam format 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;
}
Fungsi ini disebut oleh hslToRgb untuk mengubah rona menjadi nilai RGB yang terpisah.
/**
* 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;
}
Input: HSL dalam format Derajat, Persen, Persen Output: Hex dalam format 00ff22
(tanpa tanda pound).
Konversi ke RGB, lalu konversi secara terpisah ke hex.
/**
* 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
, Anda mungkin ingin memperbarui kode php Anda. Ada / ada bug dalam kode. Dalam rgbToHsl () s = maxSub / (2 - maxSub)
haruss = maxSub / (2 - maxAdd)
(2 - maxSub) = 1.7333333333333334
ketika seharusnya seperti pada contoh tautan kedua ( 2 - max - min ) = 0.6352941176470588
. Menggunakan 2 - maxAdd
membuat saya lebih dekat secara konsisten dengan hasil pemotretan jadi saya menganggap itu benar.
Ini adalah bagaimana saya melakukannya yang mudah diingat adalah menganggap RGB sebagai tiga jari pada roda, berjarak 120 derajat.
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
Bagian yang sulit adalah saturasi, yang turun ke rata-rata dari ketiganya.
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
+
, -
, *
, dan /
) - seperti yang digunakan oleh definisi untuk konversi warna - untuk mengekspresikan mereka dengan bantuan dari sine
fungsi dengan independen yang sama (input) variabel. Meskipun demikian, itu bagus untuk memahami prinsip (tetapi tidak untuk melakukan konversi).
(R1 + G1 + B1) = L*[ SIN(H) + SIN(H+120) + SIN(H+240) ]
- dan sekarang jika kita menggunakan rumus sin(a)+sin(b) = 2*sin((a+b)/2)*cos((a-b)/2)
untuk dua dosa pertama kita dapatkan: AVERAGE=L*( sin(h+60) + sin(h+240) )
dan lagi AVERAGE= L*2*sin(h+150)*cos(-180/2) = 0
(karena cos (-180/2) = cos (90) = 0). Jadi perhitungan saturasi salah dan sebenarnya saturasi bekerja di sini sebagai luminance.
Berikut ini adalah versi cepat, super-sederhana, tanpa cabang di 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));
}
Tidak jauh lebih pendek dari itu ~
Tautan ke bukti-konsep asli: https://www.shadertoy.com/view/XljGzV
(Penafian: bukan kode saya!)
Ini adalah fungsi javascript yang dimodifikasi, menghasilkan Hue pada set 0-360 derajat.
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));
Saya mendapatkan ini dari kode sumber HSL Picker Brandon Mathis .
Itu aslinya ditulis dalam CoffeeScript . Saya mengonversinya ke JavaScript menggunakan konverter online, dan mengeluarkan mekanisme untuk memverifikasi input pengguna adalah nilai RGB yang valid. Jawaban ini berhasil untuk usecase saya, karena jawaban yang paling banyak dipilih pada posting ini saya temukan tidak menghasilkan nilai HSL yang valid.
Perhatikan bahwa itu mengembalikan hsla
nilai, dengan a
mewakili opacity / transparansi. 0
sepenuhnya transparan, dan 1
sepenuhnya buram.
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];
}
Untuk saat Anda membutuhkan RGB ke HSV dan sebaliknya:
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)];
}
Unity3D C # Kode dari jawaban Mohsen.
Ini adalah kode dari jawaban Mohsen di C # yang ditargetkan khusus untuk Unity3D. Itu diadaptasi dari jawaban C # yang diberikan oleh Alec Thilenius di atas.
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);
}
}
Untuk semua yang mengatakan bahwa solusi Garry Tan mengubah salah dari RGB ke HSL dan kembali. Itu karena dia meninggalkan sebagian kecil dari angka dalam kodenya. Saya mengoreksi kodenya (javascript). Maaf untuk tautan di languadge Rusia, tetapi tidak ada bahasa Inggris - 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) }
};
};
Nilai hsl | a, yang diatur dalam javascript, akan langsung dikonversi ke rgb | a Yang perlu Anda lakukan adalah mengakses nilai gaya yang dihitung
document.body.style.color = 'hsla(44, 100%, 50%, 0.8)';
console.log(window.getComputedStyle(document.body).color);
// displays: rgba(255, 187, 0, 0.8)
Secara teknis, saya kira, ini bahkan tidak ada baris kode - itu hanya dilakukan secara otomatis. Jadi, tergantung pada lingkungan Anda, Anda mungkin bisa lolos begitu saja. Bukan berarti tidak ada banyak tanggapan yang sangat bijaksana di sini. Saya tidak tahu apa tujuan Anda.
Sekarang, bagaimana jika Anda ingin mengkonversi dari rbg | a ke hsl | a?
Implementasi C ++ dengan kinerja yang mungkin lebih baik daripada kode @Mohsen. Menggunakan rentang [0-6] untuk rona, menghindari pembagian dan perkalian dengan 6. S dan rentang L adalah [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;
}
}
}
Dengan H, S, dan L dalam kisaran [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 };
}
}
Saya membutuhkan yang sangat ringan, tidak 100%, tetapi cukup dekat untuk beberapa penggunaan.
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);
}
Maaf memposting ulang ini. Tetapi saya benar-benar belum melihat implementasi lain yang memberikan kualitas yang saya butuhkan.
/**
* 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 */