0

I need to convert HSL color values to RGB, or to be more precise HSL-values to a System.Drawing.Color object with Powershell. There are a few solutions in other prog.-languages out there (like LINK). But while it looks simple, I dont get it converted it into Powershell.

Function HSLtoRGB ($H,$S,$L) {
    $H = [double]($H / 360)
    $S = [double]($S / 100)
    $L = [double]($L / 100)

     if ($s -eq 0) {
        $r = $g = $b = $l
     }
    else {
        if ($l -lt 0.5){
           $q = $l * (1 + $s) 
        } 
        else {
          $q =  $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))
    }

     $r = [Math]::Round($r * 255)
    $g = [Math]::Round($g * 255)
    $b = [Math]::Round($b * 255)

return ($r,$g,$b)
}


function Hue2rgb ($p, $q, $t) {
    if ($t -lt 0) { $t++ }
    if ($t -gt 0) { $t-- }
    if ($t -lt 1/6) { return ( $p + ($q + $p) * 6 * $t ) }
    if ($t -lt 1/2) { return $q }    
    if ($t -lt 2/3) { return ($p + ($q - $p) * (2/3 - $t) * 6 ) }
     return $p
}


HSLtoRGB 63 45 40       #  result should be R 145  G 148  B 56
Community
  • 1
  • 1
Moss
  • 325
  • 2
  • 16
  • "I dont get it converted it into Powershell" - what have you tried so far? How does it not meet your expectations? – Mathias R. Jessen Apr 23 '16 at 17:10
  • The example function in the answer you linked to works perfectly fine when ported to PowerShell btw – Mathias R. Jessen Apr 23 '16 at 17:28
  • Yeah forgot the code. :) I had doubts at a few lines and one line i could not translate at all (see code). Mainly i dont know what some of the operators mean. – Moss Apr 23 '16 at 17:44

1 Answers1

1

Let's start with the line you're having trouble with translating:

$q =    l < 0.5 ? l * (1 + s) : l + s - l * s;    #could not translate this line

This construct:

statement ? someValue : anotherValue;

is known as a ternary operation. It basically means:

if(statement){
    someValue
} else {
    anotherValue
}

So in PowerShell that becomes:

$q = if($l -lt 0.5){
    $l * (1 + $s) 
} else {
    $l + $s - $l * $s
}

Your translation of the inline Hue2Rgb function has two typos that greatly change the calculation:

function Hue2rgb ($p, $q, $t) {
    if ($t -lt 0) { $t++ }
    if ($t -gt 0) { $t-- } # This condition should be ($t -gt 1)
    if ($t -lt 1/6) { return ( $p + ($q + $p) * 6 * $t ) } # The innermost calculation should be ($q - $p) not ($q + $p)
    if ($t -lt 1/2) { return $q }    
    if ($t -lt 2/3) { return ($p + ($q - $p) * (2/3 - $t) * 6 ) }
    return $p
}

Regarding the input values, if you take a look at the comments in the original script:

* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].

So if you want to pass your input values as degrees (hue) and percentages (saturation + luminance), you'll have to handle a conversion to a relative value between 0 and 1:

Function HSLtoRGB ($H,$S,$L) {
    $H = [double]($H / 360)
    $S = [double]($S / 100)
    $L = [double]($L / 100)

    # rest of script
}

Lastly, you can use Color.FromArgb() to return an actual Color object:

$r = [Math]::Round($r * 255)
$g = [Math]::Round($g * 255)
$b = [Math]::Round($b * 255)

return [System.Drawing.Color]:FromArgb($r,$g,$b)
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • added that, see above. But the result is completely wrong. – Moss Apr 23 '16 at 17:54
  • 1
    You didn't really read the accompanying parameter documentation when you copied the example, did you? :) – Mathias R. Jessen Apr 23 '16 at 17:58
  • still get non-valid values: -546 -954 -138 updated the code – Moss Apr 23 '16 at 18:01
  • 1
    You have a typo in the second conditional in `Hue2rgb`: `if($t -gt 0)` should be `if($t -gt 1)` – Mathias R. Jessen Apr 23 '16 at 18:30
  • Looks good so far. Thank for now. ill check a few values and report back or mark the answer. – Moss Apr 23 '16 at 18:40
  • @Moss You're welcome. For future reference, please avoid continuously updating your code sample, it obscures the original question, making it less valuable to future users/readers – Mathias R. Jessen Apr 23 '16 at 18:43
  • Oddly, **a lot of** HSL - values produce errors, because one of the resulting RGB values is higher than 255, here are a few examples: 48,36,48 // 56,36,48 // 168,36,48 // 176,36,48 // 288,36,48 // – Moss Apr 23 '16 at 21:44
  • Mathias could you take a look please? A lot of values are out pf range and I can not figure out if this is due to a code conversion error or if the source function was already faulty. – Moss Apr 24 '16 at 20:34
  • 1
    @Moss I updated the answer earlier today after noticing another typo in your translation of the `Hue2Rgb` function, please see the 2nd section in my answer – Mathias R. Jessen Apr 24 '16 at 20:47
  • damn i checked that twice today and did not see it. – Moss Apr 24 '16 at 21:25
  • This is starting to drive me crazy. Now the values are in range but completly wrong. `HSLtoRGB 15 20 35` gives me **RGB 107,80,71** but it should be **35,33,32** I checked again for typos and such but I cant find any more errors – Moss Apr 24 '16 at 21:52
  • 1
    @Moss No, I think you've got that wrong. Compare with http://www.rapidtables.com/convert/color/hsl-to-rgb.htm – Mathias R. Jessen Apr 25 '16 at 15:36
  • Interesting. Seems my beloved color picker and conversion tool is wrong. But its odd because Photoshop has also other values, closer to the one of the website-converter but still different. Anyhow, thanks again. – Moss Apr 25 '16 at 15:57