Powershell:HSL 到 RGB

Powershell: HSL to RGB

我需要将 HSL 颜色值转换为 RGB,或者更准确地说,使用 Powershell[=18= 将 HSL 值转换为 System.Drawing.Color 对象]. 在其他编程语言中有一些解决方案(比如 LINK)。但是虽然它看起来很简单,但我没有将它转换成 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

让我们从您在翻译时遇到问题的行开始:

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

这个结构:

statement ? someValue : anotherValue;

被称为 ternary operation。它基本上意味着:

if(statement){
    someValue
} else {
    anotherValue
}

因此在 PowerShell 中变为:

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

您对内联 Hue2Rgb 函数的翻译有两个错别字,大大改变了计算方式:

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
}

关于输入值,如果你看一下原始脚本中的注释:

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

因此,如果您想将输入值作为度数(色调)和百分比(饱和度 + 亮度)传递,则必须处理转换为 0 到 1 之间的相对值:

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

    # rest of script
}

最后,您可以使用 Color.FromArgb() 来 return 一个实际的 Color 对象:

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

return [System.Drawing.Color]:FromArgb($r,$g,$b)