Implementation
Java

Be concise.

Be useful.

All contributions dictatorially edited by webmasters to match personal tastes.

Please do not paste any copyright violating resource.

Please try to avoid dependencies to third-party libraries and frameworks.

Other implementations
import "fmt"
import "strconv"
r1, _ := strconv.ParseInt(c1[1:3], 16, 0)
r2, _ := strconv.ParseInt(c2[1:3], 16, 0)
r := (r1 + r2) / 2

g1, _ := strconv.ParseInt(c1[3:5], 16, 0)
g2, _ := strconv.ParseInt(c2[3:5], 16, 0)
g := (g1 + g2) / 2

b1, _ := strconv.ParseInt(c1[5:7], 16, 0)
b2, _ := strconv.ParseInt(c2[5:7], 16, 0)
b := (b1 + b2) / 2

c := fmt.Sprintf("#%02X%02X%02X", r, g, b)
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();
import "fmt"
import "strconv"
var buf [7]byte
buf[0] = '#'
for i := 0; i < 3; i++ {
	sub1 := c1[1+2*i : 3+2*i]
	sub2 := c2[1+2*i : 3+2*i]
	v1, _ := strconv.ParseInt(sub1, 16, 0)
	v2, _ := strconv.ParseInt(sub2, 16, 0)
	v := (v1 + v2) / 2
	sub := fmt.Sprintf("%02X", v)
	copy(buf[1+2*i:3+2*i], sub)
}
c := string(buf[:])
SysUtils, Graphics
var
  c1, c2: string;
  RGB1, RGB2: LongInt;
  R1, G1, B1, R2, G2, B2: Byte;
  c: TColor;
begin
  RGB1 := ColorToRGB(StrToInt(StringReplace(c1,'#','$',[])));
  RGB1 := ColorToRGB(StrToInt(StringReplace(c2,'#','$',[])));
  RedGreenBlue(RGB1, R1, G1, B1);
  RedGreenBlue(RGB2, R2, G2, B2);
  c := RGBToColor(R1+R2 div 2, G1+G2 div 2, B1+B2 div 2);
end.
rgbs = c1[1..-1].scan(/../), c2[1..-1].scan(/../)
c = "#%02X%02X%02X" % rgbs.transpose.map{|h1, h2| (h1.hex + h2.hex)/2 }
var c = "#";
for(var i = 0; i<3; i++) {
  var sub1 = c1.substring(1+2*i, 3+2*i);
  var sub2 = c2.substring(1+2*i, 3+2*i);
  var v1 = parseInt(sub1, 16);
  var v2 = parseInt(sub2, 16);
  var v = Math.floor((v1 + v2) / 2);
  var sub = v.toString(16).toUpperCase();
  var padsub = ('0'+sub).slice(-2);
  c += padsub;
}
import std.algorithm, std.range; 
import std.conv, std.array, std.format;
string c = roundRobin(c1.dropOne.chunks(2), c2.dropOne.chunks(2))
    .map!(a => a.to!int(16)).array
    .chunks(2)
    .map!(a => ((a[0] + a[1]) / 2))
    .fold!((a,b) => a ~= "%.2X".format(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)
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)
use std::str::FromStr;
use std::fmt;
"Too long for text box, see online demo"