16

I tried to convert rgba to hex color code, but unable to covert opacity value remaining color I able to convert,

Below is my code

var colorcode = "rgba(0, 0, 0, 0.74)";

var finalCode = rgba2hex(colorcode)

function rgba2hex(orig) {
    var a, isPercent,
    rgb = orig.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+),?([^,\s)]+)?/i),
    alpha = (rgb && rgb[4] || "").trim(),
    hex = rgb ?
    (rgb[1] | 1 << 8).toString(16).slice(1) +
    (rgb[2] | 1 << 8).toString(16).slice(1) +
    (rgb[3] | 1 << 8).toString(16).slice(1) : orig;
  
    if (alpha !== "") { a = alpha; }
    else { a = 01; }
    hex = hex + a;
  
    return hex;
}

console.log(finalCode)

Here I need alpha value also convert to hex code.

Please suggest how to convert

Output

Expect:000000bd

Pankaj Bisht
  • 986
  • 1
  • 8
  • 27
dhana
  • 857
  • 3
  • 11
  • 26
  • The color2color library on github might be what you are looking for: https://github.com/metaloha/color2color –  Apr 23 '18 at 05:56
  • See https://stackoverflow.com/a/19366389/6782 which will give you an RGBA array that's trivially converted to hexadecimal if required. – Alnitak Apr 23 '18 at 05:56

8 Answers8

32

Since the alpha channel in your rgba() notation is expressed as a 0 ~ 1 value, you need to multiply it by 255 before trying to convert it to its HEX form:

var colorcode = "rgba(0, 0, 0, 0.74)";

var finalCode = rgba2hex(colorcode)

function rgba2hex(orig) {
  var a, isPercent,
    rgb = orig.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+),?([^,\s)]+)?/i),
    alpha = (rgb && rgb[4] || "").trim(),
    hex = rgb ?
    (rgb[1] | 1 << 8).toString(16).slice(1) +
    (rgb[2] | 1 << 8).toString(16).slice(1) +
    (rgb[3] | 1 << 8).toString(16).slice(1) : orig;

  if (alpha !== "") {
    a = alpha;
  } else {
    a = 01;
  }
  // multiply before convert to HEX
  a = ((a * 255) | 1 << 8).toString(16).slice(1)
  hex = hex + a;

  return hex;
}

function test(colorcode) {
  console.log(colorcode, rgba2hex(colorcode));
}

test("rgba(0, 0, 0, 0.74)");
test("rgba(0, 0, 0, 1)");
test("rgba(0, 0, 0, 0)");
test("rgba(0, 255, 0, 0.5)");

But note that this is just one of the rgba notation, and that it will e.g fail with percent based notation.
Note also that all browsers do not support RGBA HEX notation, so you might prefer an other method to convert your values depending on what you want to do with it.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
5

My solution. Hope be useful.

