Reputation: 10839
How to convert colors in RGB format to hex format and vice versa?
For example, convert '#0080C0'
to (0, 128, 192)
.
Upvotes: 844
Views: 863507
Reputation: 403
Here is the code I use for many web-related projects. This method has no regex and easily translates to other languages. Support includes alpha and three-digit formats.
Usage example (uppercase values are fine too):
// Example usage:
console.log(colorfromHex("#ff00ff")); // { r: 255, g: 0, b: 255, a: 255 }
const color = { r: 255, g: 0, b: 255, a: 255 };
console.log("Hex:", RGBAToHex(color)); // #ff00ff
Supported string formats:
"fff" // RGB
"#fff" // #RGB
"ffff" // RGBA
"#ffff" // #RGBA
"ffffff" // RRGGBB
"#ffffff" // #RRGGBB
"ffffffff" // RRGGBBAA
"#ffffffff" // #RRGGBBAA
The digits represent Red, Green, Blue and Alpha (like transparency).
Code:
function colorfromHex(hex) {
var r = 0, g = 0, b = 0, a = 255;
var offset = hex.startsWith("#") ? 1 : 0;
if (hex.length == 4 + offset) {
r = parseInt(hex[offset] + hex[offset], 16);
g = parseInt(hex[offset+1] + hex[offset+1], 16);
b = parseInt(hex[offset+2] + hex[offset+2], 16);
a = parseInt(hex[offset+3] + hex[offset+3], 16);
} else if (hex.length == 8 + offset) {
a = parseInt(hex[offset+6] + hex[offset+7], 16);
r = parseInt(hex[offset] + hex[offset+1], 16);
g = parseInt(hex[offset+2] + hex[offset+3], 16);
b = parseInt(hex[offset+4] + hex[offset+5], 16);
} else if (hex.length == 6 + offset) {
r = parseInt(hex[offset] + hex[offset+1], 16);
g = parseInt(hex[offset+2] + hex[offset+3], 16);
b = parseInt(hex[offset+4] + hex[offset+5], 16);
} else {
r = g = b = a = 0;
}
return { r: r, g: g, b: b, a: a };
}
function RGBAToHex({r, g, b, a = 255}) {
const toHex = (n) => n.toString(16).padStart(2, '0');
return `#${toHex(r)}${toHex(g)}${toHex(b)}${a < 255 ? toHex(a) : ''}`;
}
// Color from a web-style hex string -- for named colors, see https://gist.github.com/akingdom/0a0edd3ea37a9a331983cff3a69c4bee
// By Andrew Kingdom
// MIT license (use free and do not remove this author's name, etc)
License: MIT
Caveat:
Hex colours originating from Android are usually in format AARRGGBB and will thus require reformatting. e.g. const newColor = color.slice(-2) + color.slice(0,6)
Source:
https://gist.github.com/akingdom/0a0edd3ea37a9a331983cff3a69c4bee
Upvotes: 1
Reputation: 643
RGB to HEX (CodeWars)
const convertToHex = (color) => {
if(color < 0){color = 0}
else if(color > 255){color = 255};
const hex = color.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
const rgb = (r, g, b) => (
(convertToHex(r) + convertToHex(g) + convertToHex(b)).toUpperCase()
)
Upvotes: 0
Reputation: 92347
let hex2rgb= c=> `rgb(${c.match(/\w\w/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.match(/\w\w/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)'));
Upvotes: 30
Reputation: 6531
Surprised this answer hasn't come up.
const toRGB = (color) => {
const { style } = new Option();
style.color = color;
return style.color;
}
// handles any color the browser supports and converts it.
console.log(toRGB("#333")) // rgb(51, 51, 51);
console.log(toRGB("hsl(30, 30%, 30%)"))
Upvotes: 28
Reputation: 902
basically, hex to rgb:
var hex = '0080C0'.match(/.{1,2}/g).map(e=>parseInt(e, 16));
if you want string
var rgb = `rgb(${hex.join(", ")})`
rgb to hex:
var rgb_arr = [0, 128, 40];
var rgb = "#" + rgb_arr.map(e=>e.toString(16).padStart(2, 0)).join("")
Upvotes: 3
Reputation: 2039
Wow. None of these answers handle edge cases of fractions, etc. Also the bit-shift versions don't work when r, g, b are zero.
Here is a version that can handle if r, g, b are fractional. It is useful for interpolating between colors, so I'm including that code too. But it still doesn't handle the cases where r, g, b are outside the range of 0-255
/**
* Operates with colors.
* @class Q.Colors
*/
Q.Color = {
/**
* Get a color somewhere between startColor and endColor
* @method toHex
* @static
* @param {String|Number} startColor
* @param {String|Number} endColor
* @param {String|Number} fraction
* @returns {String} a color as a hex string without '#' in front
*/
toHex: function (r, g, b) {
return [r, g, b].map(x => {
const hex = Math.round(x).toString(16)
return hex.length === 1 ? '0' + hex : hex
}).join('');
},
/**
* Get a color somewhere between startColor and endColor
* @method between
* @static
* @param {String|Number} startColor
* @param {String|Number} endColor
* @param {String|Number} fraction
* @returns {String} a color as a hex string without '#' in front
*/
between: function(startColor, endColor, fraction) {
if (typeof startColor === 'string') {
startColor = parseInt(startColor.replace('#', '0x'), 16);
}
if (typeof endColor === 'string') {
endColor = parseInt(endColor.replace('#', '0x'), 16);
}
var startRed = (startColor >> 16) & 0xFF;
var startGreen = (startColor >> 8) & 0xFF;
var startBlue = startColor & 0xFF;
var endRed = (endColor >> 16) & 0xFF;
var endGreen = (endColor >> 8) & 0xFF;
var endBlue = endColor & 0xFF;
var newRed = startRed + fraction * (endRed - startRed);
var newGreen = startGreen + fraction * (endGreen - startGreen);
var newBlue = startBlue + fraction * (endBlue - startBlue);
return Q.Color.toHex(newRed, newGreen, newBlue);
},
/**
* Sets a new theme-color on the window
* @method setWindowTheme
* @static
* @param {String} color in any CSS format, such as "#aabbcc"
* @return {String} the previous color
*/
setWindowTheme: function (color) {
var meta = document.querySelector('meta[name="theme-color"]');
var prevColor = null;
if (meta) {
prevColor = meta.getAttribute('content');
}
if (color) {
if (!meta) {
meta = document.createElement('meta');
meta.setAttribute('name', 'theme-color');
}
meta.setAttribute('content', color);
}
return prevColor;
},
/**
* Gets the current window theme color
* @method getWindowTheme
* @static
* @param {String} color in any CSS format, such as "#aabbcc"
* @return {String} the previous color
*/
getWindowTheme: function () {
var meta = document.querySelector('meta[name="theme-color"]');
return meta.getAttribute('content');
}
}
Upvotes: -1
Reputation: 324477
Note: both versions of rgbToHex
expect integer values for r
, g
and b
, so you'll need to do your own rounding if you have non-integer values.
The following will do to the RGB to hex conversion and add any required zero padding:
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
alert(rgbToHex(0, 51, 255)); // #0033ff
Converting the other way:
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
alert(hexToRgb("#0033ff").g); // "51";
Finally, an alternative version of rgbToHex()
, as discussed in @casablanca's answer and suggested in the comments by @cwolves:
function rgbToHex(r, g, b) {
return "#" + (1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1);
}
alert(rgbToHex(0, 51, 255)); // #0033ff
Here's a version of hexToRgb()
that also parses a shorthand hex triplet such as "#03F":
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
alert(hexToRgb("#0033ff").g); // "51";
alert(hexToRgb("#03f").g); // "51";
Upvotes: 1707
Reputation: 3734
A readable oneliner for rgb string to hex string:
rgb = "rgb(0,128,255)"
hex = '#' + rgb.slice(4,-1).split(',').map(x => (+x).toString(16).padStart(2,0)).join('')
which returns here "#0080ff"
.
Upvotes: 0
Reputation: 561
You can use this oneliner using padStart()
:
const rgb = (r, g, b) => {
return `#${[r, g, b].map((x) => x.toString(16).padStart(2, "0")).join("")}`;
}
P.S. it isn't supported on legacy browsers, check its compatibility here.
If you don't want to use padStart()
, you can implement this function instead:
const rgb = (r, g, b) => {
return `#${[r, g, b]
.map((n) =>
n.toString(16).length === 1 ? "0" + n.toString(16) : n.toString(16)
)
.join("")}`;
};
If you're not sure who is going to use your function, you have to use the parameters validations, that the values are valid (between 0 and 255), to do so, add these conditions before each return
:
if (r > 255) r = 255; else if (r < 0) r = 0;
if (g > 255) g = 255; else if (g < 0) g = 0;
if (b > 255) b = 255; else if (b < 0) b = 0;
So the two above examples become:
const rgb = (r, g, b) => {
if (r > 255) r = 255; else if (r < 0) r = 0;
if (g > 255) g = 255; else if (g < 0) g = 0;
if (b > 255) b = 255; else if (b < 0) b = 0;
return `#${[r, g, b].map((x) => x.toString(16).padStart(2, "0")).join("")}`;
};
const rgb2 = (r, g, b) => {
if (r > 255) r = 255; else if (r < 0) r = 0;
if (g > 255) g = 255; else if (g < 0) g = 0;
if (b > 255) b = 255; else if (b < 0) b = 0;
return `#${[r, g, b]
.map((n) =>
n.toString(16).length === 1 ? "0" + n.toString(16) : n.toString(16)
)
.join("")}`;
};
For this, we are going to use some RegEx:
const hex = (h) => {
return h
.replace(
/^#?([a-f\d])([a-f\d])([a-f\d])$/i,
(_, r, g, b) => "#" + r + r + g + g + b + b
)
.substring(1)
.match(/.{2}/g)
.map((x) => parseInt(x, 16));
};
Upvotes: 2
Reputation: 728
convertHexToRgb.ts:
/**
* RGB color regexp
*/
export const RGB_REG_EXP = /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/;
/**
* HEX color regexp
*/
export const HEX_REG_EXP = /^#?(([\da-f]){3}|([\da-f]){6})$/i;
/**
* Converts HEX to RGB.
*
* Color must be only HEX string and must be:
* - 7-characters starts with "#" symbol ('#ffffff')
* - or 6-characters without "#" symbol ('ffffff')
* - or 4-characters starts with "#" symbol ('#fff')
* - or 3-characters without "#" symbol ('fff')
*
* @function { color: string => string } convertHexToRgb
* @return { string } returns RGB color string or empty string
*/
export const convertHexToRgb = (color: string): string => {
const errMessage = `
Something went wrong while working with colors...
Make sure the colors provided to the "PieDonutChart" meet the following requirements:
Color must be only HEX string and must be
7-characters starts with "#" symbol ('#ffffff')
or 6-characters without "#" symbol ('ffffff')
or 4-characters starts with "#" symbol ('#fff')
or 3-characters without "#" symbol ('fff')
- - - - - - - - -
Error in: "convertHexToRgb" function
Received value: ${color}
`;
if (
!color
|| typeof color !== 'string'
|| color.length < 3
|| color.length > 7
) {
console.error(errMessage);
return '';
}
const replacer = (...args: string[]) => {
const [
_,
r,
g,
b,
] = args;
return '' + r + r + g + g + b + b;
};
const rgbHexArr = color
?.replace(HEX_REG_EXP, replacer)
.match(/.{2}/g)
?.map(x => parseInt(x, 16));
/**
* "HEX_REG_EXP.test" is here to create more strong tests
*/
if (rgbHexArr && Array.isArray(rgbHexArr) && HEX_REG_EXP.test(color)) {
return `rgb(${rgbHexArr[0]}, ${rgbHexArr[1]}, ${rgbHexArr[2]})`;
}
console.error(errMessage);
return '';
};
I'm using Jest for tests
color.spec.ts
describe('function "convertHexToRgb"', () => {
it('returns a valid RGB with the provided 3-digit HEX color: [color = \'fff\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb('fff');
expect(RGB_REG_EXP.test(rgb)).toBeTruthy();
expect(consoleErrorMocked).not.toHaveBeenCalled();
});
it('returns a valid RGB with the provided 3-digit HEX color with hash symbol: [color = \'#fff\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb('#fff');
expect(RGB_REG_EXP.test(rgb)).toBeTruthy();
expect(consoleErrorMocked).not.toHaveBeenCalled();
});
it('returns a valid RGB with the provided 6-digit HEX color: [color = \'ffffff\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb('ffffff');
expect(RGB_REG_EXP.test(rgb)).toBeTruthy();
expect(consoleErrorMocked).not.toHaveBeenCalled();
});
it('returns a valid RGB with the provided 6-digit HEX color with the hash symbol: [color = \'#ffffff\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb(TEST_COLOR);
expect(RGB_REG_EXP.test(rgb)).toBeTruthy();
expect(consoleErrorMocked).not.toHaveBeenCalled();
});
it('returns an empty string when the provided value is not a string: [color = 1234]', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
// @ts-ignore
const rgb = convertHexToRgb(1234);
expect(rgb).toBe('');
expect(consoleErrorMocked).toHaveBeenCalledTimes(1);
});
it('returns an empty string when the provided color is too short: [color = \'FF\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb('FF');
expect(rgb).toBe('');
expect(consoleErrorMocked).toHaveBeenCalledTimes(1);
});
it('returns an empty string when the provided color is too long: [color = \'#fffffff\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb('#fffffff');
expect(rgb).toBe('');
expect(consoleErrorMocked).toHaveBeenCalledTimes(1);
});
it('returns an empty string when the provided value is looks like HEX color string but has invalid symbols: [color = \'#fffffp\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb('#fffffp');
expect(rgb).toBe('');
expect(consoleErrorMocked).toHaveBeenCalledTimes(1);
});
it('returns an empty string when the provided value is invalid: [color = \'*\']', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
const rgb = convertHexToRgb('*');
expect(rgb).toBe('');
expect(consoleErrorMocked).toHaveBeenCalledTimes(1);
});
it('returns an empty string when the provided value is undefined: [color = undefined]', () => {
expect.assertions(2);
const { consoleErrorMocked } = mockConsole();
// @ts-ignore
const rgb = convertHexToRgb(undefined);
expect(rgb).toBe('');
expect(consoleErrorMocked).toHaveBeenCalledTimes(1);
});
});
tests result
:
function "convertHexToRgb"
√ returns a valid RGB with the provided 3-digit HEX color: [color = 'fff']
√ returns a valid RGB with the provided 3-digit HEX color with hash symbol: [color = '#fff']
√ returns a valid RGB with the provided 6-digit HEX color: [color = 'ffffff']
√ returns a valid RGB with the provided 6-digit HEX color with the hash symbol: [color = '#ffffff']
√ returns an empty string when the provided value is not a string: [color = 1234]
√ returns an empty string when the provided color is too short: [color = 'FF']
√ returns an empty string when the provided color is too long: [color = '#fffffff']
√ returns an empty string when the provided value is looks like HEX color string but has invalid symbols: [color = '#fffffp']
√ returns an empty string when the provided value is invalid: [color = '*']
√ returns an empty string when the provided value is undefined: [color = undefined]
And mockConsole
:
export const mockConsole = () => {
const consoleError = jest.spyOn(console, 'error').mockImplementationOnce(() => undefined);
return { consoleError };
};
Upvotes: 0
Reputation: 1056
Use tinycolor2. It's a fast library (Around 400kb) for color manipulation and conversion in JavaScript.
It accepts various color string format. Like:
tinycolor("#000"); // Hex3
tinycolor("#f0f0f6"); // Hex6
tinycolor("#f0f0f688"); // Hex8
tinycolor("f0f0f6"); // Hex withouth the number sign '#'
tinycolor("rgb (255, 0, 0)"); // RGB
tinycolor("rgba (255, 0, 0, .5)"); // RGBA
tinycolor({ r: 255, g: 0, b: 0 }); // RGB object
tinycolor("hsl(0, 100%, 50%)"); // HSL
tinycolor("hsla(0, 100%, 50%, .5)"); // HSLA
tinycolor("red"); // Named
var color = tinycolor('rgb(0, 128, 192)');
color.toHexString(); //#0080C0
var color = tinycolor('#0080C0');
color.toRgbString(); // rgb(0, 128, 192)
Visit documentation for more demo.
Upvotes: 3
Reputation: 783
I realise there are lots of answers to this but if you're like me and you know your HEX is always going to be 6 characters with or without the # prefix then this is probably the simplest method if you want to do some quick inline stuff. It does not care if it starts with or without a hash.
var hex = "#ffffff";
var rgb = [
parseInt(hex.substr(-6,2),16),
parseInt(hex.substr(-4,2),16),
parseInt(hex.substr(-2),16)
];
Upvotes: 1
Reputation: 411
To convert from HEX to RGB where RGB are float values within the range of 0 and 1:
#FFAA22 → {r: 0.5, g: 0, b:1}
I adapted @Tim Down’s answer:
function convertRange(value,oldMin,oldMax,newMin,newMax) {
return (Math.round(((((value - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin) * 10000)/10000)
}
function hexToRgbFloat(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: convertRange(parseInt(result[1],16), 0, 255, 0, 1),
g: convertRange(parseInt(result[2],16), 0, 255, 0, 1),
b: convertRange(parseInt(result[3],16), 0, 255, 0, 1)
} : null;
}
console.log(hexToRgbFloat("#FFAA22")) // {r: 1, g: 0.6667, b: 0.1333}
Upvotes: 0
Reputation: 9488
Here's my version:
function rgbToHex(red, green, blue) {
const rgb = (red << 16) | (green << 8) | (blue << 0);
return '#' + (0x1000000 + rgb).toString(16).slice(1);
}
function hexToRgb(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;
}
Upvotes: 68
Reputation: 101
A simple answer to convert RGB to hex. Here values of color channels are clamped between 0 and 255.
function RGBToHex(r = 0, g = 0, b = 0) {
// clamp and convert to hex
let hr = Math.max(0, Math.min(255, Math.round(r))).toString(16);
let hg = Math.max(0, Math.min(255, Math.round(g))).toString(16);
let hb = Math.max(0, Math.min(255, Math.round(b))).toString(16);
return "#" +
(hr.length<2?"0":"") + hr +
(hg.length<2?"0":"") + hg +
(hb.length<2?"0":"") + hb;
}
Upvotes: 2
Reputation: 188
Hex to RGB
const hex2rgb = (hex) => {
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 {r, g, b} // return an object
return [ r, g, b ]
}
console.log(hex2rgb("#0080C0"))
RGB to Hex
const rgb2hex = (r, g, b) => {
var rgb = (r << 16) | (g << 8) | b
// return '#' + rgb.toString(16) // #80c0
// return '#' + (0x1000000 + rgb).toString(16).slice(1) // #0080c0
// or use [padStart](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart)
return '#' + rgb.toString(16).padStart(6, 0)
}
console.log(rgb2hex(0, 128, 192))
Also if someone need online tool, I have built Hex to RGB and vice versa.
Upvotes: 12
Reputation: 2491
Built my own hex to RGB converter. I hope this can help someone out.
Ive used react to sandbox it.
Usage:
Install React from the official documentation or alternatively if you have npx
installed globally, run npx create-react-app hex-to-rgb
import React, { Component, Fragment } from 'react';
const styles = {
display: 'block',
margin: '20px auto',
input: {
width: 170,
},
button: {
margin: '0 auto'
}
}
// test case 1
// #f0f
// test case 2
// #ff00ff
class HexToRGBColorConverter extends Component {
state = {
result: false,
color: "#ff00ff",
}
hexToRgb = color => {
let container = [[], [], []];
// check for shorthand hax string
if (color.length >= 3) {
// remove hash from string
// convert string to array
color = color.substring(1).split("");
for (let key = 0; key < color.length; key++) {
let value = color[key];
container[2].push(value);
// if the length is 3 we
// we need to add the value
// to the index we just updated
if (color.length === 3) container[2][key] += value;
}
for (let index = 0; index < color.length; index++) {
let isEven = index % 2 === 0;
// If index is odd an number
// push the value into the first
// index in our container
if (isEven) container[0].push(color[index]);
// If index is even an number
if (!isEven) {
// again, push the value into the
// first index in the container
container[0] += color[index];
// Push the containers first index
// into the second index of the container
container[1].push(container[0]);
// Flush the first index of
// of the container
// before starting a new set
container[0] = [];
}
}
// Check container length
if (container.length === 3) {
// Remove only one element of the array
// Starting at the array's first index
container.splice(0, 1);
let values = container[color.length % 2];
return {
r: parseInt(values[0], 16),
g: parseInt(values[1], 16),
b: parseInt(values[2], 16)
}
}
}
return false;
}
handleOnClick = event => {
event.preventDefault();
const { color } = this.state;
const state = Object.assign({}, this.state);
state.result = this.hexToRgb(color);
this.setState(state);
}
handleOnChange = event => {
event.preventDefault();
const { value } = event.currentTarget;
const pattern = /^([a-zA-Z0-9])/;
const boundaries = [3, 6];
if (
pattern.test(value) &&
boundaries.includes(value.length)
) {
const state = Object.assign({}, this.state);
state.color = `#${value}`;
this.setState(state);
}
}
render() {
const { color, result } = this.state;
console.log('this.state ', color, result);
return (
<Fragment>
<input
type="text"
onChange={this.handleOnChange}
style={{ ...styles, ...styles.input }} />
<button
onClick={this.handleOnClick}
style={{ ...styles, ...styles.button }}>
Convert hex to rgba
</button>
{
!!result &&
<div style={{ textAlign: 'center' }}>
Converted { color } to { JSON.stringify(result) }
</div>
}
</Fragment>
)
}
}
export default App;
Happy Coding =)
Upvotes: -2
Reputation: 109
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(~~red, 255));
green = Math.max(0, Math.min(~~green, 255));
blue = Math.max(0, Math.min(~~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.
Upvotes: 0
Reputation: 63
HTML converer :)
<!DOCTYPE html>
<html>
<body>
<p id="res"></p>
<script>
function hexToRgb(hex) {
var res = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return "(" + parseInt(res[1], 16) + "," + parseInt(res[2], 16) + "," + parseInt(res[3], 16) + ")";
};
document.getElementById("res").innerHTML = hexToRgb('#0080C0');
</script>
</body>
</html>
Upvotes: 0
Reputation: 8683
You can simply use rgb-hex & hex-rgb as it is battle-tested & has multiple options that are not available in other solutions.
I was recently building a Color Picker & these 2 packages came in handy.
import rgbHex from 'rgb-hex';
rgbHex(65, 131, 196);
//=> '4183c4'
rgbHex('rgb(40, 42, 54)');
//=> '282a36'
rgbHex(65, 131, 196, 0.2);
//=> '4183c433'
rgbHex(40, 42, 54, '75%');
//=> '282a36bf'
rgbHex('rgba(40, 42, 54, 75%)');
//=> '282a36bf'
import hexRgb from 'hex-rgb';
hexRgb('4183c4');
//=> {red: 65, green: 131, blue: 196, alpha: 1}
hexRgb('#4183c4');
//=> {red: 65, green: 131, blue: 196, alpha: 1}
hexRgb('#fff');
//=> {red: 255, green: 255, blue: 255, alpha: 1}
hexRgb('#22222299');
//=> {red: 34, green: 34, blue: 34, alpha: 0.6}
hexRgb('#0006');
//=> {red: 0, green: 0, blue: 0, alpha: 0.4}
hexRgb('#cd2222cc');
//=> {red: 205, green: 34, blue: 34, alpha: 0.8}
hexRgb('#cd2222cc', {format: 'array'});
//=> [205, 34, 34, 0.8]
hexRgb('#cd2222cc', {format: 'css'});
//=> 'rgb(205 34 34 / 80%)'
hexRgb('#000', {format: 'css'});
//=> 'rgb(0 0 0)'
hexRgb('#22222299', {alpha: 1});
//=> {red: 34, green: 34, blue: 34, alpha: 1}
hexRgb('#fff', {alpha: 0.5});
//=> {red: 255, green: 255, blue: 255, alpha: 0.5}
Upvotes: 5
Reputation: 51746
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();
input {
width: 200px;
margin: 0.5rem;
}
<input value="cyan" />
<input readonly="readonly" />
Upvotes: 2
Reputation: 2469
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)
Upvotes: 27
Reputation: 112
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);
Upvotes: -1
Reputation: 909
(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.
Upvotes: 17
Reputation: 82267
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)';
var rgb2hex = str => "#"+str.split(',').map(s => (s.replace(/\D/g,'')|0).toString(16)).map(s => s.length < 2 ? "0"+s : s).join('');
console.log(rgb2hex(yellow));
Upvotes: -1
Reputation: 4915
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
Upvotes: 0
Reputation: 3847
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() {
this.validateRgb = function(color) {
return typeof color === 'object' &&
color.length === 3 &&
Math.min.apply(null, color) >= 0 &&
Math.max.apply(null, color) <= 255;
};
this.validateHex = function(color) {
return color.match(/^\#?(([0-9a-f]{3}){1,2})$/i);
};
this.hexToRgb = function(color) {
var hex = color.replace(/^\#/, '');
var length = hex.length;
return [
parseInt(length === 6 ? hex['0'] + hex['1'] : hex['0'] + hex['0'], 16),
parseInt(length === 6 ? hex['2'] + hex['3'] : hex['1'] + hex['1'], 16),
parseInt(length === 6 ? hex['4'] + hex['5'] : hex['2'] + hex['2'], 16)
];
};
this.rgbToHex = function(color) {
return '#' +
('0' + parseInt(color['0'], 10).toString(16)).slice(-2) +
('0' + parseInt(color['1'], 10).toString(16)).slice(-2) +
('0' + parseInt(color['2'], 10).toString(16)).slice(-2);
};
};
var colors = new colorClass();
console.log(colors.hexToRgb('#FFFFFF'));// [255, 255, 255]
console.log(colors.rgbToHex([255, 255, 255]));// #FFFFFF
Upvotes: -1
Reputation: 333
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
Upvotes: 0
Reputation: 5889
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
Upvotes: 17
Reputation: 216
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
}
Upvotes: 1