Преобразование System.Drawing.Color в RGB и шестнадцатеричное значение


125

Используя C #, я пытался разработать следующие два. То, как я это делаю, может вызвать проблемы, и мне понадобится ваш добрый совет. Кроме того, я не знаю, существует ли какой-либо способ сделать то же самое.

private static String HexConverter(System.Drawing.Color c)
{
    String rtn = String.Empty;
    try
    {
        rtn = "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
    }
    catch (Exception ex)
    {
        //doing nothing
    }

    return rtn;
}

private static String RGBConverter(System.Drawing.Color c)
{
    String rtn = String.Empty;
    try
    {
        rtn = "RGB(" + c.R.ToString() + "," + c.G.ToString() + "," + c.B.ToString() + ")";
    }
    catch (Exception ex)
    {
        //doing nothing
    }

    return rtn;
}

Спасибо.


Ответы:


202

Я не вижу здесь проблемы. Код мне нравится.

Единственное , что я могу думать о том , что Try / уловах блоки являются избыточными - цвет является структурой и R, G, B и байты, так что с не может быть пустым и c.R.ToString(), c.G.ToString()и c.B.ToString()фактически не может терпеть неудачу ( единственный способ увидеть, как они проигрывают, - этоNullReferenceException , и ни один из них не может быть нулевым).

Вы можете очистить все это, используя следующее:

private static String HexConverter(System.Drawing.Color c)
{
    return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}

private static String RGBConverter(System.Drawing.Color c)
{
    return "RGB(" + c.R.ToString() + "," + c.G.ToString() + "," + c.B.ToString() + ")";
}

1
Я бы пошел еще дальше и сказал, что пустые блоки try-catch должны (почти) повсеместно искореняться. У них есть большой потенциал привести к ошибочному коду, если не сейчас, то в будущем, когда этот код будет изменен. Тем не менее, +1 за очищенный код и OP +1 за хорошо сформулированный вопрос.
JMD

7
Мне потребовалось время, чтобы найти эквивалент VB: String.Format ("# {0: X2} {1: X2} {2: X2}", cR, cG, cB)
zacharydl

1
В качестве альтернативного ответа я публикую адаптацию вашего кода для C # 6. Вы можете увидеть это здесь .
aloisdg переходит на codidact.com

Это приведет к неправильному цвету, если у цвета есть альфа-канал (прозрачность). Вы получите полную непрозрачность.
LarryBud

@LarryBud Абсолютно верно, и спасибо, что указали на это. В моем примере альфа-канал пропущен только потому, что я отключил исходный вопрос, который также не включал его. :)
Ари Рот

189

Вы можете сделать это просто и использовать собственный переводчик цветов:

Color red = ColorTranslator.FromHtml("#FF0000");
string redHex = ColorTranslator.ToHtml(red);

Затем разбейте три пары цветов в целочисленную форму:

int value = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);

7
Но если я сделаю так, Color red = System.Drawing.Color.Red; строка redHex = ColorTranslator.ToHtml (красный); он не предоставляет шестнадцатеричное значение.
Nazmul

Конечно, должен, я специально протестировал этот код и получил # "FF0000". Что ты получишь? Вы также можете обратиться к ссылке MSDN: msdn.microsoft.com/en-us/library/…
Трой Хант,

Попробуйте использовать Color red = System.Drawing.Color.Red; -> он не предоставляет # FF0000.
Назмул

9
Предоставленный вами код работает, но когда я изменяю первую строку вашего кода на: Color red = System.Drawing.Color.Red; -> Тогда он не дает шестнадцатеричный код. На выходе он дает «Красный».
Nazmul

4
@Hoque - Подтверждено. ColorTranslator дает цвету «понятное» имя. Как раздражает!
анон

38

Если вы можете использовать C # 6 или выше, вы можете воспользоваться Interpolated Strings и переписать решение @Ari Roth следующим образом:

С # 6:

public static class ColorConverterExtensions
{
    public static string ToHexString(this Color c) => $"#{c.R:X2}{c.G:X2}{c.B:X2}";

    public static string ToRgbString(this Color c) => $"RGB({c.R}, {c.G}, {c.B})";
}

Также:

  • Я добавляю ключевое слово, thisчтобы использовать их в качестве методов расширения.
  • Мы можем использовать ключевое слово type string вместо имени класса.
  • Мы можем использовать лямбда-синтаксис.
  • Я переименовал их, чтобы они были более понятными на свой вкус.

Так чисто ... +1!
Shockwaver

26

например

 ColorTranslator.ToHtml(Color.FromArgb(Color.Tomato.ToArgb()))

Это поможет избежать уловки KnownColor.


1

Я нашел способ расширения, который работает достаточно хорошо

public static string ToHex(this Color color)
{
    return String.Format("#{0}{1}{2}{3}"
        , color.A.ToString("X").Length == 1 ? String.Format("0{0}", color.A.ToString("X")) : color.A.ToString("X")
        , color.R.ToString("X").Length == 1 ? String.Format("0{0}", color.R.ToString("X")) : color.R.ToString("X")
        , color.G.ToString("X").Length == 1 ? String.Format("0{0}", color.G.ToString("X")) : color.G.ToString("X")
        , color.B.ToString("X").Length == 1 ? String.Format("0{0}", color.B.ToString("X")) : color.B.ToString("X"));
}

Ссылка: https://social.msdn.microsoft.com/Forums/en-US/4c77ba6c-6659-4a46-920a-7261dd4a15d0/how-to-convert-rgba-value-into-its-equivalent-hex-code? форум = winappswithcsharp


Я считаю, что это должно быть Hex2, а не Hex, иначе цвет может быть неправильно интерполирован.
Мохаммед

@MohammedNoureldin Куда бы Hex2 пошел в коде, я видел, что иногда цвета немного отличаются?
user1

Я имел в виду X2вместо X, иначе вы можете получить 1вместо, 01тогда это будет проблемой.
Мохаммед

@MohammedNoureldin Да, X2тогда вам не нужны все color.B.ToString("X").Length == 1 ? троичные.
ПрофК

1

Для шестнадцатеричного кода попробуйте это

  1. Получить представление цвета в ARGB (альфа, красный, зеленый, синий)
  2. Отфильтровано альфа-канал:& 0x00FFFFFF
  3. Отформатируйте значение (как шестнадцатеричный "X6" для шестнадцатеричного)

Для одного RGB

  1. Просто форматировать из Red , Green, Blueзначения

Реализация

private static string HexConverter(Color c) {
  return String.Format("#{0:X6}", c.ToArgb() & 0x00FFFFFF);
}

public static string RgbConverter(Color c) {
  return String.Format("RGB({0},{1},{2})", c.R, c.G, c.B);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.