问题
I'm trying to convert a RGB32 value to HSL because I want to use the Hue component.
I have used some examples that I found online to create this class:
public class HSLColor
{
public Double Hue;
public Double Saturation;
public Double Luminosity;
public HSLColor(Double H, Double S, Double L)
{
Hue = H;
Saturation = S;
Luminosity = L;
}
public static HSLColor FromRGB(Color Clr)
{
return FromRGB(Clr.R, Clr.G, Clr.B);
}
public static HSLColor FromRGB(Byte R, Byte G, Byte B)
{
Double _R = (R / 255d);
Double _G = (G / 255d);
Double _B = (B / 255d);
Double _Min = Math.Min(Math.Min(_R, _G), _B);
Double _Max = Math.Max(Math.Max(_R, _G), _B);
Double _Delta = _Max - _Min;
Double H = 0;
Double S = 0;
Double L = (float)((_Max + _Min) / 2.0f);
if (_Delta != 0)
{
if (L < 0.5d)
{
S = (float)(_Delta / (_Max + _Min));
}
else
{
S = (float)(_Delta / (2.0f - _Max - _Min));
}
if (_R == _Max)
{
H = (_G - _B) / _Delta;
}
else if (_G == _Max)
{
H = 2f + (_B - _R) / _Delta;
}
else if (_B == _Max)
{
H = 4f + (_R - _G) / _Delta;
}
}
//Convert to degrees
H = H * 60d;
if (H < 0) H += 360;
//Convert to percent
S *= 100d;
L *= 100d;
return new HSLColor(H, S, L);
}
private Double Hue_2_RGB(Double v1, Double v2, Double vH)
{
if (vH < 0) vH += 1;
if (vH > 1) vH -= 1;
if ((6.0d * vH) < 1) return (v1 + (v2 - v1) * 6 * vH);
if ((2.0d * vH) < 1) return (v2);
if ((3.0d * vH) < 2) return (v1 + (v2 - v1) * ((2.0d / 3.0d) - vH) * 6.0d);
return (v1);
}
public Color ToRGB()
{
Color Clr = new Color();
Double var_1, var_2;
if (Saturation == 0)
{
Clr.R = (Byte)(Luminosity * 255);
Clr.G = (Byte)(Luminosity * 255);
Clr.B = (Byte)(Luminosity * 255);
}
else
{
if (Luminosity < 0.5) var_2 = Luminosity * (1 + Saturation);
else var_2 = (Luminosity + Saturation) - (Saturation * Luminosity);
var_1 = 2 * Luminosity - var_2;
Clr.R = (Byte)(255 * Hue_2_RGB(var_1, var_2, Hue + (1 / 3)));
Clr.G = (Byte)(255 * Hue_2_RGB(var_1, var_2, Hue));
Clr.B = (Byte)(255 * Hue_2_RGB(var_1, var_2, Hue - (1 / 3)));
}
return Clr;
}
}
However it doesn't seem to work correctly,
If I use an input color of (R 0, G 255, B 193)
for example:
I get Hue = 0
while in photoshop if I choose the exact same RGB values I get:
Hue = 165
which is the correct value.
I want the Hue to be a value ranging from 0 to 360 or 0 to 240
What is the problem?..
Reference: EasyRGB RGB->HSL
回答1:
The below is open source mixture of Drupal + some various programmers work mixed into one single function boasting RGB > HSL and back. It works flawlessly.
<?php
### RGB >> HSL
function _color_rgb2hsl($rgb) {
$r = $rgb[0]; $g = $rgb[1]; $b = $rgb[2];
$min = min($r, min($g, $b)); $max = max($r, max($g, $b));
$delta = $max - $min; $l = ($min + $max) / 2; $s = 0;
if ($l > 0 && $l < 1) {
$s = $delta / ($l < 0.5 ? (2 * $l) : (2 - 2 * $l));
}
$h = 0;
if ($delta > 0) {
if ($max == $r && $max != $g) $h += ($g - $b) / $delta;
if ($max == $g && $max != $b) $h += (2 + ($b - $r) / $delta);
if ($max == $b && $max != $r) $h += (4 + ($r - $g) / $delta);
$h /= 6;
} return array($h, $s, $l);
}
### HSL >> RGB
function _color_hsl2rgb($hsl) {
$h = $hsl[0]; $s = $hsl[1]; $l = $hsl[2];
$m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l*$s;
$m1 = $l * 2 - $m2;
return array(_color_hue2rgb($m1, $m2, $h + 0.33333),
_color_hue2rgb($m1, $m2, $h),
_color_hue2rgb($m1, $m2, $h - 0.33333));
}
### Helper function for _color_hsl2rgb().
function _color_hue2rgb($m1, $m2, $h) {
$h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $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) * (0.66666 - $h) * 6;
return $m1;
}
### Convert a hex color into an RGB triplet.
function _color_unpack($hex, $normalize = false) {
if (strlen($hex) == 4) {
$hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3];
} $c = hexdec($hex);
for ($i = 16; $i >= 0; $i -= 8) {
$out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1);
} return $out;
}
### Convert an RGB triplet to a hex color.
function _color_pack($rgb, $normalize = false) {
foreach ($rgb as $k => $v) {
$out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8));
}return '#'. str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
}
print "Hex: ";
$testhex = "#b7b700";
print $testhex;
$testhex2rgb = _color_unpack($testhex,true);
print "<br />RGB: ";
var_dump($testhex2rgb);
print "<br />HSL color module: ";
$testrgb2hsl = _color_rgb2hsl($testhex2rgb); //Convert to HSL
var_dump($testrgb2hsl);
print "<br />RGB: ";
$testhsl2rgb = _color_hsl2rgb($testrgb2hsl); // And back to RGB
var_dump($testhsl2rgb);
print "<br />Hex: ";
$testrgb2hex = _color_pack($testhsl2rgb,true);
var_dump($testrgb2hex);
?>
回答2:
R / 255
this is integer division, meaning you get either 0 or 1. try:
(float)R / 255
and for all other cases.
for constants try:
( 1 / 3 ) -> ( 1.0 / 3.0 )
来源:https://stackoverflow.com/questions/4784040/rgb-to-hsl-hue-calculation-is-wrong