2012-04-19 21 views
1

我得到了用C#工作的代碼。我想幫助將其轉換爲慣用的PowerShell腳本,該腳本將rgb或十六進制顏色定義作爲輸入,並將包含顏色名稱和rgb值的前3或5個匹配輸出到控制檯。我對PowerShell很新,很抱歉,如果這太要求了。使用PowerShell查找最接近的System.Color實例

private static void FindMyColor() 
    { 
     System.Drawing.Color targetColor = System.Drawing.Color.FromArgb(red: 0, green: 128, blue: 0); 
     var myStuff = EnumerateColors(targetColor: targetColor).OrderBy(tpl => tpl.Item1).ToList(); 
     int a = 0; // Pause the debugger here. 
    } 

    private static double GetColorDistance(System.Drawing.Color lhs, System.Drawing.Color rhs) 
    { 
     double sum = Cube(lhs.R - rhs.R) + Cube(lhs.G - rhs.G) + Cube(lhs.B - rhs.B); 
     return Math.Pow(sum, 1.0/3.0); 
    } 

    private static double Cube(int value) 
    { 
     return (double) (value * value * value); 
    } 

    private static System.Collections.Generic.IEnumerable<Tuple<double, string, System.Drawing.Color>> EnumerateColors(System.Drawing.Color targetColor) 
    { 
     var candidateColors = EnumerateSystemColors(); 
     foreach (string colorName in candidateColors.Keys) 
     { 
      var color = candidateColors[key: colorName]; 
      double colorDistance = GetColorDistance(lhs: color, rhs: targetColor); 
      yield return new Tuple<double, string, System.Drawing.Color>(colorDistance, colorName, color); 
     } 
    } 

    private static System.Collections.Generic.Dictionary<string, System.Drawing.Color> EnumerateSystemColors() 
    { 
     var properties = typeof(System.Drawing.Color) 
       .GetProperties(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); 
     return properties.ToDictionary(p => p.Name, p => (System.Drawing.Color)p.GetValue(null, null)); 
    } 

回答

1

爲什麼不添加此代碼作爲添加類型的類型?而在PowerShell中使用它作爲[myclass]::GetColorDistance(....) - 在這裏看到更多的細節

Add-Type

1

只是爲了完整性,這裏是一個PowerShell版本找到最接近的顏色。

首先,我們獲得的所有聲明的Color類型的靜態命名屬性的顏色:

$namedColors = [Drawing.Color] | Get-Member -Static -MemberType Property | 
    foreach { [Drawing.Color]::($_.Name) } 

爲了確定兩個顏色之間的距離,我們可以定義使用Cartesian distance三個自定義函數RGB尺寸:

function Measure-ColorDistance([Drawing.Color]$a, [Drawing.Color]$b) { 
    $sum = 'R','G','B' | foreach { [Math]::Pow($a.$_ - $b.$_, 2) } | measure -Sum 
    [Math]::Round([Math]::Pow($sum.Sum, 0.5), 2) 
} 

爲了更容易地確定目標色彩,我們可以定義一個輔助函數來創建一個ARGB顏色值:

function New-Color([byte]$r = 0, [byte]$g = 0, [byte]$b = 0, [byte]$a = 255) { 
    [Drawing.Color]::FromArgb($a, $r, $g, $b) 
} 

最後,找到最接近的顏色,我們可以得到每個命名顏色與目標之間的距離,並返回該距離排序頂部顏色:

function MatchColor([Drawing.Color]$targetColor, [int]$top = 5) { 
    $distance = @{ n='Distance'; e={ Measure-ColorDistance $targetColor $_ } } 
    $distances = $namedColors | Select-Object $distance,Name 
    $distances | Sort-Object Distance | Select-Object -First $top 
} 

調用MatchColor (New-Color -g 128)會顯示前五名的結果:

Distance Name 
-------- ---- 
     0 Green 
     28 DarkGreen 
    49.33 ForestGreen 
    99.03 SeaGreen 
    99.37 DarkOliveGreen 
+0

這很酷,謝謝! – 2012-08-06 16:33:44