How to convert HEX2 to RGBA?

11

The world of art is full of colour, but the world of the network is even fuller than the world of art of diferent colours and it's renderings. That's why we need to know how to convert one type of colour format to another.

The challenge is self-evident:

Write a program / function than converts an given HEX code (#00ff0080, for instance) to RGBA (like rgba(0, 255, 0, 0.5)).

Rules:

  • External libraries/ built-ins for converting HEX to RGBA are disallowed. However, jQuery and syntax replacers like that are acceptable.
  • Standard Input/Output rules apply.
  • Format of the alpha can be between (1 == 100%) or the other (100 == 100%) that's not really important.
  • The output is flexible, as long as it returns the 4 converted values (as a String, Array, List, your choice).
  • You may choose to take the input without the # in the beginning. Hence, you can take input as either #RRGGBBAA or RRGGBBAA. You can assume that the hex code (excluding the #) will always be 8 characters long.
  • You should divide all the values by 255, including the alpha. The minimum decimal precision (for the alpha will be 2 decimal places).

Test Cases

Input:  00ff0080
Output: 0, 255, 0, 0.5

Scoring

, the code with the least amount of bytes wins.

Obsdarek

Posted 2017-06-29T15:46:07.777

Reputation: 145

Comments are not for extended discussion; this conversation has been moved to chat.

– Dennis – 2017-06-30T18:57:40.337

1Are we required to take the "hex code" as a string? You say that we can take it without the leading #, in which case it would just be a 32-bit integer value. Is it legal to take it as that? – Cody Gray – 2017-07-10T16:06:54.580

Answers

4

JavaScript (ES6), 73 54 50 bytes

(Saved some bytes thanks to @LeakyNun, the edited challenge, and @CraigAyre.)

s=>s.match(/../g).map((c,i)=>('0x'+c)/(i-3?1:255))

let f=

s=>s.match(/../g).map((c,i)=>('0x'+c)/(i-3?1:255))

console.log(f('00ff0080'));

Rick Hitchcock

Posted 2017-06-29T15:46:07.777

Reputation: 2 461

Rick, it looks like we have the final spec for this now so you can update your answer. – Shaggy – 2017-06-30T16:06:33.550

As well as @Shaggy's comment you can save a few bytes by using eval instead of parseInt: s=>s.match(/../g).map((x,i)=>eval('0x'+x)/(i-3?1:255)) – Craig Ayre – 2017-06-30T16:16:03.930

@CraigAyre, eval is a great alternative to parseInt for golfing purposes, thanks! – Rick Hitchcock – 2017-06-30T18:12:49.450

@RickHitchcock, no worries! You can also shave a couple of bytes from the regex using /../g. You might be able to reduce it even further using replace over match/map – Craig Ayre – 2017-06-30T18:20:12.580

Oh, I see the rules have changed, so the initial pound sign is no longer required. – Rick Hitchcock – 2017-06-30T18:21:59.760

Yeah, it's now optional. +2 bytes for supporting it isn't bad however! – Craig Ayre – 2017-06-30T18:22:37.267

Can't find a good replace solution that's shorter. If you have one, you should post it – would be an interesting alternative. – Rick Hitchcock – 2017-06-30T18:25:43.470

@CraigAyre, found a great alternative to parseInt and eval for hexadecimal: +('0x'+c) – Rick Hitchcock – 2017-07-02T05:08:29.607

@RickHitchcock, nice! You could even drop the conversion to number and divide the string directly to save another byte – Craig Ayre – 2017-07-02T10:34:03.490

Duh, of course! : ) – Rick Hitchcock – 2017-07-02T12:39:37.587

3

Japt, 13 bytes

Takes input as a string, without the leading #. Outputs the rgba value as an array.

ò ®nG
pUo /#ÿ

Test it


Explanation

We implicitly take the string as input via variable U.
"00ff0080"

ò

Split the string into an array of elements of length 2.
["00","ff","00","80"]

®nG

Map over the array and convert each element from a base 16 string to a decimal number. Because of the following newline, that array is implicitly assigned to variable U.
[0,255,0,128]

Uo

Pop the last element from the array.
128

/#ÿ

Divide it by 255.
0.5019607843137255

p

Push the result back into U then implicitly output the final array.
[0,255,0,0.5019607843137255]

Shaggy

Posted 2017-06-29T15:46:07.777

Reputation: 24 623

2

05AB1E, 9 bytes

