Powershell:HSL到RGB

时间:2016-04-23 16:50:59

标签: powershell rgb hsl

我需要将HSL颜色值转换为RGB,或者使用 Powershell 将更精确的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

1 个答案:

答案 0 :(得分:1)

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

$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()返回实际的Color对象:

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

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