34
$\begingroup$

For example: "#FF8000".

How could I convert it to RGBColor or Hue?

$\endgroup$
1
  • 2
    $\begingroup$ Incidentally, this site, among many others, also uses three character color codes (#888). Should answers accept both forms? $\endgroup$
    – cormullion
    Jan 26, 2013 at 17:53

11 Answers 11

33
$\begingroup$

Using IntegerDigits to convert directly to base 256:

hexToRGB = RGBColor @@ (IntegerDigits[
  ToExpression@StringReplace[#, "#" -> "16^^"], 256, 3]/255.) &

hexToRGB["#FF8000"]
(*   RGBColor[1., 0.501961, 0.]  *)

Edit

Shorter version, since somebody mentioned golfing...

hexToRGB = RGBColor @@ (IntegerDigits[# ~StringDrop~ 1 ~FromDigits~ 16, 256, 3]/255.) &
$\endgroup$
7
  • $\begingroup$ That is a particularly clever solution... $\endgroup$
    – Stefan
    Jan 26, 2013 at 11:10
  • 2
    $\begingroup$ Why the "3" in the golfed version? $\endgroup$ Jan 26, 2013 at 11:39
  • 2
    $\begingroup$ @belisarius, you need to pad to 3 digits in case the red component is zero $\endgroup$ Jan 26, 2013 at 11:52
  • 1
    $\begingroup$ Again we think alike. You're even using infix! FWIW when using infix I recommend the spacing that I just edited your post to include. I think it's much more readable that way, and I can tell you from experience that a lot of people find it hard to read anyway. $\endgroup$
    – Mr.Wizard
    Jan 26, 2013 at 17:13
  • 1
    $\begingroup$ @Mr.Wizard, thanks for the edit - I agree it's more readable like that. $\endgroup$ Jan 26, 2013 at 18:06
21
$\begingroup$

Starting from version 10.1 you can use RGBColor directly:

RGBColor["#FF8000"]
(* RGBColor[1., 0.5019607843137255, 0.] *)

RGBColor["#45A"]
(* RGBColor[0.26666666666666666`, 0.3333333333333333, 0.6666666666666666] *)

ToColor[RGBColor["#FF8000"], Hue]
(* Hue[0.08366013071895424, 1., 1.] *)
$\endgroup$
12
$\begingroup$

Function that converts string to a list of 3 numbers: for R, G and B component:

toRGBSequence[i_] := 
  Composition[FromDigits[#, 16] &, StringJoin] /@ 
   Partition[Characters[StringDrop[i, 1]], 2] /. List -> Sequence;
  • First, dropping the # sign.
  • Converting to a list, using the Characters function.
  • Partitioning in groups of 2.
  • Composition of function to first join the two letters and than convert it to a base-10 format.
  • Map over a list.
  • Converting everything to Sequence to use with RGBColor function.

Usage:

RGBColor[toRGBSequence["#FF5500"]]

PS: This may, or may not be the most accurate and fast solution.

$\endgroup$
1
  • 1
    $\begingroup$ +1 it's more beautiful than mine is, that's for sure :) $\endgroup$
    – cormullion
    Jan 26, 2013 at 10:23
10
$\begingroup$

I hate regular expressions... :)

hexColorToRGB[s_] := RGBColor[FromDigits[#, 16]/255 & /@ Flatten[
  StringCases[ToLowerCase@s,
   {RegularExpression[
    "#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})" ] 
      -> {"$1", "$2", "$3"},
    RegularExpression["#([0-9a-f])([0-9a-f])([0-9a-f])"] 
      -> {"$1$1", "$2$2", "$3$3"}}
 ]]]

ColorSetter /@ 
 hexColorToRGB /@ 
    {"#000", "#FF0000", "#0F0", "#0000FF", "#FF0", 
     "#00FFFF", "#F0F", "#C0C0C0", "#FFF"}

test

$\endgroup$
8
$\begingroup$

Here is another option:

hexToRGB =
  RGBColor[ FromDigits[#, 16]/255 & /@ StringTake[#, {{2, 3}, {4, 5}, {6, 7}}] ] &;

hexToRGB@"#FF8c00" // ColorSetter

Mathematica graphics

And another:

hexToRGB =
  RGBColor[ FromDigits[#, 16]/255 & /@ StringCases[#, Except["#"] ~~ _] ] &;

#RGB form

Responding to cormullion's comment:

hexToRGB[color_String | {colors__String}] :=
  RGBColor[FromDigits[#, 16]/255 & /@ #] & @@@
    StringCases[{color, colors},
      {"#" ~~ r_ ~~ g_ ~~ b_ ~~ EndOfString :> {r ~~ r, g ~~ g, b ~~ b},
       "#" ~~ r : (_ ~~ _) ~~ g : (_ ~~ _) ~~ b : (_ ~~ _) :> {r, g, b}}]

ColorSetter /@ hexToRGB @ 
  {"#000", "#FF0000", "#0F0", "#0000FF", "#FF0", "#00FFFF", "#F0F", "#C0C0C0", "#FFF"}

Mathematica graphics

Operating on the entire list of color strings should be faster than one at a time.

$\endgroup$
1
  • $\begingroup$ I really like the second one... $\endgroup$ Jan 26, 2013 at 18:07
7
$\begingroup$

Also

rgb[x_] := RGBColor[FromDigits[#, 2] / 255 & /@ 
            Partition[IntegerDigits[FromDigits[StringDrop[x, 1], 16], 2, 24], 8]]

rgb@"#FF5500"

RGBColor[{255, 85, 0}]

Edit

Golfing a one liner :)

rgb[x_] := RGBColor[FromDigits[#, 16]/255 & /@ StringJoin /@ Partition[Rest@Characters@x, 2]]
$\endgroup$
3
  • $\begingroup$ You need to work on your swing: rgb[x_] := RGBColor[FromDigits["" <> # , 16]/255 & /@ Rest@Characters@x ~Partition~ 2] or fully Golfed: rgb=RGBColor[FromDigits[""<>#,16]/255&/@Rest@Characters@#~Partition~2]& $\endgroup$
    – Mr.Wizard
    Jan 26, 2013 at 17:32
  • $\begingroup$ @Mr.Wizard Good one :). I wasn't golfing seriously, just trying to fit it in one line. Simon's answer is far better, anyway $\endgroup$ Jan 26, 2013 at 17:37
  • $\begingroup$ Yeah, I'm pretty miffed he got that one before me. :o) $\endgroup$
    – Mr.Wizard
    Jan 26, 2013 at 17:44
7
$\begingroup$

In version 10

Interpreter["StructuredColor"]["#FF8000"]

RGBColor[1, Rational[128, 255], 0]

$\endgroup$
6
$\begingroup$

You guys are too fast for me ;)

My solution which is similar to @cormullion's:

hexToRGB[hex_String] :=Module[{RGB},
    RGB = StringCases[hex, 
       RegularExpression["^#(\\w{2})(\\w{2})(\\w{2})"] -> {"$1", "$2", 
        "$3"}] // Flatten;
    RGBColor[FromDigits[#, 16]/100 - 1 & /@ RGB]
]

Graphics[{hexToRGB["#A4A4A4"], Disk[]}]

P.S.: Things are not always just #000000 and #FFFFFF. It's mostly varying of shades of #A4A4A4 :)

EDIT

PieChart of the sector angles proportional to {R, G, B}

hexToPiechart =PieChart3D @@ {ToExpression@#/255. & /@ (StringCases[#, 
    RegularExpression["^#(\\w{2})(\\w{2})(\\w{2})"] -> {"16^^$1", 
      "16^^$2", "16^^$3"}])} &;


hexToPiechart["#A4A4A4"]

pie chart

$\endgroup$
5
$\begingroup$
 ColorData["WebSafe", "Panel"] (*click to get RGBColor *)

enter image description here

$\endgroup$
5
$\begingroup$

Borrowing from amr's answer here

ToExpression["16^^" <> #] & /@ 
   Partition[Characters@StringTrim[#, "#"], 2] & /@ {"FFFFFF", 
  "#FFFFFF", "000000", "#FF5500", "#005500"}

=>{{255, 255, 255}, {255, 255, 255}, {0, 0, 0}, {255, 85, 0}, {0, 85, 0}}

$\endgroup$
4
$\begingroup$

Just to add nothing to the previous answers

toRGB[str_String]:=ToExpression["16^^" <> #] & /@ 
  str~StringDrop~1~StringCases~Repeated[_, {2}] /. 
 List -> RGBColor
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.