const rgbaToHex = (color: string): string => {
  if (/^rgb/.test(color)) {
    const rgba = color.replace(/^rgba?\(|\s+|\)$/g, '').split(',');

    // rgb to hex
    // eslint-disable-next-line no-bitwise
    let hex = `#${((1 << 24) + (parseInt(rgba[0], 10) << 16) + (parseInt(rgba[1], 10) << 8) + parseInt(rgba[2], 10))
      .toString(16)
      .slice(1)}`;

    // added alpha param if exists
    if (rgba[4]) {
      const alpha = Math.round(0o1 * 255);
      const hexAlpha = (alpha + 0x10000).toString(16).substr(-2).toUpperCase();
      hex += hexAlpha;
    }

    return hex;
  }
  return color;
};
  • 1
    Welcome to Stack Overflow. Code without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please edit your question and explain how it answers the specific question being asked. See [How to Answer](https://stackoverflow.com/help/how-to-answer). – Sfili_81 Jul 01 '21 at 14:01
5

Try this:

  • ✓ Works with alpha rgba(255, 255, 255, 0) => #ffffff00
  • ✓ Works with single digits rgba(0, 0, 0, 0) => #00000000
  • ✓ Works with RGB as well rgb(124, 255, 3) => #7cff03
  • ✓ You can slice alpha channel away rgba(255, 255, 255, 0) => #ffffff

function RGBAToHexA(rgba, forceRemoveAlpha = false) {
  return "#" + rgba.replace(/^rgba?\(|\s+|\)$/g, '') // Get's rgba / rgb string values
    .split(',') // splits them at ","
    .filter((string, index) => !forceRemoveAlpha || index !== 3)
    .map(string => parseFloat(string)) // Converts them to numbers
    .map((number, index) => index === 3 ? Math.round(number * 255) : number) // Converts alpha to 255 number
    .map(number => number.toString(16)) // Converts numbers to hex
    .map(string => string.length === 1 ? "0" + string : string) // Adds 0 when length of one number is 1
    .join("") // Puts the array to togehter to a string
}

//
// Only tests below! Click "Run code snippet" to see results
//

// RGBA with Alpha value
expect(RGBAToHexA("rgba(255, 255, 255, 0)"), "#ffffff00")
expect(RGBAToHexA("rgba(0, 0, 0, 0)"), "#00000000")
expect(RGBAToHexA("rgba(124, 255, 3, 0.5)"), "#7cff0380")
expect(RGBAToHexA("rgba(124, 255, 3, 1)"), "#7cff03ff")

// RGB value 
expect(RGBAToHexA("rgba(255, 255, 255)"), "#ffffff")
expect(RGBAToHexA("rgba(0, 0, 0)"), "#000000")
expect(RGBAToHexA("rgba(124, 255, 3)"), "#7cff03")

// RGBA without Alpha value
expect(RGBAToHexA("rgba(255, 255, 255, 0)", true), "#ffffff")
expect(RGBAToHexA("rgba(0, 0, 0, 0)", true), "#000000")
expect(RGBAToHexA("rgba(124, 255, 3, 0.5)", true), "#7cff03")
expect(RGBAToHexA("rgba(124, 255, 3, 1)", true), "#7cff03")

function expect(result, expectation) {
  console.log(result === expectation ? "✓" : "X", result, expectation)
}

Code is built based on:

Lars Flieger
  • 2,421
  • 1
  • 12
  • 34
3

Great @kaiido, i tried this way

function rgba2hex(orig) {
      var a, isPercent,
        rgb = orig.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+),?([^,\s)]+)?/i),
        alpha = (rgb && rgb[4] || "").trim(),
        hex = rgb ? 
        (rgb[1] | 1 << 8).toString(16).slice(1) +
        (rgb[2] | 1 << 8).toString(16).slice(1) +
        (rgb[3] | 1 << 8).toString(16).slice(1) : orig;
          if (alpha !== "") {
            a = alpha;
          } else {
            a = 01;
          }

          a = Math.round(a * 100) / 100;
            var alpha = Math.round(a * 255);
            var hexAlpha = (alpha + 0x10000).toString(16).substr(-2).toUpperCase();
            hex = hex + hexAlpha;

      return hex;
}
dhana
  • 857
  • 3
  • 11
  • 26
2

If you have the rgba color as a string, you can do something like this.

const color = 'rgba(249,6,6,1,0)';
const rgba = color.replace(/^rgba?\(|\s+|\)$/g, '').split(',');

const hex = `#${((1 << 24) + (parseInt(rgba[0]) << 16) + (parseInt(rgba[1]) << 8) + parseInt(rgba[2])).toString(16).slice(1)}`;
console.log(hex); // #f90606
Harry12345
  • 1,144
  • 6
  • 20
  • 47
2

Just create a function to be more effective! Code is same as above.

    var color;

    function HexCode(color){
        const rgba = color.replace(/^rgba?\(|\s+|\)$/g, '').split(',');
        const hex = `#${((1 << 24) + (parseInt(rgba[0]) << 16) + (parseInt(rgba[1]) << 8) + parseInt(rgba[2])).toString(16).slice(1)}`;
        
        return hex;
    }

    console.log(HexCode('rgba(0,255,255,0.1)'))
Nicholas
  • 2,800
  • 1
  • 14
  • 21
2

Here is a simplified option.

function rgbToHex(rgb) {
  return '#' + rgb.match(/[0-9|.]+/g).map((x,i) => i === 3 ? parseInt(255 * parseFloat(x)).toString(16) : parseInt(x).toString(16)).join('')
}

Works for rgb and rgba.

H K
  • 1,062
  • 8
  • 10
  • 2
    This is almost there, but it doesn't pad single digits with `0` Its a simple matter of check string length is one and prepending with 0 in that case. – Pure Function Dec 01 '21 at 01:51
0

  function rgbaToHex(r, g, b, a) {
  const red = r.toString(16).padStart(2, '0');
  const green = g.toString(16).padStart(2, '0');
  const blue = b.toString(16).padStart(2, '0');
  const alpha = Math.round(a * 255).toString(16).padStart(2, '0');
  return `#${red}${green}${blue}${alpha}`;
}

console.log(rgbaToHex(2,2,2,0.6));
console.log(rgbaToHex(2,2,2,0.50));
Sotos
  • 416
  • 4
  • 4