Convert Hex to RGBA

My fiddle - http://jsbin.com/pitu/1/edit

I wanted to try an easy hex to rgba conversion. Ever browser I've used renders colors using rgb as default so when using the farbtastic color picker I'm converting the hex value to rgb by grabbing the background color the hex value generates (as rgb by default = simple conversion)

I tried replacing the ) symbol to , 1), but that didn't work so I went to just see how converting rgb to rgba would work, and I'm still having trouble.

The jquery

$('.torgb').val($('#color').css('background-color'));
$('.torgba').val().replace(/rgb/g,"rgba");

The goal
enter image description here

EDIT:

TinyColor Is a great color manipulation js library that does everything I want here and more. I figure you guys may want to give it a try! - https://github.com/bgrins/TinyColor

158440 次浏览

Pure JS solution if it helps:

function hexToRGB(hex,alphaYes){
var h = "0123456789ABCDEF";
var r = h.indexOf(hex[1])*16+h.indexOf(hex[2]);
var g = h.indexOf(hex[3])*16+h.indexOf(hex[4]);
var b = h.indexOf(hex[5])*16+h.indexOf(hex[6]);
if(alphaYes) return "rgba("+r+", "+g+", "+b+", 1)";
else return "rgb("+r+", "+g+", "+b+")";
}

"alphaYes" is "true" or "false" depending upon whether you want the alpha or not.

Preview

Try This

<div class="torgb" onclick="rgba();" style="background-color:#000; width:20px; height:20px;"></div>
<script>
function rgba(){
$('.torgb').attr('background-color','rgba(0,0,0,1)');
$('.torgb').attr('onclick','hex();');
}
function hex(){
$('.torgb').attr('background-color','#000');
$('.torgb').attr('onclick','rgba();');
}
</script>
//If you write your own code, remember hex color shortcuts (eg., #fff, #000)


function hexToRgbA(hex){
var c;
if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
c= hex.substring(1).split('');
if(c.length== 3){
c= [c[0], c[0], c[1], c[1], c[2], c[2]];
}
c= '0x'+c.join('');
return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+',1)';
}
throw new Error('Bad Hex');
}


hexToRgbA('#fbafff')


/*  returned value: (String)
rgba(251,175,255,1)
*/

@ElDoRado1239 has the right idea, but there's also a cleaner way:

function hexToRGB(hex, alpha) {
var r = parseInt(hex.slice(1, 3), 16),
g = parseInt(hex.slice(3, 5), 16),
b = parseInt(hex.slice(5, 7), 16);


if (alpha) {
return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
} else {
return "rgb(" + r + ", " + g + ", " + b + ")";
}
}


hexToRGB('#FF0000', 0.5);

I liked the @AJFarkas answer and append the support for shortcut hex (#fff) to it

function hexToRGB(hex, alpha) {
if (!hex || [4, 7].indexOf(hex.length) === -1) {
return; // throw new Error('Bad Hex');
}


hex = hex.substr(1);
// if shortcuts (#F00) -> set to normal (#FF0000)
if (hex.length === 3) {
hex = hex.split('').map(function(el){
return el + el + '';
}).join('');
}


var r = parseInt(hex.slice(0, 2), 16),
g = parseInt(hex.slice(2, 4), 16),
b = parseInt(hex.slice(4, 6), 16);


if (alpha !== undefined) {
return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
} else {
return "rgb(" + r + ", " + g + ", " + b + ")";
}
}


document.write(hexToRGB('#FF0000', 0.5));
document.write('<br>');
document.write(hexToRGB('#F00', 0.4));

Here is a function that returns rgb or rgba if you provide an alpha. The function also converts short hex color codes too.

function:

function hexToRgb(hex, alpha) {
hex   = hex.replace('#', '');
var r = parseInt(hex.length == 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2), 16);
var g = parseInt(hex.length == 3 ? hex.slice(1, 2).repeat(2) : hex.slice(2, 4), 16);
var b = parseInt(hex.length == 3 ? hex.slice(2, 3).repeat(2) : hex.slice(4, 6), 16);
if ( alpha ) {
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
}
else {
return 'rgb(' + r + ', ' + g + ', ' + b + ')';
}
}

examples:

hexToRgb('FF0000');// rgb(255, 0, 0)
hexToRgb('#FF0000');// rgb(255, 0, 0)
hexToRgb('#FF0000', 1);// rgba(255, 0, 0, 1)
hexToRgb('F00');// rgb(255, 0, 0)
hexToRgb('#F00');// rgb(255, 0, 0)
hexToRgb('#F00', 1);// rgba(255, 0, 0, 1)

