2

このコードを C# で動作させました。これを、rgb または 16 進数の色の定義を入力として取り、色名と rgb 値を含む上位 3 または 5 つの一致をコンソールに出力する、慣用的な PowerShell スクリプトに変換する手助けをしたいと思います。私は PowerShell を初めて使用します。質問が多すぎる場合は申し訳ありません。

    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));
    }
4

2 に答える 2

3

完全を期すために、最も近い色を見つけるための PowerShell バージョンを次に示します。

まず、Color型の静的な名前付きプロパティとして宣言されたすべての色を取得します。

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

2 つの色の間の距離を決定するために、3 つの 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)と、上位 5 つの結果が表示されます。

Distance Name
-------- ----
       0 Green
      28 DarkGreen
   49.33 ForestGreen
   99.03 SeaGreen
   99.37 DarkOliveGreen
于 2012-08-05T15:14:17.350 に答える
2

このコードをadd-typeを使用してtypeとして追加してみませんか?そして、PowerShellで次のように使用します[myclass]::GetColorDistance(....)-詳細については、こちらを参照してください

追加タイプ

于 2012-04-19T20:43:10.540 に答える