31
$\begingroup$

For example: "#FF8000".

How could I convert it to RGBColor or Hue?

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

11 Answers 11

27
$\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$
  • $\begingroup$ That is a particularly clever solution... $\endgroup$ – Stefan Jan 26 '13 at 11:10
  • 2
    $\begingroup$ Why the "3" in the golfed version? $\endgroup$ – Dr. belisarius Jan 26 '13 at 11:39
  • 2
    $\begingroup$ @belisarius, you need to pad to 3 digits in case the red component is zero $\endgroup$ – Simon Woods Jan 26 '13 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 '13 at 17:13
  • 1
    $\begingroup$ @Mr.Wizard, thanks for the edit - I agree it's more readable like that. $\endgroup$ – Simon Woods Jan 26 '13 at 18:06
17
$\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
    $\begingroup$ +1 it's more beautiful than mine is, that's for sure :) $\endgroup$ – cormullion Jan 26 '13 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$
  • $\begingroup$ I really like the second one... $\endgroup$ – Simon Woods Jan 26 '13 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$
  • $\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 '13 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$ – Dr. belisarius Jan 26 '13 at 17:37
  • $\begingroup$ Yeah, I'm pretty miffed he got that one before me. :o) $\endgroup$ – Mr.Wizard Jan 26 '13 at 17:44
6
$\begingroup$

You guys are to fast for me ;)

My solution which is similar to's @cormullion:

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 a 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"]

enter image description here

$\endgroup$
6
$\begingroup$

In version 10

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

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

$\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, privacy policy and cookie policy

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