Clean TypeScript version:

hexToRGB(hex: string, alpha: string) {


const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);


if (alpha) {
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}


return `rgb(${r}, ${g}, ${b})`;
}

Based on @AJFarkas's answer.

Here's an ES2015+ version that's a little more defensive and handles the shorthand 3-digit syntax.

/*
* Takes a 3 or 6-digit hex color code, and an optional 0-255 numeric alpha value
*/
function hexToRGB(hex, alpha) {
if (typeof hex !== 'string' || hex[0] !== '#') return null; // or return 'transparent'


const stringValues = (hex.length === 4)
? [hex.slice(1, 2), hex.slice(2, 3), hex.slice(3, 4)].map(n => `${n}${n}`)
: [hex.slice(1, 3), hex.slice(3, 5), hex.slice(5, 7)];
const intValues = stringValues.map(n => parseInt(n, 16));


return (typeof alpha === 'number')
? `rgba(${intValues.join(', ')}, ${alpha})`
: `rgb(${intValues.join(', ')})`;
}

ES6 modern, RegEx free, solution with error checking and constant arrow function, that returns null for errors. If alpha is not given then the default value of one is used:

const hexToRGB = (hex, alpha = 1) => {
let parseString = hex;
if (hex.startsWith('#')) {parseString = hex.slice(1, 7);}
if (parseString.length !== 6) {return null;}
const r = parseInt(parseString.slice(0, 2), 16);
const g = parseInt(parseString.slice(2, 4), 16);
const b = parseInt(parseString.slice(4, 6), 16);
if (isNaN(r) || isNaN(g) || isNaN(b)) {return null;}
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
};

Note: It returns null for errors. You may replace {return null;} with a throw statement: {throw "Not a valid hex color!";}, but then you should call it from within try-catch:

hexToRGB("#3454r5") => null
hexToRGB("#345465") => rgba(52, 84, 101, 1)
hexToRGB("#345465", 0.5) => rgba(52, 84, 101, 0.5)

ES6 function for only handling 6 character hex with or without the '#':

const hex2rgba = (hex, alpha = 1) => {
const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16));
return `rgba(${r},${g},${b},${alpha})`;
};

Usage:

hex2rgba('#af087b', .5)   // returns: rgba(175,8,123,0.5)
hex2rgba('af087b', .5)    // returns: rgba(175,8,123,0.5)
hex2rgba('af087b')        // returns: rgba(175,8,123,1)

Any Hex Form Modular Approach

The main challenge is that as of 2018 there are a few forms of HEX. The 6 char traditional form, the 3 char shorten form, and a new 4 and 8 char form that includes alpha. The following function can handle any HEX form.

const isValidHex = (hex) => /^#([A-Fa-f0-9]{3,4}){1,2}$/.test(hex)


const getChunksFromString = (st, chunkSize) => st.match(new RegExp(`.{${chunkSize}}`, "g"))


const convertHexUnitTo256 = (hexStr) => parseInt(hexStr.repeat(2 / hexStr.length), 16)


const getAlphafloat = (a, alpha) => {
if (typeof a !== "undefined") {return a / 255}
if ((typeof alpha != "number") || alpha <0 || alpha >1){
return 1
}
return alpha
}


export const hexToRGBA = (hex, alpha) => {
if (!isValidHex(hex)) {throw new Error("Invalid HEX")}
const chunkSize = Math.floor((hex.length - 1) / 3)
const hexArr = getChunksFromString(hex.slice(1), chunkSize)
const [r, g, b, a] = hexArr.map(convertHexUnitTo256)
return `rgba(${r}, ${g}, ${b}, ${getAlphafloat(a, alpha)})`
}

Alpha could be provided to the function in the following ways:

  1. As part of a 4, or 8 form HEX .
  2. As a second parameter between 0-1,

OutPut

    const c1 = "#f80"
const c2 = "#f808"
const c3 = "#0088ff"
const c4 = "#0088ff88"
const c5 = "#98736"


console.log(hexToRGBA(c1))   //  rgba(255, 136, 0, 1)
console.log(hexToRGBA(c2))   //  rgba(255, 136, 0, 0.53125)
console.log(hexToRGBA(c3))   //  rgba(0, 136, 255, 1)
console.log(hexToRGBA(c4))   //  rgba(0, 136, 255, 0.53125)
console.log(hexToRGBA(c5))   //  Uncaught Error: Invalid HEX


