Преобразовать шестнадцатеричный код в название цвета

Как я могу преобразовать это hexa code = #2088C1 в название цвета, как синий или красный

Моя цель - я хочу получить название цвета, например, "синий" для данного гекса кода

Я пробовал приведенный ниже код, но он не давал никакого названия цвета..

System.Drawing.Color col = System.Drawing.ColorTranslator.FromHtml("#2088C1");

Color col = ColorConverter.ConvertFromString("#2088C1") as Color;

но это не дает название цвета, как этот "aquablue"

Я использую Winforms приложения с C#

9 ответов

Решение

Я наткнулся на немецкий сайт, который делает именно то, что вы хотите:

/// <summary>
/// Gets the System.Drawing.Color object from hex string.
/// </summary>
/// <param name="hexString">The hex string.</param>
/// <returns></returns>
private System.Drawing.Color GetSystemDrawingColorFromHexString(string hexString)
{
    if (!System.Text.RegularExpressions.Regex.IsMatch(hexString, @"[#]([0-9]|[a-f]|[A-F]){6}\b"))
        throw new ArgumentException();
    int red = int.Parse(hexString.Substring(1, 2), NumberStyles.HexNumber);
    int green = int.Parse(hexString.Substring(3, 2), NumberStyles.HexNumber);
    int blue = int.Parse(hexString.Substring(5, 2), NumberStyles.HexNumber);
    return Color.FromArgb(red, green, blue);
}

Чтобы получить название цвета, вы можете использовать его следующим образом, чтобы получить KnownColor:

private KnownColor GetColor(string colorCode)
{
    Color color = GetSystemDrawingColorFromHexString(colorCode);
    return color.GetKnownColor();
}

Тем не мение, System.Color.GetKnownColor кажется, будет удалено в более новых версиях.NET

Используйте этот метод

Color myColor = ColorTranslator.FromHtml(htmlColor);

Также смотрите ссылку

Это может быть сделано с небольшим количеством размышления. Не оптимизировано, но работает:

string GetColorName(Color color)
{
    var colorProperties = typeof(Color)
        .GetProperties(BindingFlags.Public | BindingFlags.Static)
        .Where(p => p.PropertyType == typeof(Color));
    foreach(var colorProperty in colorProperties) 
    {
        var colorPropertyValue = (Color)colorProperty.GetValue(null, null);
        if(colorPropertyValue.R == color.R 
               && colorPropertyValue.G == color.G 
               && colorPropertyValue.B == color.B) {
            return colorPropertyValue.Name;
        }
    }

    //If unknown color, fallback to the hex value
    //(or you could return null, "Unkown" or whatever you want)
    return ColorTranslator.ToHtml(color);
}

Я только что придумал это:

enum MatchType
{
  NoMatch,
  ExactMatch,
  ClosestMatch
};

static MatchType FindColour (Color colour, out string name)
{
  MatchType
    result = MatchType.NoMatch;

  int
    least_difference = 0;

  name = "";

  foreach (PropertyInfo system_colour in typeof (Color).GetProperties (BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy))
  {
    Color
      system_colour_value = (Color) system_colour.GetValue (null, null);

    if (system_colour_value == colour)
    {
      name = system_colour.Name;
      result = MatchType.ExactMatch;
      break;
    }

    int
      a = colour.A - system_colour_value.A,
      r = colour.R - system_colour_value.R,
      g = colour.G - system_colour_value.G,
      b = colour.B - system_colour_value.B,
      difference = a * a + r * r + g * g + b * b;

    if (result == MatchType.NoMatch || difference < least_difference)
    {
      result = MatchType.ClosestMatch;
      name = system_colour.Name;
      least_difference = difference;
    }
  }

  return result;
}