2ôH`255/)

Try it online!

At least we have supporters like Emigna to often use some common sense...(that's what you get for golfing all day and then you start producing stuff like 2ô16öRć255/¸ìR ಠ_ಠ)

Erik the Outgolfer

Posted 2017-06-29T15:46:07.777

Reputation: 38 134

5 bytes shorter: 2ôH\žz/)` – Emigna – 2017-06-29T16:49:20.643

@Emigna The challenge has been closed nevertheless... – Erik the Outgolfer – 2017-06-29T17:44:24.900

2

PHP, 63 bytes

Output as array

$h=array_map(hexdec,str_split($argn,2));$h[3]/=255;print_r($h);

Try it online!

PHP, 80 bytes

Output as rgba value, Input without #

$h=array_map(hexdec,str_split($argn,2));$h[3]/=255;echo"rgba(",join(",",$h),")";

Try it online!

PHP, 88 bytes

Output as rgba value, Input with #

for(;$i<7;)$h[]=hexdec($argn[++$i].$argn[++$i]);$h[3]/=255;echo"rgba(",join(",",$h),")";

Try it online!

Jörg Hülsermann

Posted 2017-06-29T15:46:07.777

Reputation: 13 026

2

C (gcc), 139 bytes

C(x){x=x>57?x-87:x-48;}
#define Z C(h[i])*16+C(h[++i]))
i;f(char*h){printf("rgba(");for(i=0;i<6;i++)printf("%i, ",Z;printf("%g)",(Z/256.);}

Try it online!

My other attempt clocked in at 145 bytes. I'm not much of a C golfer, so this could probably be shorter.

Conor O'Brien

Posted 2017-06-29T15:46:07.777

Reputation: 36 228

1

Jelly, 15 14 bytes

Øhi$€’s2ḅ⁴÷4¦⁹

Try it online!

How it Works

Øhi$€’s2ḅ⁴÷4¦⁹ - main link, takes input without # and all lowercase
   $€             - to each input character:
  i               - return its 1-based index in
Øh                - the string "0123456789abcdef"
     ’            - decrement (otherwise 0 is mapped to 1 and f to 16)
      s2          - split the characters into groups of two
        ḅ⁴        - convert from base 16 to decimal
           4¦     - on the fourth element:
          ÷       - divide by
             ⁹    - 256

-1 byte thanks to @EricTheOutgolfer

fireflame241

Posted 2017-06-29T15:46:07.777

Reputation: 7 021

1

PHP, 72 bytes

Jörg´s array output version is unbeatable; but there are other options:

<?=($a=hexdec($argn))>>24,",",255&$a>>16,",",255&$a>>8,",",(255&$a)>256;

Run as pipe with -F. # does not matter, plain csv output

or 73 bytes (run with -R):

for($a=hexdec($argn);$i++<4;)echo(255&$a>>32-8*$i)/($i<4?:256),","[$i>3];

74 bytes with the spaces:

<?=($a=hexdec($argn))>>24,$c=", ",255&$a>>16,$c,255&$a>>8,$c,(255&$a)>256;

not so plain, 81 bytes:

rgba(<?=($a=hexdec($argn))>>24,$c=", ",255&$a>>16,$c,255&$a>>8,$c,(255&$a)/256?>)

Titus

Posted 2017-06-29T15:46:07.777

Reputation: 13 814

1

Stacked, 47 45 41 bytes

[2#<$unhexmap(1::256)/', '#`'rgba(@id)'!]

Try it online!

Conor O'Brien

Posted 2017-06-29T15:46:07.777

Reputation: 36 228

1

Excel, 99 bytes

=HEX2DEC(LEFT(A1,2))&","&HEX2DEC(MID(A1,3,2))&","&HEX2DEC(MID(A1,5,2))&","&HEX2DEC(RIGHT(A1,2))/256

Wernisch

Posted 2017-06-29T15:46:07.777

Reputation: 2 534

1

SmileBASIC, 50 bytes

INPUT H$RGBREAD VAL("&H"+H$)OUT R,G,B,A?R,G,B,A/#L

The hexadecimal string is converted to a number using VAL(), then RGBREAD extracts each byte. #L is a constant with the value 256.

RGBREAD is designed to extract the channels from an ARGB color, but really it just splits a 4 byte integer into 4 separate bytes, so the order doesn't matter.

12Me21

Posted 2017-06-29T15:46:07.777

Reputation: 6 110

I always like seeing [tag:basic] responses, but I am afraid that this response may be invalid, as it uses a built in for converting hexadecimal to rgba – Taylor Scott – 2018-03-05T21:54:16.060

I think it doesn't count as a hex->rgba builtin because it requires an extra step to convert the hex string into an integer. – 12Me21 – 2018-03-05T23:21:40.270

Actually, looking at it again, I think you are right, the explicit conversion from hex to int would make it valid. – Taylor Scott – 2018-03-06T12:35:07.983

0

Perl 6, 42 bytes

{m:g/../.map({:16(~$_)}) »/«(1,1,1,255)}

Try it online!

Sean

Posted 2017-06-29T15:46:07.777

Reputation: 4 136

0

JS ES2015, 84 bytes

$=>{a=[1,3,5,7].map(b=>eval("0x"+$.substr(b,2)));a[3]=(a[3]/256);return a.join(",")}

this is a function. Run it using

( CODE )("#00ff0080")

Евгений Новиков

Posted 2017-06-29T15:46:07.777

Reputation: 987

0

Python 3, 62 bytes

lambda h:[int(h[x:x+2],16)for x in(0,2,4)]+[int(h[6:],16)/255]

Try it online!

ovs

Posted 2017-06-29T15:46:07.777

Reputation: 21 408

0

q/kdb+, 43 bytes

Solution:

{(16 sv'(.Q.n,6#.Q.a)?/:2 cut x)%1 1 1 256}

Example:

q){(16 sv'(.Q.n,6#.Q.a)?/:2 cut x)%1 1 1 256}"00ff0080"
0 255 0 0.5

Explanation:

{                                         } / anonymous lambda function
                        2 cut x             / split input into 2-char length lists
                     ?/:                    / returns index where (each-right) item is found in 'the list'
        (           )                       / 'the list'
              6#.Q.a                        / Q.a is lowercase alphabet, 6# takes first 6 chars
         .Q.n,                              / Q.n is "012..89", so prepend this onto the "abcdef"                         
  16 sv'                                    / converts each index from base 16 to base 10
 (                            )%1 1 1 256   / divide this output by 1,1,1,256 to get alpha in 0..1 range 

streetster

Posted 2017-06-29T15:46:07.777

Reputation: 3 635

0

APL (Dyalog), 24 bytes

Requires ⎕IO←0 which is default on many systems. Prompts for input as uppercase without #.

256÷⍨@3⊢16⊥⍉4 2⍴⍞⍳⍨⎕D,⎕A

Try it online!

⎕D,⎕ADigits followed by Alphabet

⍞⍳⍨ prompt for text input (mnemonic: console with quote) and find the ɩndex of each letter in that

4 2⍴reshape as four row two column matrix

 transpose (because base conversion works columnwise)

16⊥ evaluate as base sixteen

 yield (serves to separate 3 and 16)

256÷⍨@3 divide the 4th element by 256

Adám

Posted 2017-06-29T15:46:07.777

Reputation: 37 779

0

Python 2, 54 bytes

lambda h:[int(h[i-2:i],16)/2.**(8&i)for i in(2,4,6,8)]

Try it online!

TFeld

Posted 2017-06-29T15:46:07.777

Reputation: 19 246

0

Yabasic, 96 bytes

Yet another answer; Takes input as string and outputs to the console.

Input""a$
For i=1To 7Step 2
?Dec(Mid$(a$,i,2))/(j+1);
If i=5Then j=255Fi
If i<7Then?", ";Fi
Next

Try it online!

Taylor Scott

Posted 2017-06-29T15:46:07.777

Reputation: 6 709

You can save a byte by removing the line break before ?. – 12Me21 – 2018-03-05T23:23:53.983

0

Excel VBA, 90 bytes

An anonymous VBE immediate window function that takes input from the range [A1] and outputs to the VBE immediate window.

For i=1To 7Step 2:[B1]=i:?[Hex2Dec(Mid(A1,B1,2))]/IIf(i=7,256,1)&""+IIf(i<7,", ","");:Next

Taylor Scott

Posted 2017-06-29T15:46:07.777

Reputation: 6 709

0

Vim, 46 bytes

:s/../$((16#&)) /g␊iecho ␛$hhi*100/255␛:w !sh␊

Takes input without the # and returns by printing on the screen.

Herman L

Posted 2017-06-29T15:46:07.777

Reputation: 3 611