console.log(hexToRGBA(c1, 0.5))   //  rgba(255, 136, 0, 0.5)
console.log(hexToRGBA(c3, 0.5))   //  rgba(0, 136, 255, 0.5)

And another one based around bit shifting.

// hex can be a string in the format of "fc9a04", "0xfc9a04" or "#fc90a4" (uppercase digits are allowed) or the equivalent number
// alpha should be 0-1
const hex2rgb = (hex, alpha) => {
const c = typeof(hex) === 'string' ? parseInt(hex.replace('#', ''), 16)  : hex;
return `rgb(${c >> 16}, ${(c & 0xff00) >> 8}, ${c & 0xff}, ${alpha})`;
};

Try

let hex2rgba= (hex,a)=> `rgba(${hex.substr(1).match(/../g).map(x=>+`0x${x}`)},${a})`

/// hex - str e.g. "#abcdef"; a - alpha range 0-1; result e.g. "rgba(1,1,1,0)"
let hex2rgba= (hex,a)=> `rgba(${hex.substr(1).match(/../g).map(x=>+`0x${x}`)},${a})`;


function convert() {
console.log(hex2rgba(inp.value,1));
}
<input id="inp" value="#abcdef" >
<button onclick="convert()">convert</button>

Convert HEX with alpha (ahex) in to rgba.

function ahex_to_rba(ahex) {
//clean #
ahex = ahex.substring(1, ahex.length);
ahex = ahex.split('');


var r = ahex[0] + ahex[0],
g = ahex[1] + ahex[1],
b = ahex[2] + ahex[2],
a = ahex[3] + ahex[3];


if (ahex.length >= 6) {
r = ahex[0] + ahex[1];
g = ahex[2] + ahex[3];
b = ahex[4] + ahex[5];
a = ahex[6] + (ahex[7] ? ahex[7] : ahex[6]);
}


var int_r = parseInt(r, 16),
int_g = parseInt(g, 16),
int_b = parseInt(b, 16),
int_a = parseInt(a, 16);




int_a = int_a / 255;


if (int_a < 1 && int_a > 0) int_a = int_a.toFixed(2);


if (int_a || int_a === 0)
return 'rgba('+int_r+', '+int_g+', '+int_b+', '+int_a+')';
return 'rgb('+int_r+', '+int_g+', '+int_b+')';
}

Try it yourself with snippet:

function ahex_to_rba(ahex) {
//clean #
ahex = ahex.substring(1, ahex.length);
ahex = ahex.split('');


var r = ahex[0] + ahex[0],
g = ahex[1] + ahex[1],
b = ahex[2] + ahex[2],
a = ahex[3] + ahex[3];


if (ahex.length >= 6) {
r = ahex[0] + ahex[1];
g = ahex[2] + ahex[3];
b = ahex[4] + ahex[5];
a = ahex[6] + (ahex[7] ? ahex[7] : ahex[6]);
}


var int_r = parseInt(r, 16),
int_g = parseInt(g, 16),
int_b = parseInt(b, 16),
int_a = parseInt(a, 16);




int_a = int_a / 255;


if (int_a < 1 && int_a > 0) int_a = int_a.toFixed(2);


if (int_a || int_a === 0)
return 'rgba('+int_r+', '+int_g+', '+int_b+', '+int_a+')';
return 'rgb('+int_r+', '+int_g+', '+int_b+')';
}




