c# - 使用 PowerShell 查找最接近的 System.Color 实例

标签 c# powershell

我让这段代码在 C# 中运行。我希望帮助将其转换为惯用的 PowerShell 脚本,该脚本将 rgb 或十六进制颜色定义作为输入,并将前 3 或 5 个匹配项输出到控制台,包括颜色名称和 rgb 值。我对 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));
    }

最佳答案

为了完整起见,这里有一个 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

关于c# - 使用 PowerShell 查找最接近的 System.Color 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10234046/

相关文章:

c# - c# 和 java 之间的基准测试和差异原因

c# - 异常 :The total length of a DataValidation list cannot exceed 255 characters

c# - 产生数据注释

arrays - 当数组为空时,是否可以让measure-object为Sum返回0而不是null/nothing?

powershell - 在文件中搜索多个字符串

powershell - 如何将今天的日期作为 powershell 中参数的默认值

c# - 查找匹配的列表项索引号c#

c# - 在 C# 中获取数据库字段名称数组?

Azure powershell - 获取具有大小的 VM 列表

powershell - 为什么我的 powershell localhost 服务器这么慢?