static void Main (string [] args)
{
  string
    colour;

  MatchType
    match_type = FindColour (Color.FromArgb (0x2088C1), out colour);

  Console.WriteLine (colour + " is the " + match_type.ToString ());

  match_type = FindColour (Color.AliceBlue, out colour);

  Console.WriteLine (colour + " is the " + match_type.ToString ());
}

Это старый пост, но вот оптимизированный конвертер Color в KnownColor, так как встроенный.NET ToKnownColor() не работает корректно со структурами adhoc Color. Когда вы в первый раз вызываете этот код, он будет загружать известные значения цвета и получит незначительный перфоманс. Последовательные вызовы функции - это простой и быстрый поиск по словарю.

public static class ColorExtensions
{
    private static Lazy<Dictionary<uint, KnownColor>> knownColors = new Lazy<Dictionary<uint, KnownColor>>(() =>
    {
        Dictionary<uint, KnownColor> @out = new Dictionary<uint, KnownColor>();
        foreach (var val in Enum.GetValues(typeof(KnownColor)))
        {
            Color col = Color.FromKnownColor((KnownColor)val);
            @out[col.PackColor()] = (KnownColor)val;
        }
        return @out;
    });

    /// <summary>Packs a Color structure into a single uint (argb format).</summary>
    /// <param name="color">The color to package.</param>
    /// <returns>uint containing the packed color.</returns>
    public static uint PackColor(this Color color) => (uint)((color.A << 24) | (color.R << 16) | (color.G << 8) | (color.B << 0));

    /// <summary>Unpacks a uint containing a Color structure.</summary>
    /// <param name="color">The color to unpackage.</param>
    /// <returns>A new Color structure containing the color defined by color.</returns>
    public static Color UnpackColor(this uint color) => Color.FromArgb((byte)(color >> 24), (byte)(color >> 16), (byte)(color >> 8), (byte)(color >> 0));

    /// <summary>Gets the name of the color</summary>
    /// <param name="color">The color to get the KnownColor for.</param>
    /// <returns>A new KnownColor structure.</returns>
    public static KnownColor? GetKnownColor(this Color color)
    {
        KnownColor @out;
        if (knownColors.Value.TryGetValue(color.PackColor(), out @out))
            return @out;

        return null;
    }
}

Если вы хотите получить название цвета, вы можете сделать это без шага преобразования цвета в гекс через:

Color c = (Color) yourColor;

yourColor.Color.Tostring;

Затем удалите ненужные символы, которые возвращаются, в большинстве случаев, если ваш цвет не определен, он будет возвращать значение ARGB, которое в этом случае не имеет встроенных имен, но в него включено много значений имени.

Кроме того, ColorConverter - хороший способ конвертировать из шестнадцатеричного имени в имя, если вам вообще нужен шестнадцатеричный код.

Для этого нет готовой функции. Вам нужно будет просмотреть список известных цветов и сравнить RGB каждого известного цвета с RGB вашего неизвестного.

Проверьте эту ссылку: http://bytes.com/topic/visual-basic-net/answers/365789-argb-color-know-color-name

Сделал преобразователь строк в цвет wpf, так как он мне нужен:

     class StringColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        string colorString = value.ToString();
        //Color colorF = (Color)ColorConverter.ConvertFromString(color); //displays r,g ,b values
        Color colorF = ColorTranslator.FromHtml(colorString);
        return colorF.Name;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

можно использовать с

          <TextBlock Width="40" Height="80" Background="DarkViolet" Text="{Binding Background, Converter={StaticResource StringColorConverter}, Mode=OneWay, RelativeSource={RelativeSource Self}}" Foreground="White" FontWeight="SemiBold"/>

Если у вас есть доступ к сборкам SharePoint, Microsoft.SharePoint содержит класс Microsoft.SharePoint.Utilities.ThemeColor статическим методом GetScreenNameForColor который занимает System.Drawing.Color объект и возвращает string описывая это. Там может быть около 20 наименований разных цветов со светлыми и темными вариациями.

Другие вопросы по тегам