How to Convert an Array of RGB Values to a Hexadecimal Value in JavaScript?

You can convert an RGB value to a hexadecimal value using JavaScript, in the following ways:

Using Array.prototype.reduce()

Given an array of RGB values (split into red, green and blue channels respectively), you can do the following:

  1. Loop over the rgb values (using Array.prototype.reduce());
  2. Convert each value to its hexadecimal equivalent (using Number.prototype.toString() with 16 as radix);
  3. Append converted value to an "accumulator" string that's passed to Array.prototype.reduce() callback (as the first argument). This "accumulator" string contains the result (of the RGB to hexadecimal conversion) from one previous iteration, and at start, it is initialized to an empty string;
  4. Return the single, reduced hexadecimal value.

For example:

// ES6+
const rgbToHex = (rgb) => (
    rgb.reduce((accum, colorVal) => {
        accum += colorVal.toString(16);
        return accum;
    }, '')
);

console.log(rgbToHex([66, 135, 245])); // '4287f5'

The second argument to the Array.prototype.reduce() method is the initial value for the accumulator, which in this case is an empty string.

You can rewrite the callback to Array.prototype.reduce() without arrow function to make it compatible with ES5.

Using for Loop

Given an array of RGB values (split into red, green and blue channels respectively), you can do the following:

  1. Loop over the rgb values;
  2. Convert each value to its hexadecimal equivalent (using Number.prototype.toString() with 16 as radix);
  3. Append resulting values to a string;
  4. Return the hexadecimal value.

This can be implemented, for example, in the following way:

function rgbToHex(rgb) {
    let hex = '';

    for (let i = 0; i < rgb.length; i++) {
        hex += rgb[i].toString(16);
    }

    return hex;
}

console.log(rgbToHex([66, 135, 245])); // '4287f5'

Using Bitwise Left Shift Operator (<<)

Given an array of RGB values (split into red, green and blue channels respectively), you can do the following to shift binary bits of the RGB color and then convert the result to a hexadecimal value:

  1. Add the left-shifted values of the following together:
    1. The value 1 shifted 24 bits to the left. This is to guarantee 8 bit representation for each color channel in RGB, so that padding is added to values such as 0 (which takes up 1 bit of space), or 10 (which takes up 4 bits of space) ensuring that they occupy exactly 8 bits;
    2. The red channel value shifted 16 bits to the left (so that it occupies the first 8 bits);
    3. The green channel value shifted 8 bits to the left (so that it occupies the 8 bits right after the red color);
    4. The blue channel value appended to the end (so that it occupies the last 8 bits — i.e. right after the green color).
  2. Convert the resulting binary number to its hexadecimal equivalent (using Number.prototype.toString() with 16 as radix);
  3. Remove the leading 1 that was added for padding (for example, by using String.prototype.slice());
  4. Return the hexadecimal value.
function rgbToHex(rgb) {
    const padding = (1 << 24); // 16777216

    const binRed = rgb[0] << 16; // e.g. 66 << 16 = 4325376
    const binGreen = rgb[1] << 8; // e.g. 135 << 8 = 34560
    const binBlue = rgb[2]; // e.g. 245

    const sum = padding + binRed + binGreen + binBlue; // e.g. 21137397

    return sum.toString(16).slice(1);
}

console.log(rgbToHex([66, 135, 245])); // '4287f5'

Given the RGB array "[66, 135, 245]", this would work in the following way:

const padding = 16777216; // 1 << 24 = 0b1000000000000000000000000
const binRed = 4325376; // 66 << 16 = 0b10000100000000000000000
const binGreen = 34560; // 135 << 8 = 0b1000011100000000
const binBlue = 245; // 0b11110101

const sum = (padding + binRed + binGreen + binBlue); // 21137397 (or 0b1010000101000011111110101)

console.log(sum.toString(16).slice(1)); // '4287f5'
console.log((0b1010000101000011111110101).toString(16).slice(1)); // '4287f5'

In the example above, you can see the values at each step (and their binary equivalents as the bits are shifted to the left). This also shows the need to add a padding, as values such as 135 for example, do not occupy entire 8-bits of space.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.