Private/Console/Colors.psm1
|
using namespace System using namespace System.Globalization using namespace System.Collections.Generic using module ..\Enums.psm1 using module ..\Abstracts.psm1 class ColorTable { static hidden [byte[]] $RgbData = @(0, 0, 0, 128, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 128, 128, 0, 128, 0, 128, 128, 192, 192, 192, 128, 128, 128, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0, 0, 255, 255, 0, 255, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 95, 0, 0, 135, 0, 0, 175, 0, 0, 215, 0, 0, 255, 0, 95, 0, 0, 95, 95, 0, 95, 135, 0, 95, 175, 0, 95, 215, 0, 95, 255, 0, 135, 0, 0, 135, 95, 0, 135, 135, 0, 135, 175, 0, 135, 215, 0, 135, 255, 0, 175, 0, 0, 175, 95, 0, 175, 135, 0, 175, 175, 0, 175, 215, 0, 175, 255, 0, 215, 0, 0, 215, 95, 0, 215, 135, 0, 215, 175, 0, 215, 215, 0, 215, 255, 0, 255, 0, 0, 255, 95, 0, 255, 135, 0, 255, 175, 0, 255, 215, 0, 255, 255, 95, 0, 0, 95, 0, 95, 95, 0, 135, 95, 0, 175, 95, 0, 215, 95, 0, 255, 95, 95, 0, 95, 95, 95, 95, 95, 135, 95, 95, 175, 95, 95, 215, 95, 95, 255, 95, 135, 0, 95, 135, 95, 95, 135, 135, 95, 135, 175, 95, 135, 215, 95, 135, 255, 95, 175, 0, 95, 175, 95, 95, 175, 135, 95, 175, 175, 95, 175, 215, 95, 175, 255, 95, 215, 0, 95, 215, 95, 95, 215, 135, 95, 215, 175, 95, 215, 215, 95, 215, 255, 95, 255, 0, 95, 255, 95, 95, 255, 135, 95, 255, 175, 95, 255, 215, 95, 255, 255, 135, 0, 0, 135, 0, 95, 135, 0, 135, 135, 0, 175, 135, 0, 215, 135, 0, 255, 135, 95, 0, 135, 95, 95, 135, 95, 135, 135, 95, 175, 135, 95, 215, 135, 95, 255, 135, 135, 0, 135, 135, 95, 135, 135, 135, 135, 135, 175, 135, 135, 215, 135, 135, 255, 135, 175, 0, 135, 175, 95, 135, 175, 135, 135, 175, 175, 135, 175, 215, 135, 175, 255, 135, 215, 0, 135, 215, 95, 135, 215, 135, 135, 215, 175, 135, 215, 215, 135, 215, 255, 135, 255, 0, 135, 255, 95, 135, 255, 135, 135, 255, 175, 135, 255, 215, 135, 255, 255, 175, 0, 0, 175, 0, 95, 175, 0, 135, 175, 0, 175, 175, 0, 215, 175, 0, 255, 175, 95, 0, 175, 95, 95, 175, 95, 135, 175, 95, 175, 175, 95, 215, 175, 95, 255, 175, 135, 0, 175, 135, 95, 175, 135, 135, 175, 135, 175, 175, 135, 215, 175, 135, 255, 175, 175, 0, 175, 175, 95, 175, 175, 135, 175, 175, 175, 175, 175, 215, 175, 175, 255, 175, 215, 0, 175, 215, 95, 175, 215, 135, 175, 215, 175, 175, 215, 215, 175, 215, 255, 175, 255, 0, 175, 255, 95, 175, 255, 135, 175, 255, 175, 175, 255, 215, 175, 255, 255, 215, 0, 0, 215, 0, 95, 215, 0, 135, 215, 0, 175, 215, 0, 215, 215, 0, 255, 215, 95, 0, 215, 95, 95, 215, 95, 135, 215, 95, 175, 215, 95, 215, 215, 95, 255, 215, 135, 0, 215, 135, 95, 215, 135, 135, 215, 135, 175, 215, 135, 215, 215, 135, 255, 215, 175, 0, 215, 175, 95, 215, 175, 135, 215, 175, 175, 215, 175, 215, 215, 175, 255, 215, 215, 0, 215, 215, 95, 215, 215, 135, 215, 215, 175, 215, 215, 215, 215, 215, 255, 215, 255, 0, 215, 255, 95, 215, 255, 135, 215, 255, 175, 215, 255, 215, 215, 255, 255, 255, 0, 0, 255, 0, 95, 255, 0, 135, 255, 0, 175, 255, 0, 215, 255, 0, 255, 255, 95, 0, 255, 95, 95, 255, 95, 135, 255, 95, 175, 255, 95, 215, 255, 95, 255, 255, 135, 0, 255, 135, 95, 255, 135, 135, 255, 135, 175, 255, 135, 215, 255, 135, 255, 255, 175, 0, 255, 175, 95, 255, 175, 135, 255, 175, 175, 255, 175, 215, 255, 175, 255, 255, 215, 0, 255, 215, 95, 255, 215, 135, 255, 215, 175, 255, 215, 215, 255, 215, 255, 255, 255, 0, 255, 255, 95, 255, 255, 135, 255, 255, 175, 255, 255, 215, 255, 255, 255, 8, 8, 8, 18, 18, 18, 28, 28, 28, 38, 38, 38, 48, 48, 48, 58, 58, 58, 68, 68, 68, 78, 78, 78, 88, 88, 88, 98, 98, 98, 108, 108, 108, 118, 118, 118, 128, 128, 128, 138, 138, 138, 148, 148, 148, 158, 158, 158, 168, 168, 168, 178, 178, 178, 188, 188, 188, 198, 198, 198, 208, 208, 208, 218, 218, 218, 228, 228, 228, 238, 238, 238) static hidden [string[]] $Names = @('Black', 'Maroon', 'Green', 'Olive', 'Navy', 'Purple', 'Teal', 'Silver', 'Grey', 'Red', 'Lime', 'Yellow', 'Blue', 'Fuchsia', 'Aqua', 'White', 'Grey0', 'NavyBlue', 'DarkBlue', 'Blue3', 'Blue3', 'Blue1', 'DarkGreen', 'DeepSkyBlue4', 'DeepSkyBlue4', 'DeepSkyBlue4', 'DodgerBlue3', 'DodgerBlue2', 'Green4', 'SpringGreen4', 'Turquoise4', 'DeepSkyBlue3', 'DeepSkyBlue3', 'DodgerBlue1', 'Green3', 'SpringGreen3', 'DarkCyan', 'LightSeaGreen', 'DeepSkyBlue2', 'DeepSkyBlue1', 'Green3', 'SpringGreen3', 'SpringGreen2', 'Cyan3', 'DarkTurquoise', 'Turquoise2', 'Green1', 'SpringGreen2', 'SpringGreen1', 'MediumSpringGreen', 'Cyan2', 'Cyan1', 'DarkRed', 'DeepPink4', 'Purple4', 'Purple4', 'Purple3', 'BlueViolet', 'Orange4', 'Grey37', 'MediumPurple4', 'SlateBlue3', 'SlateBlue3', 'RoyalBlue1', 'Chartreuse4', 'DarkSeaGreen4', 'PaleTurquoise4', 'SteelBlue', 'SteelBlue3', 'CornflowerBlue', 'Chartreuse3', 'DarkSeaGreen4', 'CadetBlue', 'CadetBlue', 'SkyBlue3', 'SteelBlue1', 'Chartreuse3', 'PaleGreen3', 'SeaGreen3', 'Aquamarine3', 'MediumTurquoise', 'SteelBlue1', 'Chartreuse2', 'SeaGreen2', 'SeaGreen1', 'SeaGreen1', 'Aquamarine1', 'DarkSlateGray2', 'DarkRed', 'DeepPink4', 'DarkMagenta', 'DarkMagenta', 'DarkViolet', 'Purple', 'Orange4', 'LightPink4', 'Plum4', 'MediumPurple3', 'MediumPurple3', 'SlateBlue1', 'Yellow4', 'Wheat4', 'Grey53', 'LightSlateGrey', 'MediumPurple', 'LightSlateBlue', 'Yellow4', 'DarkOliveGreen3', 'DarkSeaGreen', 'LightSkyBlue3', 'LightSkyBlue3', 'SkyBlue2', 'Chartreuse2', 'DarkOliveGreen3', 'PaleGreen3', 'DarkSeaGreen3', 'DarkSlateGray3', 'SkyBlue1', 'Chartreuse1', 'LightGreen', 'LightGreen', 'PaleGreen1', 'Aquamarine1', 'DarkSlateGray1', 'Red3', 'DeepPink4', 'MediumVioletRed', 'Magenta3', 'DarkViolet', 'Purple', 'DarkOrange3', 'IndianRed', 'HotPink3', 'MediumOrchid3', 'MediumOrchid', 'MediumPurple2', 'DarkGoldenrod', 'LightSalmon3', 'RosyBrown', 'Grey63', 'MediumPurple2', 'MediumPurple1', 'Gold3', 'DarkKhaki', 'NavajoWhite3', 'Grey69', 'LightSteelBlue3', 'LightSteelBlue', 'Yellow3', 'DarkOliveGreen3', 'DarkSeaGreen3', 'DarkSeaGreen2', 'LightCyan3', 'LightSkyBlue1', 'GreenYellow', 'DarkOliveGreen2', 'PaleGreen1', 'DarkSeaGreen2', 'DarkSeaGreen1', 'PaleTurquoise1', 'Red3', 'DeepPink3', 'DeepPink3', 'Magenta3', 'Magenta3', 'Magenta2', 'DarkOrange3', 'IndianRed', 'HotPink3', 'HotPink2', 'Orchid', 'MediumOrchid1', 'Orange3', 'LightSalmon3', 'LightPink3', 'Pink3', 'Plum3', 'Violet', 'Gold3', 'LightGoldenrod3', 'Tan', 'MistyRose3', 'Thistle3', 'Plum2', 'Yellow3', 'Khaki3', 'LightGoldenrod2', 'LightYellow3', 'Grey84', 'LightSteelBlue1', 'Yellow2', 'DarkOliveGreen1', 'DarkOliveGreen1', 'DarkSeaGreen1', 'Honeydew2', 'LightCyan1', 'Red1', 'DeepPink2', 'DeepPink1', 'DeepPink1', 'Magenta2', 'Magenta1', 'OrangeRed1', 'IndianRed1', 'IndianRed1', 'HotPink', 'HotPink', 'MediumOrchid1', 'DarkOrange', 'Salmon1', 'LightCoral', 'PaleVioletRed1', 'Orchid2', 'Orchid1', 'Orange1', 'SandyBrown', 'LightSalmon1', 'LightPink1', 'Pink1', 'Plum1', 'Gold1', 'LightGoldenrod2', 'LightGoldenrod2', 'NavajoWhite1', 'MistyRose1', 'Thistle1', 'Yellow1', 'LightGoldenrod1', 'Khaki1', 'Wheat1', 'Cornsilk1', 'Grey100', 'Grey3', 'Grey7', 'Grey11', 'Grey15', 'Grey19', 'Grey23', 'Grey27', 'Grey30', 'Grey35', 'Grey39', 'Grey42', 'Grey46', 'Grey50', 'Grey54', 'Grey58', 'Grey62', 'Grey66', 'Grey70', 'Grey74', 'Grey78', 'Grey82', 'Grey85', 'Grey89', 'Grey93') static hidden [System.Collections.Generic.Dictionary[string, int]] $NameToNumber static [Color] GetColor([int]$number) { if ($number -lt 0 -or $number -gt 255) { throw "Color number must be between 0 and 255" } $offset = $number * 3 return [Color]::new([ColorTable]::RgbData[$offset], [ColorTable]::RgbData[$offset + 1], [ColorTable]::RgbData[$offset + 2], $number, $false) } static [Color] GetColor([string]$name) { if ($null -eq [ColorTable]::NameToNumber) { $dict = [System.Collections.Generic.Dictionary[string, int]]::new([StringComparer]::OrdinalIgnoreCase) for ($i = 0; $i -lt [ColorTable]::Names.Count; $i++) { if (!$dict.ContainsKey([ColorTable]::Names[$i])) { $dict.Add([ColorTable]::Names[$i], $i) } } [ColorTable]::NameToNumber = $dict } if ([ColorTable]::NameToNumber.ContainsKey($name)) { return [ColorTable]::GetColor([ColorTable]::NameToNumber[$name]) } return $null } static [string] GetName([int]$number) { if ($number -ge 0 -and $number -lt [ColorTable]::Names.Count) { return [ColorTable]::Names[$number] } return $null } } class Color { [byte]$R [byte]$G [byte]$B [Nullable[byte]]$Number [bool]$IsDefault static [Color] $Default static Color() { [Color]::Default = [Color]::new(0, 0, 0, $null, $true) } Color() {} Color([byte]$r, [byte]$g, [byte]$b) { $this.R = $r $this.G = $g $this.B = $b $this.IsDefault = $false $this.Number = $null } Color([byte]$r, [byte]$g, [byte]$b, [Nullable[byte]]$number, [bool]$isDefault) { $this.R = $r $this.G = $g $this.B = $b $this.Number = $number $this.IsDefault = $isDefault } Color([string]$colorOrHex) { if ([string]::IsNullOrWhiteSpace($colorOrHex)) { $this.IsDefault = $true return } $c = if ($colorOrHex.StartsWith("#")) { [Color]::FromHex($colorOrHex) } else { [Color]::FromName($colorOrHex) } if ($null -eq $c) { throw "Unknown color: '$colorOrHex'" } $this.R = $c.R $this.G = $c.G $this.B = $c.B $this.Number = $c.Number $this.IsDefault = $c.IsDefault } [string] ToHex() { return "{0:X2}{1:X2}{2:X2}" -f $this.R, $this.G, $this.B } [string] ToMarkup() { if ($this.IsDefault) { return "default" } if ($null -ne $this.Number) { $name = [ColorTable]::GetName($this.Number) if (-not [string]::IsNullOrWhiteSpace($name)) { return $name } } return "#" + $this.ToHex() } [string] ToString() { return $this.ToMarkup() } [bool] Equals([object]$other) { if ($null -eq $other -or $other.GetType().Name -ne 'Color') { return $false } $otherColor = [Color]$other if ($this.IsDefault -and $otherColor.IsDefault) { return $true } return $this.IsDefault -eq $otherColor.IsDefault -and $this.R -eq $otherColor.R -and $this.G -eq $otherColor.G -and $this.B -eq $otherColor.B } [Color] ExactOrClosest([ColorSystem]$system) { if ($this.IsDefault) { return [Color]::Default } $max = switch ($system) { ([ColorSystem]::Legacy) { 7 } ([ColorSystem]::Standard) { 15 } ([ColorSystem]::EightBit) { 255 } ([ColorSystem]::TrueColor) { return $this } default { return [Color]::Default } } if ($null -ne $this.Number -and $this.Number -le $max) { return $this } $closest = [ColorTable]::GetColor(0) $bestDistance = [double]::PositiveInfinity for ($index = 0; $index -le $max; $index++) { $candidate = [ColorTable]::GetColor($index) $dr = [double]$this.R - [double]$candidate.R $dg = [double]$this.G - [double]$candidate.G $db = [double]$this.B - [double]$candidate.B $distance = ($dr * $dr) + ($dg * $dg) + ($db * $db) if ($distance -lt $bestDistance) { $bestDistance = $distance $closest = $candidate } } return $closest } static [Color] FromInt32([int]$number) { return [ColorTable]::GetColor($number) } static [Color] FromHex([string]$hex) { if ($hex.StartsWith("#")) { $hex = $hex.Substring(1) } if ($hex.Length -eq 3) { $hex = "$($hex[0])$($hex[0])$($hex[1])$($hex[1])$($hex[2])$($hex[2])" } $_r = [byte]::Parse($hex.Substring(0, 2), [NumberStyles]::HexNumber) $_g = [byte]::Parse($hex.Substring(2, 2), [NumberStyles]::HexNumber) $_b = [byte]::Parse($hex.Substring(4, 2), [NumberStyles]::HexNumber) return [Color]::new($_r, $_g, $_b) } static [Color] FromName([string]$name) { return [ColorTable]::GetColor($name) } static [Color] FromConsoleColor([ConsoleColor]$color) { $c = switch ($color) { ([ConsoleColor]::Black) { [ColorTable]::GetColor(0); break } ([ConsoleColor]::DarkRed) { [ColorTable]::GetColor(1); break } ([ConsoleColor]::DarkGreen) { [ColorTable]::GetColor(2); break } ([ConsoleColor]::DarkYellow) { [ColorTable]::GetColor(3); break } ([ConsoleColor]::DarkBlue) { [ColorTable]::GetColor(4); break } ([ConsoleColor]::DarkMagenta) { [ColorTable]::GetColor(5); break } ([ConsoleColor]::DarkCyan) { [ColorTable]::GetColor(6); break } ([ConsoleColor]::Gray) { [ColorTable]::GetColor(7); break } ([ConsoleColor]::DarkGray) { [ColorTable]::GetColor(8); break } ([ConsoleColor]::Red) { [ColorTable]::GetColor(9); break } ([ConsoleColor]::Green) { [ColorTable]::GetColor(10); break } ([ConsoleColor]::Yellow) { [ColorTable]::GetColor(11); break } ([ConsoleColor]::Blue) { [ColorTable]::GetColor(12); break } ([ConsoleColor]::Magenta) { [ColorTable]::GetColor(13); break } ([ConsoleColor]::Cyan) { [ColorTable]::GetColor(14); break } ([ConsoleColor]::White) { [ColorTable]::GetColor(15); break } default { [Color]::Default; break } } return $c } } # .EXAMPLE # [rgb]"AntiqueWhite" # Red Green Blue # --- ----- ---- # 250 235 215 class RGB { [ValidateRange(0, 255)] hidden [int]$_Red [ValidateRange(0, 255)] hidden [int]$_Green [ValidateRange(0, 255)] hidden [int]$_Blue static [rgb] $Red = [rgb]::new(255, 0, 0) static [rgb] $DarkRed = [rgb]::new(128, 0, 0) static [rgb] $Green = [rgb]::new(0, 255, 0) static [rgb] $DarkGreen = [rgb]::new(0, 128, 0) static [rgb] $Blue = [rgb]::new(0, 0, 255) static [rgb] $DarkBlue = [rgb]::new(0, 0, 128) static [rgb] $White = [rgb]::new(255, 255, 255) static [rgb] $Black = [rgb]::new(0, 0, 0) static [rgb] $Yellow = [rgb]::new(255, 255, 0) static [rgb] $DarkGray = [rgb]::new(128, 128, 128) static [rgb] $Gray = [rgb]::new(192, 192, 192) static [rgb] $LightGray = [rgb]::new(238, 237, 240) static [rgb] $Cyan = [rgb]::new(0, 255, 255) static [rgb] $DarkCyan = [rgb]::new(0, 128, 128) static [rgb] $Magenta = [rgb]::new(255, 0, 255) static [rgb] $PSBlue = [rgb]::new(1, 36, 86) static [rgb] $AliceBlue = [rgb]::new(240, 248, 255) static [rgb] $AntiqueWhite = [rgb]::new(250, 235, 215) static [rgb] $AquaMarine = [rgb]::new(127, 255, 212) static [rgb] $Azure = [rgb]::new(240, 255, 255) static [rgb] $Beige = [rgb]::new(245, 245, 220) static [rgb] $Bisque = [rgb]::new(255, 228, 196) static [rgb] $BlanchedAlmond = [rgb]::new(255, 235, 205) static [rgb] $BlueViolet = [rgb]::new(138, 43, 226) static [rgb] $Brown = [rgb]::new(165, 42, 42) static [rgb] $Burlywood = [rgb]::new(222, 184, 135) static [rgb] $CadetBlue = [rgb]::new(95, 158, 160) static [rgb] $Chartreuse = [rgb]::new(127, 255, 0) static [rgb] $Chocolate = [rgb]::new(210, 105, 30) static [rgb] $Coral = [rgb]::new(255, 127, 80) static [rgb] $CornflowerBlue = [rgb]::new(100, 149, 237) static [rgb] $CornSilk = [rgb]::new(255, 248, 220) static [rgb] $Crimson = [rgb]::new(220, 20, 60) static [rgb] $DarkGoldenrod = [rgb]::new(184, 134, 11) static [rgb] $DarkKhaki = [rgb]::new(189, 183, 107) static [rgb] $DarkMagenta = [rgb]::new(139, 0, 139) static [rgb] $DarkOliveGreen = [rgb]::new(85, 107, 47) static [rgb] $DarkOrange = [rgb]::new(255, 140, 0) static [rgb] $DarkOrchid = [rgb]::new(153, 50, 204) static [rgb] $DarkSalmon = [rgb]::new(233, 150, 122) static [rgb] $DarkSeaGreen = [rgb]::new(143, 188, 143) static [rgb] $DarkSlateBlue = [rgb]::new(72, 61, 139) static [rgb] $DarkSlateGray = [rgb]::new(47, 79, 79) static [rgb] $DarkTurquoise = [rgb]::new(0, 206, 209) static [rgb] $DarkViolet = [rgb]::new(148, 0, 211) static [rgb] $DeepPink = [rgb]::new(255, 20, 147) static [rgb] $DeepSkyBlue = [rgb]::new(0, 191, 255) static [rgb] $DimGray = [rgb]::new(105, 105, 105) static [rgb] $DodgerBlue = [rgb]::new(30, 144, 255) static [rgb] $FireBrick = [rgb]::new(178, 34, 34) static [rgb] $FloralWhite = [rgb]::new(255, 250, 240) static [rgb] $ForestGreen = [rgb]::new(34, 139, 34) static [rgb] $GainsBoro = [rgb]::new(220, 220, 220) static [rgb] $GhostWhite = [rgb]::new(248, 248, 255) static [rgb] $Gold = [rgb]::new(255, 215, 0) static [rgb] $Goldenrod = [rgb]::new(218, 165, 32) static [rgb] $GreenYellow = [rgb]::new(173, 255, 47) static [rgb] $HoneyDew = [rgb]::new(240, 255, 240) static [rgb] $HotPink = [rgb]::new(255, 105, 180) static [rgb] $IndianRed = [rgb]::new(205, 92, 92) static [rgb] $Indigo = [rgb]::new(75, 0, 130) static [rgb] $Ivory = [rgb]::new(255, 255, 240) static [rgb] $Khaki = [rgb]::new(240, 230, 140) static [rgb] $Lavender = [rgb]::new(230, 230, 250) static [rgb] $LavenderBlush = [rgb]::new(255, 240, 245) static [rgb] $LawnGreen = [rgb]::new(124, 252, 0) static [rgb] $LemonChiffon = [rgb]::new(255, 250, 205) static [rgb] $LightBlue = [rgb]::new(173, 216, 230) static [rgb] $LightCoral = [rgb]::new(240, 128, 128) static [rgb] $LightCyan = [rgb]::new(224, 255, 255) static [rgb] $LightGoldenrodYellow = [rgb]::new(250, 250, 210) static [rgb] $LightPink = [rgb]::new(255, 182, 193) static [rgb] $LightSalmon = [rgb]::new(255, 160, 122) static [rgb] $LightSeaGreen = [rgb]::new(32, 178, 170) static [rgb] $LightSkyBlue = [rgb]::new(135, 206, 250) static [rgb] $LightSlateGray = [rgb]::new(119, 136, 153) static [rgb] $LightSteelBlue = [rgb]::new(176, 196, 222) static [rgb] $LightYellow = [rgb]::new(255, 255, 224) static [rgb] $LimeGreen = [rgb]::new(50, 205, 50) static [rgb] $Linen = [rgb]::new(250, 240, 230) static [rgb] $MediumAquaMarine = [rgb]::new(102, 205, 170) static [rgb] $MediumOrchid = [rgb]::new(186, 85, 211) static [rgb] $MediumPurple = [rgb]::new(147, 112, 219) static [rgb] $MediumSeaGreen = [rgb]::new(60, 179, 113) static [rgb] $MediumSlateBlue = [rgb]::new(123, 104, 238) static [rgb] $MediumSpringGreen = [rgb]::new(0, 250, 154) static [rgb] $MediumTurquoise = [rgb]::new(72, 209, 204) static [rgb] $MediumVioletRed = [rgb]::new(199, 21, 133) static [rgb] $MidnightBlue = [rgb]::new(25, 25, 112) static [rgb] $MintCream = [rgb]::new(245, 255, 250) static [rgb] $MistyRose = [rgb]::new(255, 228, 225) static [rgb] $Moccasin = [rgb]::new(255, 228, 181) static [rgb] $NavajoWhite = [rgb]::new(255, 222, 173) static [rgb] $OldLace = [rgb]::new(253, 245, 230) static [rgb] $Olive = [rgb]::new(128, 128, 0) static [rgb] $OliveDrab = [rgb]::new(107, 142, 35) static [rgb] $Orange = [rgb]::new(255, 165, 0) static [rgb] $OrangeRed = [rgb]::new(255, 69, 0) static [rgb] $Orchid = [rgb]::new(218, 112, 214) static [rgb] $PaleGoldenrod = [rgb]::new(238, 232, 170) static [rgb] $PaleGreen = [rgb]::new(152, 251, 152) static [rgb] $PaleTurquoise = [rgb]::new(175, 238, 238) static [rgb] $PaleVioletRed = [rgb]::new(219, 112, 147) static [rgb] $PapayaWhip = [rgb]::new(255, 239, 213) static [rgb] $PeachPuff = [rgb]::new(255, 218, 185) static [rgb] $Peru = [rgb]::new(205, 133, 63) static [rgb] $Pink = [rgb]::new(255, 192, 203) static [rgb] $Plum = [rgb]::new(221, 160, 221) static [rgb] $PowderBlue = [rgb]::new(176, 224, 230) static [rgb] $Purple = [rgb]::new(128, 0, 128) static [rgb] $RosyBrown = [rgb]::new(188, 143, 143) static [rgb] $RoyalBlue = [rgb]::new(65, 105, 225) static [rgb] $SaddleBrown = [rgb]::new(139, 69, 19) static [rgb] $Salmon = [rgb]::new(250, 128, 114) static [rgb] $SandyBrown = [rgb]::new(244, 164, 96) static [rgb] $SeaGreen = [rgb]::new(46, 139, 87) static [rgb] $SeaShell = [rgb]::new(255, 245, 238) static [rgb] $Sienna = [rgb]::new(160, 82, 45) static [rgb] $SkyBlue = [rgb]::new(135, 206, 235) static [rgb] $SlateBlue = [rgb]::new(106, 90, 205) static [rgb] $SlateGray = [rgb]::new(112, 128, 144) static [rgb] $Snow = [rgb]::new(255, 250, 250) static [rgb] $SpringGreen = [rgb]::new(0, 255, 127) static [rgb] $SteelBlue = [rgb]::new(70, 130, 180) static [rgb] $Tan = [rgb]::new(210, 180, 140) static [rgb] $Thistle = [rgb]::new(216, 191, 216) static [rgb] $Tomato = [rgb]::new(255, 99, 71) static [rgb] $Turquoise = [rgb]::new(64, 224, 208) static [rgb] $Violet = [rgb]::new(238, 130, 238) static [rgb] $Wheat = [rgb]::new(245, 222, 179) static [rgb] $WhiteSmoke = [rgb]::new(245, 245, 245) static [rgb] $YellowGreen = [rgb]::new(154, 205, 50) RGB() { $this._initialize() } RGB([string]$Name) { if ([string]::IsNullOrWhiteSpace($Name)) { throw [System.ArgumentException]::new("Color name cannot be null or whitespace.") } $IsValid = [rgb].GetProperties().Name.ToLower().Contains($Name.ToLower()) if (!$IsValid) { throw [System.InvalidCastException]::new("Color name '$Name' is not valid. see [ConsoleWriter]::Colors for a list of valid colors OR ue: [rgb].GetProperties().Where({ `$_.IsStatic }).Name") } [RGB]$c = [rgb]::$Name $this._Red = $c.Red $this._Green = $c.Green $this._Blue = $c.Blue $this._initialize() } RGB([int]$r, [int]$g, [int]$b) { $this._Red = $r $this._Green = $g $this._Blue = $b $this._initialize() } hidden [void] _initialize() { $this.PsObject.Properties.Add([PSAliasproperty]::new("Red", "_Red")) $this.PsObject.Properties.Add([PSAliasproperty]::new("Green", "_Green")) $this.PsObject.Properties.Add([PSAliasproperty]::new("Blue", "_Blue")) } [tuple[int, int, int]] ToHsv() { return $this.ToHsv($this._Red, $this._Green, $this._Blue) } [tuple[int, int, int]] ToHsv([rgb]$RGB) { return $this.ToHsv($RGB.Red, $RGB.Green, $RGB.Blue) } [tuple[int, int, int]] ToHsv([int]$Red, [int]$Green, [int]$Blue) { $null = [RGB]::new($Red, $Green, $Blue) # for validation $redPercent = $Red / 255.0 $greenPercent = $Green / 255.0 $bluePercent = $Blue / 255.0 $max = [Math]::Max([Math]::Max($redPercent, $greenPercent), $bluePercent) $min = [Math]::Min([Math]::Min($redPercent, $greenPercent), $bluePercent) $delta = $max - $min $saturation = 0 $value = 0 $hue = 0 if ($delta -eq 0) { $hue = 0 } elseif ($max -eq $redPercent) { $hue = 60 * ((($greenPercent - $bluePercent) / $delta) % 6) } elseif ($max -eq $greenPercent) { $hue = 60 * ((($bluePercent - $redPercent) / $delta) + 2) } elseif ($max -eq $bluePercent) { $hue = 60 * ((($redPercent - $greenPercent) / $delta) + 4) } if ($hue -lt 0) { $hue = 360 + $hue } if ($max -eq 0) { $saturation = 0 } else { $saturation = $delta / $max * 100 } $value = $max * 100 return [tuple]::Create([int]$hue, [int]$saturation, [int]$value) } [RGB] FromHsl([int]$Hue, [int]$Saturation, [int]$Lightness) { $huePercent = $Hue / 360.0 $saturationPercent = $Saturation / 100.0 $lightnessPercent = $Lightness / 100.0 ($r, $g, $b) = if ($saturationPercent -eq 0) { $lightnessPercent, $lightnessPercent, $lightnessPercent } else { $q = ($lightnessPercent -lt 0.5) ? ($lightnessPercent * (1 + $saturationPercent)) : ($lightnessPercent + $saturationPercent - ($lightnessPercent * $saturationPercent)) $p = 2 * $lightnessPercent - $q [rgb]::FromPQT($p, $q, ($huePercent + (1 / 3))), [rgb]::FromPQT($p, $q, $huePercent), [rgb]::FromPQT($p, $q, ($huePercent - (1 / 3))) } return [RGB]::new([int]($r * 255), [int]($g * 255), [int]($b * 255)) } static [int] FromPQT([double]$P, [double]$Q, [double]$T) { if ($T -lt 0) { $T += 1 } if ($T -gt 1) { $T -= 1 } 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 } [int] GetLightness([int]$Red, [int]$Green, [int]$Blue) { $redPercent = $Red / 255.0 $greenPercent = $Green / 255.0 $bluePercent = $Blue / 255.0 $max = [Math]::Max([Math]::Max($redPercent, $greenPercent), $bluePercent) $min = [Math]::Min([Math]::Min($redPercent, $greenPercent), $bluePercent) return ($max + $min) / 2 } [string] GetCategory([int]$Hue, [int]$Saturation, [int]$Value) { $categories = @{ "02 Red" = @(0..20 + 350..360) "03 Orange" = @(21..45) "04 Yellow" = @(46..60) "05 Green" = @(61..108) "06 Green2" = @(109..150) "07 Cyan" = @(151..190) "08 Blue" = @(191..220) "09 Blue2" = @(221..240) "10 Purple" = @(241..280) "11 Pink1" = @(281..300) "12 Pink" = @(301..350) } if ($Saturation -lt 15) { if ($Value -lt 40) { return "00 Grey" } return "00 GreyZMud" } $res = @() foreach ($category in $categories.GetEnumerator()) { if ($Hue -in $category.Value) { $cat = $category.Key if ($Saturation -lt 2) { $cat = $cat + "ZMud" } $res += $cat } } return $res } [string] ToString() { return [rgb].GetProperties().Name.Where({ [rgb]::$_ -eq $this }) } } |