$(function() {
$('#go').click(function() {
$('p b').text(ahex_to_rba($('#hex').val()));
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="hex" type="text" value="#ffaaffaa">
<input id="go" type="button" value="Go">


<p>Result: <b></b></p>

Original Author

Adding to @ElDoRado1239

For those that want to pass alpha value (typescript snippet):

static hexToRGB(hex: string, alpha: number): string {
var h = "0123456789ABCDEF";
var r = h.indexOf(hex[1]) * 16 + h.indexOf(hex[2]);
var g = h.indexOf(hex[3]) * 16 + h.indexOf(hex[4]);
var b = h.indexOf(hex[5]) * 16 + h.indexOf(hex[6]);
if (alpha) {
return `rgba(${r}, ${g}, ${b}, ${alpha})`
}


return `rgba(${r}, ${g}, ${b})`;
}

No need to re-implement the wheel:

Here's a quick function that supports 3, 4, 6 and 8 character color codes:

function hexToRGBA(hex) {
// remove invalid characters
hex = hex.replace(/[^0-9a-fA-F]/g, '');


if (hex.length < 5) {
// 3, 4 characters double-up
hex = hex.split('').map(s => s + s).join('');
}


// parse pairs of two
let rgba = hex.match(/.{1,2}/g).map(s => parseInt(s, 16));


// alpha code between 0 & 1 / default 1
rgba[3] = rgba.length > 3 ? parseFloat(rgba[3] / 255).toFixed(2): 1;


return 'rgba(' + rgba.join(', ') + ')';
}

Here's what it does. It removes any non-hexadecimal characters. If the HEX is shorter than 5 (3 or 4) characters, it doubles each character. It then splits the HEX into pairs of two characters and parses each pair to an integer. If there is an alpha HEX, it's parsed to a float from 0 to 1, otherwise it's defaulted to 1. The RGBA string is then formed by joining the array and returned.

I'm just gonna put this right here:

(str, alpha) => {




if(!/^#([A-Fa-f0-9]{3}){1,2}$/.test(str))
throw new Error('Bad hex')




let c = str.substring(1).split('')
if(c.length === 3) c = [c[0], c[0], c[1], c[1], c[2], c[2]];
c = '0x'+c.join('');
return `rgba(${(c>>16)&255}, ${(c>>8)&255}, ${c&255}, ${alpha})`;


};

function hexToRGB(hex, alpha) {
var r = parseInt(hex.slice(1, 3), 16),
g = parseInt(hex.slice(3, 5), 16),
b = parseInt(hex.slice(5, 7), 16);


if (alpha) {
return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
} else {
return "rgb(" + r + ", " + g + ", " + b + ")";
}
}


hexToRGB('#FF0000', 0.5);

Actually, I like to use ES6 methods alongside preventing myself to using RegExp, RegExp is not safe, I don't trust it, the below answer is TypeScript, if you only need JavaScript just remove types:

// TypeScript


const hex2rgba = (hex: string, alpha = 1): string => {
if (alpha > 1 || alpha < 0) {
throw new Error('alpha is not correct!');
}


const red = parseInt(hex.slice(1, 3), 16);
const green = parseInt(hex.slice(3, 5), 16);
const blue = parseInt(hex.slice(5, 7), 16);


return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
};

After so many years, just for the record, the DOM API does this convertion by default including the alpha. I mean if you do like;

tempElement.style.cssText = "color: #de1e7eaa";
console.log(tempElement.style.color) // <- rgb(222, 30, 126, 0.667)

you get RGB values as a string. Then you may or not process it according to your needs. We can leverage this opportunity if we are lazy enough.

var color = "#de1e7eaa",                 // hex color code in string including alpha
temp  = document.createElement("i"), // just a temporary element
rgbStr,
rgbInt;
temp.style.cssText = `color: ${color}`;  // assign it to the style of the <i> element
rgbStr = temp.style.color;
rgbInt = Array.from(rgbStr.matchAll(/\d+\.?\d*/g), c=> +c[0]) // temp.style.color gives RGB string
// then we convert it to Number if need be
console.log(rgbStr);
console.log(rgbInt);

Modifying @kennebec's solution to have alpha parameter

function hexToRgbA(hex, alpha=1){
if(alpha > 1) alpha = 1;
if(alpha < 0) alpha = 0;
var c;
if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
c= hex.substring(1).split('');
if(c.length== 3){
c= [c[0], c[0], c[1], c[1], c[2], c[2]];
}
c= '0x'+c.join('');
return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+alpha+')';
}
throw new Error('Bad Hex');
}


hexToRgbA('#fce881', 0.6);


/* returned value: (String)
rgba(252,232,129,0.6)
*/

Works with all shortcuts

Based on @kennebec's answer, here is a solution which works with all hex shortcuts (#123, #1234, #123456, #12345678).

const hex2rgba = (hex) => {
let c = hex.substring(1).split('');


if (!/^#(([\dA-Fa-f]{3}){1,2}|([\dA-Fa-f]{4}){1,2})$/.test(hex)) {
throw new Error('Your hexadecimal color is not correct.');
}


switch (c.length) {
case 3:
c = [c[0] + c[0], c[1] + c[1], c[2] + c[2], 'ff'];
break;
case 4:
c = [c[0]+c[0], c[1]+c[1], c[2]+c[2], c[3]+c[3]];
break;
case 6:
c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], 'ff'];
break;
case 8:
c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], c[6]+c[7]];
break;
}


c = c.map((char) => parseInt(char, 16).toString());
c[3] = (Math.round((parseInt(c[3],10)/255)*100)/100).toString();
return c[3] === '1'
? `rgb( ${c[0]}, ${c[1]}, ${c[2]})`
: `rgba(${c[0]}, ${c[1]}, ${c[2]}, ${c[3]})`;
}


