How to convert colors in RGB format to hex format and vice versa?
For example, convert '#0080C0'
to (0, 128, 192)
.
This question is related to
javascript
colors
hex
rgb
I'm assuming you mean HTML-style hexadecimal notation, i.e. #rrggbb
. Your code is almost correct, except you've got the order reversed. It should be:
var decColor = red * 65536 + green * 256 + blue;
Also, using bit-shifts might make it a bit easier to read:
var decColor = (red << 16) + (green << 8) + blue;
Instead of copy'n'pasting snippets found here and there, I'd recommend to use a well tested and maintained library: Colors.js (available for node.js and browser). It's just 7 KB (minified, gzipped even less).
Here is the Javascript code to change HEX Color value to the Red, Green, Blue individually.
R = hexToR("#FFFFFF");
G = hexToG("#FFFFFF");
B = hexToB("#FFFFFF");
function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
My version of hex2rbg:
String.replace, String.split, String.match
etc..you may need remove hex.trim() if you are using IE8.
e.g.
hex2rgb('#fff') //rgb(255,255,255)
hex2rgb('#fff', 1) //rgba(255,255,255,1)
hex2rgb('#ffffff') //rgb(255,255,255)
hex2rgb('#ffffff', 1) //rgba(255,255,255,1)
code:
function hex2rgb (hex, opacity) {
hex = hex.trim();
hex = hex[0] === '#' ? hex.substr(1) : hex;
var bigint = parseInt(hex, 16), h = [];
if (hex.length === 3) {
h.push((bigint >> 4) & 255);
h.push((bigint >> 2) & 255);
} else {
h.push((bigint >> 16) & 255);
h.push((bigint >> 8) & 255);
}
h.push(bigint & 255);
if (arguments.length === 2) {
h.push(opacity);
return 'rgba('+h.join()+')';
} else {
return 'rgb('+h.join()+')';
}
}
One-line functional HEX to RGBA
Supports both short #fff
and long #ffffff
forms.
Supports alpha channel (opacity).
Does not care if hash specified or not, works in both cases.
function hexToRGBA(hex, opacity) {
return 'rgba(' + (hex = hex.replace('#', '')).match(new RegExp('(.{' + hex.length/3 + '})', 'g')).map(function(l) { return parseInt(hex.length%2 ? l+l : l, 16) }).concat(isFinite(opacity) ? opacity : 1).join(',') + ')';
}
examples:
hexToRGBA('#fff') -> rgba(255,255,255,1)
hexToRGBA('#ffffff') -> rgba(255,255,255,1)
hexToRGBA('#fff', .2) -> rgba(255,255,255,0.2)
hexToRGBA('#ffffff', .2) -> rgba(255,255,255,0.2)
hexToRGBA('fff', .2) -> rgba(255,255,255,0.2)
hexToRGBA('ffffff', .2) -> rgba(255,255,255,0.2)
hexToRGBA('#ffffff', 0) -> rgba(255,255,255,0)
hexToRGBA('#ffffff', .5) -> rgba(255,255,255,0.5)
hexToRGBA('#ffffff', 1) -> rgba(255,255,255,1)
When you're working in 3D environment (webGL, ThreeJS) you sometimes need to create 3 values for the different faces of meshes, the basic one (main color), a lighter one and a darker one :
material.color.set( 0x660000, 0xff0000, 0xff6666 ); // red cube
We can create these 3 values from the main RBG color : 255,0,0
function rgbToHex(rgb) {
var hex = Number(rgb).toString(16);
if (hex.length < 2) {
hex = "0" + hex;
}
return hex;
};
function convertToHex(r,g,b) {
var fact = 100; // contrast
var code = '0x';
// main color
var r_hexa = rgbToHex(r);
var g_hexa = rgbToHex(g);
var b_hexa = rgbToHex(b);
// lighter
var r_light = rgbToHex(Math.floor(r+((1-(r/255))*fact)));
var g_light = rgbToHex(Math.floor(g+((1-(g/255))*fact)));
var b_light = rgbToHex(Math.floor(b+((1-(b/255))*fact)));
// darker
var r_dark = rgbToHex(Math.floor(r-((r/255)*(fact*1.5)))); // increase contrast
var g_dark = rgbToHex(Math.floor(g-((g/255)*(fact*1.5))));
var b_dark = rgbToHex(Math.floor(b-((b/255)*(fact*1.5))));
var hexa = code+r_hexa+g_hexa+b_hexa;
var light = code+r_light+g_light+b_light;
var dark = code+r_dark+g_dark+b_dark;
console.log('HEXs -> '+dark+" + "+hexa+" + "+light)
var colors = [dark, hexa, light];
return colors;
}
In your ThreeJS code simply write:
var material = new THREE.MeshLambertMaterial();
var c = convertToHex(255,0,0); // red cube needed
material.color.set( Number(c[0]), Number(c[1]), Number(c[2]) );
Results:
// dark normal light
convertToHex(255,255,255) HEXs -> 0x696969 + 0xffffff + 0xffffff
convertToHex(255,0,0) HEXs -> 0x690000 + 0xff0000 + 0xff6464
convertToHex(255,127,0) HEXs -> 0x690000 + 0xff0000 + 0xff6464
convertToHex(100,100,100) HEXs -> 0x292929 + 0x646464 + 0xa0a0a0
convertToHex(10,10,10) HEXs -> 0x040404 + 0x0a0a0a + 0x6a6a6a
This code accept #fff and #ffffff variants and opacity.
function hex2rgb(hex, opacity) {
var h=hex.replace('#', '');
h = h.match(new RegExp('(.{'+h.length/3+'})', 'g'));
for(var i=0; i<h.length; i++)
h[i] = parseInt(h[i].length==1? h[i]+h[i]:h[i], 16);
if (typeof opacity != 'undefined') h.push(opacity);
return 'rgba('+h.join(',')+')';
}
I'm working with XAML data that has a hex format of #AARRGGBB (Alpha, Red, Green, Blue). Using the answers above, here's my solution:
function hexToRgba(hex) {
var bigint, r, g, b, a;
//Remove # character
var re = /^#?/;
var aRgb = hex.replace(re, '');
bigint = parseInt(aRgb, 16);
//If in #FFF format
if (aRgb.length == 3) {
r = (bigint >> 4) & 255;
g = (bigint >> 2) & 255;
b = bigint & 255;
return "rgba(" + r + "," + g + "," + b + ",1)";
}
//If in #RRGGBB format
if (aRgb.length >= 6) {
r = (bigint >> 16) & 255;
g = (bigint >> 8) & 255;
b = bigint & 255;
var rgb = r + "," + g + "," + b;
//If in #AARRBBGG format
if (aRgb.length == 8) {
a = ((bigint >> 24) & 255) / 255;
return "rgba(" + rgb + "," + a.toFixed(1) + ")";
}
}
return "rgba(" + rgb + ",1)";
}
In case this helps anyone, my API has functions for those conversions.
<script src="http://api.xlww.net/xQuery/xQuery.js"></script>
<script>
x.init();
var rgb=new x.rgb(37,255,83);
alert(rgb.hex);
var hex=new x.hex("#ffa500");
alert("("+hex.rgb[0]+","+hex.rgb[1]+","+hex.rgb[2]+")");
</script>
If you need compare two color values (given as RGB, name color or hex value) or convert to HEX use HTML5 canvas object.
var canvas = document.createElement("canvas");
var ctx = this.canvas.getContext('2d');
ctx.fillStyle = "rgb(pass,some,value)";
var temp = ctx.fillStyle;
ctx.fillStyle = "someColor";
alert(ctx.fillStyle == temp);
@ Tim, to add to your answer (its a little awkward fitting this into a comment).
As written, I found the rgbToHex function returns a string with elements after the point and it requires that the r, g, b values fall within the range 0-255.
I'm sure this may seem obvious to most, but it took two hours for me to figure out and by then the original method had ballooned to 7 lines before I realised my problem was elsewhere. So in the interests of saving others time & hassle, here's my slightly amended code that checks the pre-requisites and trims off the extraneous bits of the string.
function rgbToHex(r, g, b) {
if(r < 0 || r > 255) alert("r is out of bounds; "+r);
if(g < 0 || g > 255) alert("g is out of bounds; "+g);
if(b < 0 || b > 255) alert("b is out of bounds; "+b);
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1,7);
}
(2017) SIMPLE ES6 composable arrow functions
I can't resist sharing this for those who may be writing some modern functional/compositional js using ES6. Here are some slick one-liners I am using in a color module that does color interpolation for data visualization.
Note that this does not handle the alpha channel at all.
const arrayToRGBString = rgb => `rgb(${rgb.join(',')})`;
const hexToRGBArray = hex => hex.match(/[A-Za-z0-9]{2}/g).map(v => parseInt(v, 16));
const rgbArrayToHex = rgb => `#${rgb.map(v => v.toString(16).padStart(2, '0')).join('')}`;
const rgbStringToArray = rgb => rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).splice(1, 3)
.map(v => Number(v));
const rgbStringToHex = rgb => rgbArrayToHex(rgbStringToArray(rgb));
BTW, If you like this style/syntax, I wrote a full color module (modern-color) you can grab from npm. I made it so I could use prop getters for conversion and parse virtually anything (Color.parse(anything)). Worth a look if you deal with color a lot like I do.
Looks like you're looking for something like this:
function hexstr(number) {
var chars = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f");
var low = number & 0xf;
var high = (number >> 4) & 0xf;
return "" + chars[high] + chars[low];
}
function rgb2hex(r, g, b) {
return "#" + hexstr(r) + hexstr(g) + hexstr(b);
}
I found this...
http://jsfiddle.net/Mottie/xcqpF/1/light/
function rgb2hex(rgb){
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}
Bitwise solution normally is weird. But in this case I guess that is more elegant
function hexToRGB(hexColor){
return {
red: (hexColor >> 16) & 0xFF,
green: (hexColor >> 8) & 0xFF,
blue: hexColor & 0xFF,
}
}
Usage:
const {red, green, blue } = hexToRGB(0xFF00FF)
console.log(red) // 255
console.log(green) // 0
console.log(blue) // 255
const rgbToHex = (r, g, b) => '#' + [r, g, b].map(x => {_x000D_
const hex = x.toString(16)_x000D_
return hex.length === 1 ? '0' + hex : hex_x000D_
}).join('')_x000D_
_x000D_
console.log(rgbToHex(0, 51, 255)); // '#0033ff'
_x000D_
Returns an array [r, g, b]
. Works also with shorthand hex triplets such as "#03F"
.
const hexToRgb = hex =>_x000D_
hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i_x000D_
,(m, r, g, b) => '#' + r + r + g + g + b + b)_x000D_
.substring(1).match(/.{2}/g)_x000D_
.map(x => parseInt(x, 16))_x000D_
_x000D_
console.log(hexToRgb("#0033ff")) // [0, 51, 255]_x000D_
console.log(hexToRgb("#03f")) // [0, 51, 255]
_x000D_
padStart()
methodconst rgbToHex = (r, g, b) => '#' + [r, g, b]_x000D_
.map(x => x.toString(16).padStart(2, '0')).join('')_x000D_
_x000D_
console.log(rgbToHex(0, 51, 255)); // '#0033ff'
_x000D_
Note that this answer uses latest ECMAScript features, which are not supported in older browsers. If you want this code to work in all environments, you should use Babel to compile your code.
function rgbToHex(a){_x000D_
a=a.replace(/[^\d,]/g,"").split(","); _x000D_
return"#"+((1<<24)+(+a[0]<<16)+(+a[1]<<8)+ +a[2]).toString(16).slice(1)_x000D_
}_x000D_
_x000D_
document.write(rgbToHex("rgb(255,255,255)"));
_x000D_
function rgbToHex(a){_x000D_
if(~a.indexOf("#"))return a;_x000D_
a=a.replace(/[^\d,]/g,"").split(","); _x000D_
return"#"+((1<<24)+(+a[0]<<16)+(+a[1]<<8)+ +a[2]).toString(16).slice(1)_x000D_
}_x000D_
_x000D_
document.write("rgb: "+rgbToHex("rgb(255,255,255)")+ " -- hex: "+rgbToHex("#e2e2e2"));
_x000D_
// Ignoring hsl notation, color values are commonly expressed as names, rgb, rgba or hex-
// Hex can be 3 values or 6.
// Rgb can be percentages as well as integer values.
// Best to account for all of these formats, at least.
String.prototype.padZero= function(len, c){
var s= this, c= c || "0", len= len || 2;
while(s.length < len) s= c + s;
return s;
}
var colors={
colornames:{
aqua: '#00ffff', black: '#000000', blue: '#0000ff', fuchsia: '#ff00ff',
gray: '#808080', green: '#008000', lime: '#00ff00', maroon: '#800000',
navy: '#000080', olive: '#808000', purple: '#800080', red: '#ff0000',
silver: '#c0c0c0', teal: '#008080', white: '#ffffff', yellow: '#ffff00'
},
toRgb: function(c){
c= '0x'+colors.toHex(c).substring(1);
c= [(c>> 16)&255, (c>> 8)&255, c&255];
return 'rgb('+c.join(',')+')';
},
toHex: function(c){
var tem, i= 0, c= c? c.toString().toLowerCase(): '';
if(/^#[a-f0-9]{3,6}$/.test(c)){
if(c.length< 7){
var A= c.split('');
c= A[0]+A[1]+A[1]+A[2]+A[2]+A[3]+A[3];
}
return c;
}
if(/^[a-z]+$/.test(c)){
return colors.colornames[c] || '';
}
c= c.match(/\d+(\.\d+)?%?/g) || [];
if(c.length<3) return '';
c= c.slice(0, 3);
while(i< 3){
tem= c[i];
if(tem.indexOf('%')!= -1){
tem= Math.round(parseFloat(tem)*2.55);
}
else tem= parseInt(tem);
if(tem< 0 || tem> 255) c.length= 0;
else c[i++]= tem.toString(16).padZero(2);
}
if(c.length== 3) return '#'+c.join('').toLowerCase();
return '';
}
}
//var c='#dc149c';
//var c='rgb(100%,25%,0)';
//
var c= 'red';
alert(colors.toRgb(c)+'\n'+colors.toHex(c));
You can try this simple piece of code below.
For HEX to RGB
list($r, $g, $b) = sscanf(#7bde84, "#%02x%02x%02x");
echo $r . "," . $g . "," . $b;
This will return 123,222,132
For RGB to HEX
$rgb = (123,222,132),
$rgbarr = explode(",",$rgb,3);
echo sprintf("#%02x%02x%02x", $rgbarr[0], $rgbarr[1], $rgbarr[2]);
This will return #7bde84
R = HexToR("#FFFFFF");
G = HexToG("#FFFFFF");
B = HexToB("#FFFFFF");
function HexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
function HexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
function HexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
Use these Function to achive the result without any issue. :)
function hex2rgb(hex) {
return ['0x' + hex[1] + hex[2] | 0, '0x' + hex[3] + hex[4] | 0, '0x' + hex[5] + hex[6] | 0];
}
Try (bonus)
let hex2rgb= c=> `rgb(${c.substr(1).match(/../g).map(x=>+`0x${x}`)})`;
let rgb2hex= c=>'#'+c.match(/\d+/g).map(x=>(+x).toString(16).padStart(2,0)).join``
let hex2rgb= c=> `rgb(${c.substr(1).match(/../g).map(x=>+`0x${x}`)})`;
let rgb2hex= c=> '#'+c.match(/\d+/g).map(x=>(+x).toString(16).padStart(2,0)).join``;
// TEST
console.log('#0080C0 -->', hex2rgb('#0080C0'));
console.log('rgb(0, 128, 192) -->', rgb2hex('rgb(0, 128, 192)'));
_x000D_
I whipped up this for use with lodash. It will convert an RGB string such as "30,209,19"
to its corresponding hex string "#1ed113"
:
var rgb = '30,209,19';
var hex = _.reduce(rgb.split(','), function(hexAccumulator, rgbValue) {
var intColor = _.parseInt(rgbValue);
if (_.isNaN(intColor)) {
throw new Error('The value ' + rgbValue + ' was not able to be converted to int');
}
// Ensure a value such as 2 is converted to "02".
var hexColor = _.padLeft(intColor.toString(16), 2, '0');
return hexAccumulator + hexColor;
}, '#');
While this answer is unlikely to fit the question perfectly it may be very useful none the less.
var toRgb = document.createElement('div');
toRg.style.color = "hsl(120, 60%, 70%)";
> toRgb.style.color;
< "rgb(133, 225, 133)"
Your color has been converted to Rgb
Works for: Hsl, Hex
Does not work for: Named colors
Fairly straightforward one liner. Splits the rgb by commas, ignores non numerics, converts to hex, pads a 0, and finishes off with a hashbang.
var yellow = 'rgb(255, 255, 0)';_x000D_
var rgb2hex = str => "#"+str.split(',').map(s => (s.replace(/\D/g,'')|0).toString(16)).map(s => s.length < 2 ? "0"+s : s).join('');_x000D_
_x000D_
console.log(rgb2hex(yellow));
_x000D_
For convert directly from jQuery you can try:
function rgbToHex(color) {
var bg = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(bg[1]) + hex(bg[2]) + hex(bg[3]);
}
rgbToHex($('.col-tab-bar .col-tab span').css('color'))
This snippet converts hex to rgb and rgb to hex.
function hexToRgb(str) {
if ( /^#([0-9a-f]{3}|[0-9a-f]{6})$/ig.test(str) ) {
var hex = str.substr(1);
hex = hex.length == 3 ? hex.replace(/(.)/g, '$1$1') : hex;
var rgb = parseInt(hex, 16);
return 'rgb(' + [(rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255].join(',') + ')';
}
return false;
}
function rgbToHex(red, green, blue) {
var out = '#';
for (var i = 0; i < 3; ++i) {
var n = typeof arguments[i] == 'number' ? arguments[i] : parseInt(arguments[i]);
if (isNaN(n) || n < 0 || n > 255) {
return false;
}
out += (n < 16 ? '0' : '') + n.toString(16);
}
return out
}
Using combining anonymous functions and Array.map
for a cleaner; more streamlined look.
var write=function(str){document.body.innerHTML=JSON.stringify(str,null,' ');};_x000D_
_x000D_
function hexToRgb(hex, asObj) {_x000D_
return (function(res) {_x000D_
return res == null ? null : (function(parts) {_x000D_
return !asObj ? parts : { r : parts[0], g : parts[1], b : parts[2] }_x000D_
}(res.slice(1,4).map(function(val) { return parseInt(val, 16); })));_x000D_
}(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)));_x000D_
}_x000D_
_x000D_
function rgbToHex(r, g, b) {_x000D_
return (function(values) {_x000D_
return '#' + values.map(function(intVal) {_x000D_
return (function(hexVal) {_x000D_
return hexVal.length == 1 ? "0" + hexVal : hexVal;_x000D_
}(intVal.toString(16)));_x000D_
}).join('');_x000D_
}(arguments.length === 1 ? Array.isArray(r) ? r : [r.r, r.g, r.b] : [r, g, b]))_x000D_
}_x000D_
_x000D_
// Prints: { r: 255, g: 127, b: 92 }_x000D_
write(hexToRgb(rgbToHex(hexToRgb(rgbToHex(255, 127, 92), true)), true));
_x000D_
body{font-family:monospace;white-space:pre}
_x000D_
A simple answer for rgb to hex
function rgbtohex(r,g,b){
return "#" + (Math.round(r) * 65536 + Math.round(g) * 256 + Math.round(b)).toString(16));
}
A clean coffeescript version of the above (thanks @TimDown):
rgbToHex = (rgb) ->
a = rgb.match /\d+/g
rgb unless a.length is 3
"##{ ((1 << 24) + (parseInt(a[0]) << 16) + (parseInt(a[1]) << 8) + parseInt(a[2])).toString(16).slice(1) }"
May you be after something like this?
function RGB2HTML(red, green, blue)
{
return '#' + red.toString(16) +
green.toString(16) +
blue.toString(16);
}
alert(RGB2HTML(150, 135, 200));
displays #9687c8
CSS Level 4 side note: Generally, the reason you'd want to be able to convert Hex to RGB is for the alpha channel, in which case you can soon do that with CSS4 by adding a trailing hex. Example: #FF8800FF
or #f80f
for fully transparent orange.
That aside, the code below answers both the questions in a single function, going from and to another. This accepts an optional alpha channel, supports both string an array formats, parses 3,4,6,7 character hex's, and rgb/a complete or partial strings (with exception of percent-defined rgb/a values) without a flag.
(Replace the few ES6 syntaxes if supporting IE)
In a line:
function rgbaHex(c,a,i){return(Array.isArray(c)||(typeof c==='string'&&/,/.test(c)))?((c=(Array.isArray(c)?c:c.replace(/[\sa-z\(\);]+/gi,'').split(',')).map(s=>parseInt(s).toString(16).replace(/^([a-z\d])$/i,'0$1'))),'#'+c[0]+c[1]+c[2]):(c=c.replace(/#/,''),c=c.length%6?c.replace(/(.)(.)(.)/,'$1$1$2$2$3$3'):c,a=parseFloat(a)||null,`rgb${a?'a':''}(${[(i=parseInt(c,16))>>16&255,i>>8&255,i&255,a].join().replace(/,$/,'')})`);}
Readable version:
function rgbaHex(c, a) {
// RGBA to Hex
if (Array.isArray(c) || (typeof c === 'string' && /,/.test(c))) {
c = Array.isArray(c) ? c : c.replace(/[\sa-z\(\);]+/gi, '').split(',');
c = c.map(s => window.parseInt(s).toString(16).replace(/^([a-z\d])$/i, '0$1'));
return '#' + c[0] + c[1] + c[2];
}
// Hex to RGBA
else {
c = c.replace(/#/, '');
c = c.length % 6 ? c.replace(/(.)(.)(.)/, '$1$1$2$2$3$3') : c;
c = window.parseInt(c, 16);
a = window.parseFloat(a) || null;
const r = (c >> 16) & 255;
const g = (c >> 08) & 255;
const b = (c >> 00) & 255;
return `rgb${a ? 'a' : ''}(${[r, g, b, a].join().replace(/,$/,'')})`;
}
}
Usages:
rgbaHex('#a8f')
rgbaHex('#aa88ff')
rgbaHex('#A8F')
rgbaHex('#AA88FF')
rgbaHex('#AA88FF', 0.5)
rgbaHex('#a8f', '0.85')
// etc.
rgbaHex('rgba(170,136,255,0.8);')
rgbaHex('rgba(170,136,255,0.8)')
rgbaHex('rgb(170,136,255)')
rgbaHex('rg170,136,255')
rgbaHex(' 170, 136, 255 ')
rgbaHex([170,136,255,0.8])
rgbaHex([170,136,255])
// etc.
For those who value short arrow function.
A arrow function version of David's Answer
const hex2rgb = h => [(x=parseInt(h,16)) >> 16 & 255,x >> 8 & 255, x & 255];
A more flexible solution that supports shortand hex or the hash #
const hex2rgb = h => {
if(h[0] == '#') {h = h.slice(1)};
if(h.length <= 3) {h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2]};
h = parseInt(h,16);
return [h >> 16 & 255,h >> 8 & 255, h & 255];
};
const rgb2hex = (r,g,b) => ((1<<24)+(r<<16)+(g<<8)+b).toString(16).slice(1);
i needed a function that accepts invalid values too like
rgb(-255, 255, 255) rgb(510, 255, 255)
this is a spin off of @cwolves answer
function rgb(r, g, b) {
this.c = this.c || function (n) {
return Math.max(Math.min(n, 255), 0)
};
return ((1 << 24) + (this.c(r) << 16) + (this.c(g) << 8) + this.c(b)).toString(16).slice(1).toUpperCase();
}
My example =)
color: {_x000D_
toHex: function(num){_x000D_
var str = num.toString(16);_x000D_
return (str.length<6?'#00'+str:'#'+str);_x000D_
},_x000D_
toNum: function(hex){_x000D_
return parseInt(hex.replace('#',''), 16);_x000D_
},_x000D_
rgbToHex: function(color)_x000D_
{_x000D_
color = color.replace(/\s/g,"");_x000D_
var aRGB = color.match(/^rgb\((\d{1,3}[%]?),(\d{1,3}[%]?),(\d{1,3}[%]?)\)$/i);_x000D_
if(aRGB)_x000D_
{_x000D_
color = '';_x000D_
for (var i=1; i<=3; i++) color += Math.round((aRGB[i][aRGB[i].length-1]=="%"?2.55:1)*parseInt(aRGB[i])).toString(16).replace(/^(.)$/,'0$1');_x000D_
}_x000D_
else color = color.replace(/^#?([\da-f])([\da-f])([\da-f])$/i, '$1$1$2$2$3$3');_x000D_
return '#'+color;_x000D_
}
_x000D_
The top rated answer by Tim Down provides the best solution I can see for conversion to RGB. I like this solution for Hex conversion better though because it provides the most succinct bounds checking and zero padding for conversion to Hex.
function RGBtoHex (red, green, blue) {
red = Math.max(0, Math.min(~~this.red, 255));
green = Math.max(0, Math.min(~~this.green, 255));
blue = Math.max(0, Math.min(~~this.blue, 255));
return '#' + ('00000' + (red << 16 | green << 8 | blue).toString(16)).slice(-6);
};
The use of left shift '<<' and or '|' operators make this a fun solution too.
function getRGB(color){
if(color.length == 7){
var r = parseInt(color.substr(1,2),16);
var g = parseInt(color.substr(3,2),16);
var b = parseInt(color.substr(5,2),16);
return 'rgb('+r+','+g+','+b+')' ;
}
else
console.log('Enter correct value');
}
var a = getRGB('#f0f0f0');
if(!a){
a = 'Enter correct value';
}
a;
This could be used for getting colors from computed style propeties:
function rgbToHex(color) {
color = ""+ color;
if (!color || color.indexOf("rgb") < 0) {
return;
}
if (color.charAt(0) == "#") {
return color;
}
var nums = /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/i.exec(color),
r = parseInt(nums[2], 10).toString(16),
g = parseInt(nums[3], 10).toString(16),
b = parseInt(nums[4], 10).toString(16);
return "#"+ (
(r.length == 1 ? "0"+ r : r) +
(g.length == 1 ? "0"+ g : g) +
(b.length == 1 ? "0"+ b : b)
);
}
// not computed
<div style="color: #4d93bc; border: 1px solid red;">...</div>
// computed
<div style="color: rgb(77, 147, 188); border: 1px solid rgb(255, 0, 0);">...</div>
console.log( rgbToHex(color) ) // #4d93bc
console.log( rgbToHex(borderTopColor) ) // #ff0000
An alternative version of hexToRgb:
function hexToRgb(hex) {
var bigint = parseInt(hex, 16);
var r = (bigint >> 16) & 255;
var g = (bigint >> 8) & 255;
var b = bigint & 255;
return r + "," + g + "," + b;
}
Edit: 3/28/2017
Here is another approach that seems to be even faster
function hexToRgbNew(hex) {
var arrBuff = new ArrayBuffer(4);
var vw = new DataView(arrBuff);
vw.setUint32(0,parseInt(hex, 16),false);
var arrByte = new Uint8Array(arrBuff);
return arrByte[1] + "," + arrByte[2] + "," + arrByte[3];
}
Edit: 8/11/2017 The new approach above after more testing is not faster :(. Though it is a fun alternate way.
A total different approach to convert hex color code to RGB without regex
It handles both #FFF
and #FFFFFF
format on the base of length of string. It removes #
from beginning of string and divides each character of string and converts it to base10 and add it to respective index on the base of it's position.
//Algorithm of hex to rgb conversion in ES5_x000D_
function hex2rgbSimple(str){_x000D_
str = str.replace('#', '');_x000D_
return str.split('').reduce(function(result, char, index, array){_x000D_
var j = parseInt(index * 3/array.length);_x000D_
var number = parseInt(char, 16);_x000D_
result[j] = (array.length == 3? number : result[j]) * 16 + number;_x000D_
return result;_x000D_
},[0,0,0]);_x000D_
}_x000D_
_x000D_
//Same code in ES6_x000D_
hex2rgb = str => str.replace('#','').split('').reduce((r,c,i,{length: l},j,n)=>(j=parseInt(i*3/l),n=parseInt(c,16),r[j]=(l==3?n:r[j])*16+n,r),[0,0,0]);_x000D_
_x000D_
//hex to RGBA conversion_x000D_
hex2rgba = (str, a) => str.replace('#','').split('').reduce((r,c,i,{length: l},j,n)=>(j=parseInt(i*3/l),n=parseInt(c,16),r[j]=(l==3?n:r[j])*16+n,r),[0,0,0,a||1]);_x000D_
_x000D_
//hex to standard RGB conversion_x000D_
hex2rgbStandard = str => `RGB(${str.replace('#','').split('').reduce((r,c,i,{length: l},j,n)=>(j=parseInt(i*3/l),n=parseInt(c,16),r[j]=(l==3?n:r[j])*16+n,r),[0,0,0]).join(',')})`;_x000D_
_x000D_
_x000D_
console.log(hex2rgb('#aebece'));_x000D_
console.log(hex2rgbSimple('#aebece'));_x000D_
_x000D_
console.log(hex2rgb('#aabbcc'));_x000D_
_x000D_
console.log(hex2rgb('#abc'));_x000D_
_x000D_
console.log(hex2rgba('#abc', 0.7));_x000D_
_x000D_
console.log(hex2rgbStandard('#abc'));
_x000D_
I found this and because I think it is pretty straight forward and has validation tests and supports alpha values (optional), this will fit the case.
Just comment out the regex line if you know what you're doing and it's a tiny bit faster.
function hexToRGBA(hex, alpha){
hex = (""+hex).trim().replace(/#/g,""); //trim and remove any leading # if there (supports number values as well)
if (!/^(?:[0-9a-fA-F]{3}){1,2}$/.test(hex)) throw ("not a valid hex string"); //Regex Validator
if (hex.length==3){hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]} //support short form
var b_int = parseInt(hex, 16);
return "rgba("+[
(b_int >> 16) & 255, //R
(b_int >> 8) & 255, //G
b_int & 255, //B
alpha || 1 //add alpha if is set
].join(",")+")";
}
Immutable and human understandable version without any bitwise magic:
value < 0
or value > 255
using Math.min()
and Math.max()
hex
notation using String.toString()
function rgbToHex(r, g, b) {
return [r, g, b]
.map(color => {
const normalizedColor = Math.max(0, Math.min(255, color));
const hexColor = normalizedColor.toString(16);
return `0${hexColor}`.slice(-2);
})
.join("");
}
Yes, it won't be as performant as bitwise operators but way more readable and immutable so it will not modify any input
Here's my version:
function rgb_to_hex(red, green, blue) {
const rgb = (red << 16) | (green << 8) | (blue << 0);
return '#' + (0x1000000 + rgb).toString(16).slice(1);
}
function hex_to_rgb(hex) {
const normal = hex.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
if (normal) return normal.slice(1).map(e => parseInt(e, 16));
const shorthand = hex.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i);
if (shorthand) return shorthand.slice(1).map(e => 0x11 * parseInt(e, 16));
return null;
}
For 3 digits hexToRgb function of Tim Down can be improved as below:
var hex2Rgb = function(hex){
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})|([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i.exec(hex);
return result ? {
r: parseInt(hex.length <= 4 ? result[4]+result[4] : result[1], 16),
g: parseInt(hex.length <= 4 ? result[5]+result[5] : result[2], 16),
b: parseInt(hex.length <= 4 ? result[6]+result[6] : result[3], 16),
toString: function() {
var arr = [];
arr.push(this.r);
arr.push(this.g);
arr.push(this.b);
return "rgb(" + arr.join(",") + ")";
}
} : null;
};
I came across this problem since I wanted to parse any color string value and be able to specify an opacity, so I wrote this function that uses the canvas API.
var toRGBA = function () {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = 1;
canvas.height = 1;
return function (color) {
context.fillStyle = color;
context.fillRect(0, 0, 1, 1);
var data = context.getImageData(0, 0, 1, 1).data;
return {
r: data[0],
g: data[1],
b: data[2],
a: data[3]
};
};
}();
Note about context.fillStyle
:
If parsing the value results in failure, then it must be ignored, and the attribute must retain its previous value.
Here's a Stack Snippet demo you can use to test inputs:
var toRGBA = function () {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = 1;
canvas.height = 1;
return function (color) {
context.fillStyle = color;
context.fillRect(0, 0, 1, 1);
var data = context.getImageData(0, 0, 1, 1).data;
return {
r: data[0],
g: data[1],
b: data[2],
a: data[3]
};
};
}();
var inputs = document.getElementsByTagName('input');
function setColor() {
inputs[1].value = JSON.stringify(toRGBA(inputs[0].value));
document.body.style.backgroundColor = inputs[0].value;
}
inputs[0].addEventListener('input', setColor);
setColor();
_x000D_
input {
width: 200px;
margin: 0.5rem;
}
_x000D_
<input value="cyan" />
<input readonly="readonly" />
_x000D_
I made a small Javascript color class for RGB and Hex colors, this class also includes RGB and Hex validation functions. I've added the code as a snippet to this answer.
var colorClass = function() {_x000D_
this.validateRgb = function(color) {_x000D_
return typeof color === 'object' &&_x000D_
color.length === 3 &&_x000D_
Math.min.apply(null, color) >= 0 &&_x000D_
Math.max.apply(null, color) <= 255;_x000D_
};_x000D_
this.validateHex = function(color) {_x000D_
return color.match(/^\#?(([0-9a-f]{3}){1,2})$/i);_x000D_
};_x000D_
this.hexToRgb = function(color) {_x000D_
var hex = color.replace(/^\#/, '');_x000D_
var length = hex.length;_x000D_
return [_x000D_
parseInt(length === 6 ? hex['0'] + hex['1'] : hex['0'] + hex['0'], 16),_x000D_
parseInt(length === 6 ? hex['2'] + hex['3'] : hex['1'] + hex['1'], 16),_x000D_
parseInt(length === 6 ? hex['4'] + hex['5'] : hex['2'] + hex['2'], 16)_x000D_
];_x000D_
};_x000D_
this.rgbToHex = function(color) {_x000D_
return '#' +_x000D_
('0' + parseInt(color['0'], 10).toString(16)).slice(-2) +_x000D_
('0' + parseInt(color['1'], 10).toString(16)).slice(-2) +_x000D_
('0' + parseInt(color['2'], 10).toString(16)).slice(-2);_x000D_
};_x000D_
};_x000D_
_x000D_
var colors = new colorClass();_x000D_
console.log(colors.hexToRgb('#FFFFFF'));// [255, 255, 255]_x000D_
console.log(colors.rgbToHex([255, 255, 255]));// #FFFFFF
_x000D_
Based on @MichalPerlakowski answer (EcmaScipt 6) and his answer based on Tim Down's answer
I wrote a modified version of the function of converting hexToRGB with the addition of safe checking if the r/g/b color components are between 0-255 and also the funtions can take Number r/g/b params or String r/g/b parameters and here it is:
function rgbToHex(r, g, b) {
r = Math.abs(r);
g = Math.abs(g);
b = Math.abs(b);
if ( r < 0 ) r = 0;
if ( g < 0 ) g = 0;
if ( b < 0 ) b = 0;
if ( r > 255 ) r = 255;
if ( g > 255 ) g = 255;
if ( b > 255 ) b = 255;
return '#' + [r, g, b].map(x => {
const hex = x.toString(16);
return hex.length === 1 ? '0' + hex : hex
}).join('');
}
To use the function safely - you should ckeck whether the passing string is a real rbg string color - for example a very simple check could be:
if( rgbStr.substring(0,3) === 'rgb' ) {
let rgbColors = JSON.parse(rgbStr.replace('rgb(', '[').replace(')', ']'))
rgbStr = this.rgbToHex(rgbColors[0], rgbColors[1], rgbColors[2]);
.....
}
Source: Stackoverflow.com