Conversão System.Drawing.Color para RGB e Hex Value

125

Usando C #, eu estava tentando desenvolver os dois seguintes. A maneira como estou fazendo isso pode ter algum problema e precisar de seus gentis conselhos. Além disso, não sei se existe algum método existente para fazer o mesmo.

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

Obrigado.

Nazmul
fonte

Respostas:

202

Não estou conseguindo ver o problema aqui. O código parece bom para mim.

A única coisa que posso pensar é que os blocos try / catch são redundantes - A cor é uma struct e R, G e B são bytes, então c não pode ser nulo e c.R.ToString(), c.G.ToString()e c.B.ToString()realmente não pode falhar (o a única maneira de vê-los falhando é com a NullReferenceExceptione nenhum deles pode ser nulo).

Você pode limpar tudo usando o seguinte:

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() + ")";
}
Ari Roth
fonte
1
Eu chegaria ao ponto de dizer que blocos vazios de try-catch deveriam (quase) universalmente ser erradicados. Eles têm um grande potencial para levar ao código de buggy, se não agora, mais adiante, quando esse código é modificado. Ainda assim, +1 para o código limpo e para o OP +1 para uma pergunta bem estruturada.
JMD
7
Levei um tempo para encontrar o equivelant VB: String.Format ( "# {0: X2} {1: X2} {2: X2}", CR, a CG, CB)
zacharydl
1
Postei uma adaptação do seu código no C # 6 como uma resposta alternativa. Você pode vê-lo aqui .
aloisdg movendo-se para codidact.com 14/06
Isso produzirá a cor errada se a cor tiver um canal alfa (transparência). Você terá total opacidade.
LarryBud
@ LarryBud Absolutamente verdade, e obrigado por apontar. Meu exemplo pulou o canal alfa apenas porque eu estava encerrando a pergunta original, que também não a incluía. :)
Ari Roth
189

Você pode simplificar e usar o tradutor de cores nativo:

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

Em seguida, divida os três pares de cores na forma inteira:

int value = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
Troy Hunt
fonte
7
Mas se eu fizer dessa maneira, Color red = System.Drawing.Color.Red; string redHex = ColorTranslator.ToHtml (vermelho); ele não fornece o valor hexadecimal.
Nazmul 7/03/10
Certamente, testei esse código especificamente e obtive # "FF0000". O que você está recebendo? Você também pode consultar a referência do MSDN: msdn.microsoft.com/en-us/library/…
Troy Hunt
Tente com Cor vermelha = System.Drawing.Color.Red; -> não fornece # FF0000.
Nazmul 7/03/10
9
O código que você forneceu funciona, mas quando altero a primeira linha do seu código para: Color red = System.Drawing.Color.Red; -> Então não fornece o código hexadecimal. Dá "Vermelho" como saída.
Nazmul 7/03/10
4
@Hoque - Confirmado. ColorTranslator atribui um nome "amigável" à cor. Que irritante!
anon
38

Se você pode usar C # 6 ou superior, pode se beneficiar de Interpolated Strings e reescrever a solução do @Ari Roth assim:

C # 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})";
}

Além disso:

  • Eu adiciono a palavra this- chave para usá-los como métodos de extensões.
  • Podemos usar a palavra-chave type string vez do nome da classe.
  • Podemos usar a sintaxe lambda.
  • Eu os renomeio para serem mais explícitos para o meu gosto.
aloisdg movendo-se para codidact.com
fonte
Tão limpo ... +1!
Shockwaver
26

por exemplo

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

Isso pode evitar o truque KnownColor.

Andy Fong
fonte
1

Encontrei um método de extensão que funciona muito bem

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

Ref: https://social.msdn.microsoft.com/Forums/en-US/4c77ba6c-6659-4a46-920a-7261dd4a15d0/how-to-convert-rgba-value-into-its-equivalent-hex-code? forum = winappswithcsharp

user1
fonte
Eu acredito que deve ser Hex2, não Hex, caso contrário, a cor pode estar errada interpolada.
Mohammed Noureldin 19/10/10
@MohammedNoureldin Para onde iria o Hex2 no código, às vezes vejo cores sendo ligeiramente diferentes?
usar o seguinte
Eu quis dizer em X2vez de X, caso contrário, você pode obter em 1vez de 01então será um problema.
Mohammed Noureldin
@MohammedNoureldin Sim, X2então você não precisa de todos os color.B.ToString("X").Length == 1 ? ternários.
ProfK 27/02
1

Para código hexadecimal, tente isto

  1. Obtenha representação ARGB (alfa, vermelho, verde e azul) da cor
  2. Filtrar o canal alfa:& 0x00FFFFFF
  3. Formate o valor (como hexadecimal "X6" para hexadecimal)

Para um RGB

  1. Apenas formatar fora Red , Green, Bluevalores

Implementação

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);
}
Dmitry Bychenko
fonte