//return a rgb or rgba value according to the alpha value
console.log(hex2rgba('#af6'))
console.log(hex2rgba('#af6f'))
console.log(hex2rgba('#af64f576'))

Typescript Version

const hex2rgba = (hex: string): string => {
let c: string[] = hex.substring(1).split('');


if (!/^#(([\dA-Fa-f]{3}){1,2}|([\dA-Fa-f]{4}){1,2})$/.test(hex)) {
throw new Error('Your hexadecimal color is not correct.');
}


switch (c.length) {
case 3:
c = [c[0] + c[0], c[1] + c[1], c[2] + c[2], 'ff'];
break;
case 4:
c = [c[0]+c[0], c[1]+c[1], c[2]+c[2], c[3]+c[3]];
break;
case 6:
c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], 'ff'];
break;
case 8:
c = [c[0]+c[1], c[2]+c[3], c[4]+c[5], c[6]+c[7]];
break;
}


c = c.map((char) => parseInt(char, 16).toString());
c[3] = (Math.round((parseInt(c[3],10)/255)*100)/100).toString();
return c[3] === '1'
? `rgb( ${c[0]}, ${c[1]}, ${c[2]})`
: `rgba(${c[0]}, ${c[1]}, ${c[2]}, ${c[3]})`;
}

This should work for all use cases (short codes, long codes, with/without alpha)

hexToRGBA=q=>{
q=q.replace('#', '')
let l=q.length
if(l!=3 && l!=4 && l!==6 && l!=8) return
let red, green, blue, alpha, red_, green_, blue_, alpha_
switch(l){
case 3:
red_     = q[0]+q[0]
green_   = q[1]+q[1]
blue_    = q[2]+q[2]
alpha    = 255
break
case 4:
red_     = q[0]+q[0]
green_   = q[1]+q[1]
blue_    = q[2]+q[2]
alpha_   = q[3]+q[3]
alpha    = +("0x"+alpha_)
break
case 6:
red_     = q[0]+q[1]
green_   = q[2]+q[3]
blue_    = q[4]+q[5]
alpha    = 255
break
case 8:
red_     = q[0]+q[1]
green_   = q[2]+q[3]
blue_    = q[4]+q[5]
alpha_   = q[6]+q[7]
alpha    = +("0x"+alpha_)
break
}
red    = +("0x"+red_)
green  = +("0x"+green_)
blue   = +("0x"+blue_)
return [red, green, blue, alpha]
}

note: alpha is returned as the 4th element, range 0-255

A clean and readable typescript way: (I could separate type, but it's easier to copy past like that)

export const hexToRGB = (hex: string, alpha: number | undefined = 1) => {
hex = hex.toUpperCase();


const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);


return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}


function* chunks(array, size) {
for (let i = 0; i < array.length; i += size) {
yield array.slice(i, i + size);
}
}


function hexToRgba(hex, opacity = 1) {
const arr = hex.replace("#", "").split("");


return [...chunks(arr, arr.length === 6 ? 2 : 1)].reduce(
(accum, cv, index, array) => {
const lastIndex = array.length - 1 === index;
const int = parseInt(
array.length === 2 ? cv.join("") : cv[0] + cv[0],
16
);


return accum + int + (lastIndex ? `,${opacity})` : ",");
},
"rgba("
);
}


console.log(hexToRgba("#eee", 1));


With a generator and reduce. Can be used with or without a #.

A one-liner if you only need to handle the simple case (i.e. doesn't handle shortcuts like #fff):

"aabbcc".split(/(..)/).filter(c=>c).map(c => parseInt(c, 16))

It's likely overkill for most use cases, but if you need a solution that handles every edge case including all named colors, and actually converts any valid CSS color string (not just hex) to RGBA:

function toRGBA(cssColor) {
let el = document.createElement("div");
el.style.color = cssColor;
el.style.display = "none";
document.body.appendChild(el);
let rgba = window.getComputedStyle(el).getPropertyValue("color");
el.remove();
let [r, g, b, a] = rgba.match(/[0-9.]+/g).map(n => Number(n));
if(a === undefined) a = 1; // <-- getPropertyValue returns rgb(...) if there is no transparency, so we add alpha if missing
return [r, g, b, a];
}
toRGBA("#34f1a8") // [52, 241, 168, 1]
toRGBA("#fe6") // [255, 238, 102, 1]
toRGBA("blue") // [0, 0, 255, 1]
toRGBA("hsl(0, 90%, 50%)") // [242, 13, 13, 1]
...

(Obviously this approach is not appropriate for server-side code like Deno or Node.js)