Logo

Programming-Idioms

  • Python
  • Java

Idiom #154 Halfway between two hex color codes

Find color c, the average between colors c1, c2.

c, c1, c2 are strings of hex color codes: 7 chars, beginning with a number sign # .
Assume linear computations, ignore gamma corrections.

import static java.awt.Color.decode;
import java.awt.Color;
Color x = decode(c1), y = decode(c2);
int r = (x.getRed()   + y.getRed())   / 2,
    g = (x.getGreen() + y.getGreen()) / 2,
    b = (x.getBlue()  + y.getBlue())  / 2,
    z = (r << 16) + (g << 8) + b;
String c = "#%06x".formatted(z);
StringBuilder sb = new StringBuilder("#");
for(int i=0;i<3;i++) {
  String sub1 = c1.substring(1+2*i,3+2*i);
  String sub2 = c2.substring(1+2*i,3+2*i);
  int v1 = Integer.parseInt(sub1, 16);
  int v2 = Integer.parseInt(sub2, 16);
  int v = (v1 + v2)/2;
  String sub = String.format("%02X", v);
  sb.append(sub);
}
String c = sb.toString();

Loops over each component r, g, b.
String r1 = c1.substring(1,3);
String g1 = c1.substring(3,5);
String b1 = c1.substring(5,7);

String r2 = c2.substring(1,3);
String g2 = c2.substring(3,5);
String b2 = c2.substring(5,7);

String r = String.format("%02X", (Integer.parseInt(r1, 16)+Integer.parseInt(r2, 16))/2 );
String g = String.format("%02X", (Integer.parseInt(g1, 16)+Integer.parseInt(g2, 16))/2 );
String b = String.format("%02X", (Integer.parseInt(b1, 16)+Integer.parseInt(b2, 16))/2 );

String c = "#" + r + g + b;
r1, g1, b1 = [int(c1[p:p+2], 16) for p in range(1,6,2)]
r2, g2, b2 = [int(c2[p:p+2], 16) for p in range(1,6,2)]
c = '#{:02x}{:02x}{:02x}'.format((r1+r2) // 2, (g1+g2) //2, (b1+b2)// 2)
a = bytes.fromhex(c1[1:])
b = bytes.fromhex(c2[1:])
r, g, b = (sum(x) // 2 for x in zip(a, b))
c = (r << 16) + (g << 8) + b
c = f'{c:06x}'
import numpy
class RGB(numpy.ndarray):
  @classmethod
  def from_str(cls, rgbstr):
    return numpy.array([
      int(rgbstr[i:i+2], 16)
      for i in range(1, len(rgbstr), 2)
    ]).view(cls)
 
  def __str__(self):
    self = self.astype(numpy.uint8)
    return '#' + ''.join(format(n, 'x') for n in self)
 
c1 = RGB.from_str('#a1b1c1')
print(c1)
c2 = RGB.from_str('#1A1B1C')
print(c2)

print((c1 + c2) / 2)

numpy is standard for array numerics, and works nicely for this problem. We can represent a RGB value as a special numpy array.
using System.Drawing;
Color color1 = ColorTranslator.FromHtml(c1);
Color color2 = ColorTranslator.FromHtml(c2);
c = string.Format($"#{((color1.R + color2.R) / 2):X2}{((color1.G + color2.G) / 2):X2}{((color1.B + color2.B) / 2):X2}");

New implementation...
< >
programming-idioms.org