How can I get the color halfway between two colors?

HtmlCss

Html Problem Overview


I have two colors:

#15293E
#012549

How can I find the color that is half way in between them? Is there some way to do this calculation?

Html Solutions


Solution 1 - Html

As Mr Lister just said, it is easy to automate the calculation with any programming language :

  1. Separate your two colors into their 3 color numbers for Red, Green, Blue : (r1,g1,b1) and (r2,g2,b2).
  • For example #15293E, #012549 become ("15", "29", "3E"), ("01", "25", "49")

  1. Convert each color string into an integer, specifying explicitly that you are parsing a hexadecimal-based representation of a number.
  • For example ("15", "29", "3E") becomes (21, 41, 62)

  1. Calculate the average (r',g',b') = ( (r1+r2)/2, (g1+g2)/2, (b1+b2)/2 ).
  • For example ( (21+1)/2, (41+37)/2, (62+73)/2) = (11, 39, 67)

  1. Convert them again to strings , specifying explicitly that you are generating two-digit hexadecimal representations (pad with a zero when necessary).
  • For example (11, 39, 67) -> ("0B", "27", "43")

  1. Concatenate a hash character followed by the 3 strings
  • For example ("0B", "27", "43") -> "#0B2743"

Edit : Implementation is not "very easy" as I initially stated. I took the time to write the code in several languages on Programming-Idioms .

Solution 2 - Html

I use this website to do this task for me: ColorBlender.

The mid-color will be #0B2744.

Solution 3 - Html

With LESS

If you use the latest LESS CSS preprocessor then you'll notice there is a function (mix()) that does this:

mix(#15293E, #012549, 50%)

Outputs: #0b2744.

Solution 4 - Html

If you need to do this generically, and expect the middle colour to be visually accurate in more cases (i.e. the visual colour and tone of the mid point should "look right" to a human viewer), then as suggested above you may want to convert from RGB to HSV or HSL before calculating the mid point, and then convert back afterwards. This may differ significantly from averaging RGB values directly.

Here is some JavaScript code for the conversion to/from HSL that I found on a brief search, and that on a brief check appears to do the right thing:

github.com/mjackson/mjijackson.github.com/blob/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.txt

https://web.archive.org/web/20170919064926/https://github.com/mjackson/mjijackson.github.com/blob/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.txt

Just apply the rgbToHsl function to your two r,g,b colour vectors, average the two resulting vectors, and apply hslToRgb to that . . .

Solution 5 - Html

Handy-Dandy Function

function padToTwo(numberString) {
    if (numberString.length < 2) {
        numberString = '0' + numberString;
    }
    return numberString;
}

function hexAverage() {
    var args = Array.prototype.slice.call(arguments);
    return args.reduce(function (previousValue, currentValue) {
        return currentValue
            .replace(/^#/, '')
            .match(/.{2}/g)
            .map(function (value, index) {
                return previousValue[index] + parseInt(value, 16);
            });
    }, [0, 0, 0])
    .reduce(function (previousValue, currentValue) {
        return previousValue + padToTwo(Math.floor(currentValue / args.length).toString(16));
    }, '#');
}

console.log(hexAverage('#111111', '#333333')); // => #222222
console.log(hexAverage('#111111', '#222222')); // => #191919
console.log(hexAverage('#111111', '#222222', '#333333')); // => #222222
console.log(hexAverage('#000483', '#004B39')); // => #00275e

Solution 6 - Html

Like this:

function colourGradientor(p, rgb_beginning, rgb_end){

    var w = p * 2 - 1;
    

    var w1 = (w + 1) / 2.0;
    var w2 = 1 - w1;

    var rgb = [parseInt(rgb_beginning[0] * w1 + rgb_end[0] * w2),
        parseInt(rgb_beginning[1] * w1 + rgb_end[1] * w2),
            parseInt(rgb_beginning[2] * w1 + rgb_end[2] * w2)];
    return rgb;
};

where p is a value between 0 and 1 specifying how far through the gradient the colour should be and rgb_beginning is the from colour and rgb_end is the to colour. Both are [r,g,b] arrays so you'll have to convert from hex first. This is a simplified version of LESS's mix function which I think is from SASS. For the poster p would be 0.5

Solution 7 - Html

i just wrote a function that calculates colors between two colors so here it is in case somebody needs it, i think it's quite short and readable, it accepts two colors in hex strings, and the number of colors to calculate in between, returns the colors in an array of hex strings

i took the rgbToHex and hexToRgb functions from here

Hope this helps!

function rgbToHex(r, g, b) {
  return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

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;
}

// returns an array of startColor, colors between according to steps, and endColor
function getRamp(startColor, endColor, steps) {
  var ramp = [];

  ramp.push(startColor);

  var startColorRgb = hexToRgb(startColor);
  var endColorRgb = hexToRgb(endColor);

  var rInc = Math.round((endColorRgb.r - startColorRgb.r) / (steps+1));
  var gInc = Math.round((endColorRgb.g - startColorRgb.g) / (steps+1));
  var bInc = Math.round((endColorRgb.b - startColorRgb.b) / (steps+1));

  for (var i = 0; i < steps; i++) {
    startColorRgb.r += rInc;
    startColorRgb.g += gInc;
    startColorRgb.b += bInc;

    ramp.push(rgbToHex(startColorRgb.r, startColorRgb.g, startColorRgb.b));
  }
  ramp.push(endColor);

  return ramp;
}

Solution 8 - Html

I found an npm module that does this: https://www.npmjs.com/package/color-between

Here's some example usage:

const colorBetween = require('color-between');
 
// rgb format
colorBetween('rgb(255, 255, 255)', 'rgb(0, 0, 0)', 0.5, 'rgb');
// output: 'rgb(128, 128, 128)'
 
// rgba format
colorBetween('rgba(255, 255, 255, .2)', 'rgba(0, 0, 0, .8)', 0.5, 'rgb');
// output: 'rgba(128, 128, 128, 0.5)
 
// hex format
colorBetween('#fff', '#000', 0.5, 'hex');
// output: '#808080'
 
// mixed format
colorBetween('#fff', 'rgb(0, 0, 0)', 0.5, 'hsl');
output: 'hsl(0, 0%, 50%)'

Solution 9 - Html

If you so wished you could do it yourself with windows calculator.

  1. Open Windows Calculator > View > Programmer
  2. Choose the Hex option
  3. Enter the Hex value
  4. Switch to Dec and write down the value given
  5. Repeat for steps 2-4 for the second hex value
  6. Calculate the average by adding the two Dec numbers and dividing by 2
  7. Enter this value into calculator with the Dec option selected then switch to the hex option and voila

Example:

  • 15293E (HEX) = 1386814 (DEC)
  • 012549 (HEX) = 75081 (DEC)
  • Mid Point = (1386814+75081)/2
  • Mid Point = 730947 (DEC)
  • 730947 (DEC) = 0B2743 (HEX)
  • #0B2743

or use ColorBlender as mentioned above ;)

Solution 10 - Html

Here I leave the code that I use in my typescript app

function mixHexColors(color1: string, color2: string) {
    const valuesColor1 = color1.replace('#', '').match(/.{2}/g).map((value) =>
        parseInt(value, 16)
    )
    const valuesColor2 = color2.replace('#', '').match(/.{2}/g).map((value) =>
        parseInt(value, 16)
    )
    const mixedValues = valuesColor1.map((value, index) =>
        ((value + valuesColor2[index]) / 2).toString(16).padStart(2, '')
    )
    return `#${mixedValues.join('')}`
}

Solution 11 - Html

Here's a Python version.

# -*- coding: utf-8 -*-
"""jcolor_split.py splits 2 hex color values, HEX_COLOR_1 and HEX_COLOR_2, 
    printing the color halfway between the two colors
Usage:     jcolor_split.py HEX_COLOR_1 HEX_COLOR_2
Example: ./jcolor_split.py 3E599C      2E4892
"""
import sys

def jcolor_split(hex_color_1, hex_color_2):

    print()
    print (hex_color_1)
    r1s = hex_color_1[0:2]
    g1s = hex_color_1[2:4]
    b1s = hex_color_1[4:6]
    print(r1s,g1s,b1s)

    print()
    print (hex_color_2)
    r2s = hex_color_2[0:2]
    g2s = hex_color_2[2:4]
    b2s = hex_color_2[4:6]
    print(r2s,g2s,b2s)

    # convert rgb's to ints
    r1 = int(r1s, 16); g1 = int(g1s, 16); b1 = int(b1s, 16);
    r2 = int(r2s, 16); g2 = int(g2s, 16); b2 = int(b2s, 16);
    print()
    print(r1,g1,b1)
    print(r2,g2,b2)
   
    # get the average
    ra = int(round(float(r1+r2)/2))
    ga = int(round(float(g1+g2)/2))
    ba = int(round(float(b1+b2)/2))

    print()
    print(format(ra, 'x')+ format(ga, 'x')+ format(ba, 'x') )

    
 
NUM_ARGS = 2
def main():
    args = sys.argv[1:]
    if len(args) != NUM_ARGS or "-h" in args or "--help" in args:
        print (__doc__)
        sys.exit(2)
    jcolor_split(args[0], args[1])
 
if __name__ == '__main__':
    main()


sample_run = '''
PS C:\1d\JoeCodeswellHomePage> ./jcolor_split.py 3E599C      2E4892

3E599C
3E 59 9C

2E4892
2E 48 92

62 89 156
46 72 146

365097
PS C:\1d\JoeCodeswellHomePage> 
'''

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1943020View Question on Stackoverflow
Solution 1 - HtmlDeleplaceView Answer on Stackoverflow
Solution 2 - Htmlhjpotter92View Answer on Stackoverflow
Solution 3 - HtmlScottSView Answer on Stackoverflow
Solution 4 - HtmlNeil SlaterView Answer on Stackoverflow
Solution 5 - HtmlJacksonView Answer on Stackoverflow
Solution 6 - HtmlRestedView Answer on Stackoverflow
Solution 7 - HtmlDan LevinView Answer on Stackoverflow
Solution 8 - HtmlEric JohnsonView Answer on Stackoverflow
Solution 9 - HtmlDave HaighView Answer on Stackoverflow
Solution 10 - HtmlLucas VazquezView Answer on Stackoverflow
Solution 11 - HtmlLove and peace - Joe CodeswellView Answer on Stackoverflow