我正在研究一种能够以编程方式将深色主题应用于 HTML/CSS 文件的方法。该过程的一部分是反转所有检测到的颜色,然后将色调旋转 180 度。例如:
第 1 步和第 2 步很简单,但第 3 步让我很困惑,因为我不知道如何去做。
这是我的第 2 步:
$parsedColor = '#123456' # this would normally be automatically parsed from a HTML file
# New StringBuilder object that starts with #
$invertedColor = [Text.StringBuilder]'#'
# Split into groups of 2 characters, ignoring # and empty:
$parsedColor -split '([^#][^#])' -ne '#' -ne '' | &{process{
# Append value to StringBuilder:
$invertedColor.Append(
# Format as hexidecimal string after flipping the bit
'{0:X}' -f ([byte]"0x$_" -bxor 0xFF)
)
# Suppress .Append noise
}} | Out-Null
# Output StringBuilder as String
$invertedColor -as [string]
基于
https://drafts.fxtf.org/filter-effects/#feColorMatrixElement上的 css
hue-rotate
算法参考以及本网站上的一些其他参考...
...在 PowerShell 中应用
hue-rotate
的函数将是这样的:
function Invoke-HueRotate
{
param( [uint] $Color, [decimal] $Degrees )
# split color into r, g and b channels
$r = $Color -shr 16 -band 0xFF;
$g = $Color -shr 8 -band 0xFF;
$b = $Color -shr 0 -band 0xFF;
# convert degrees to radians and evaluate cos / sin
$cos = [Math]::Cos($Degrees * [Math]::PI / 180);
$sin = [Math]::Sin($Degrees * [Math]::PI / 180);
# long-hand matrix definition
# see https://drafts.fxtf.org/filter-effects/#feColorMatrixElement
# where it says 'For type="hueRotate"'
$a00 = 0.213 + ( 0.787 * $cos) + (-0.213 * $sin);
$a01 = 0.715 + (-0.715 * $cos) + (-0.715 * $sin);
$a02 = 0.072 + (-0.072 * $cos) + ( 0.928 * $sin);
$a10 = 0.213 + (-0.213 * $cos) + ( 0.143 * $sin);
$a11 = 0.715 + ( 0.285 * $cos) + ( 0.140 * $sin);
$a12 = 0.072 + (-0.072 * $cos) + (-0.283 * $sin);
$a20 = 0.213 + (-0.213 * $cos) + (-0.787 * $sin);
$a21 = 0.715 + (-0.715 * $cos) + ( 0.715 * $sin);
$a22 = 0.072 + ( 0.928 * $cos) + ( 0.072 * $sin);
# long-hand matrix multiplication
$r2 = ($a00 * $r) + ($a01 * $g) + ($a02 * $b);
$g2 = ($a10 * $r) + ($a11 * $g) + ($a12 * $b);
$b2 = ($a20 * $r) + ($a21 * $g) + ($a22 * $b);
# re-combine r, g and b channels
$result = [uint](
([Math]::Clamp([int]$r2, 0, 255) -shl 16) `
-bor
([Math]::Clamp([int]$g2, 0, 255) -shl 8) `
-bor
([Math]::Clamp([int]$b2, 0, 255) -shl 0) `
);
return $result;
}
(我已经避免使用任何矩阵库以保持其独立性,但是如果您不介意依赖于可以使数学更清晰的东西,则可以简化它。)
如果您还添加以下实用方法:
function Invoke-InvertColor
{
param( [uint] $Color, [decimal] $Degrees )
return $Color -bxor 0xFFFFFF;
}
function ConvertFrom-HtmlColor
{
param( [string] $Value )
return [System.Convert]::ToUInt32($Value.Substring(1), 16);
}
function ConvertTo-HtmlColor
{
param( [uint] $Value )
return "#" + $Value.ToString("X2").PadLeft(6, "0");
}
您可以按如下方式使用它:
$color = "#CC1100"
$original = ConvertFrom-HtmlColor -Value "#CC1100";
ConvertTo-HtmlColor $original;
#CC1100
$inverted = Invoke-InvertColor -Color $original;
ConvertTo-HtmlColor $inverted;
#33EEFF
$rotated = Invoke-HueRotate -Color $inverted -Degrees 180;
ConvertTo-HtmlColor $rotated;
#FFA190
请注意,这会给您的示例带来不同的结果
Invert Hue-rotate 180∘
#CC1100 -> #33EEFF -> #FF4433
但结果似乎与此答案中第一个链接中的公式相符,并获得与其他链接中的实现相同的结果,因此您可能需要详细说明您使用的算法/实现
hue-rotate
如果您追求不同的结果...