Skip to content

Instantly share code, notes, and snippets.

@oantolin
Last active May 11, 2020
Embed
What would you like to do?
Find most luminous contrasting color
#include <math.h>
#include <stdio.h>
double f(int c) {
double x = c / 255.0;
return x<=0.03928 ? x/12.92 : pow((x + 0.055)/1.055, 2.4);
}
double rellum(int r, int g, int b) {
return 0.2126*f(r) + 0.7152*f(g) + 0.0722*f(b);
}
double contrast(int c[3], int r, int g, int b) {
double l1 = rellum(c[0],c[1],c[2]), l2 = rellum(r,g,b);
double ct = (l1+0.05)/(l2+0.05);
return ct>1 ? ct : 1/ct;
}
int colors[6][3] = {{106, 228, 185},
{ 0, 186, 244},
{114, 164, 255},
{247, 143, 231},
{ 88, 221, 19},
{229, 240, 64}};
int main(int argc, char **argv) {
int r0=0, g0=0, b0=0;
double lum = 0.0;
for (int r=0; r<=255; r++)
for (int g=0; g<=255; g++)
for (int b=0; b<=255; b++) {
int good = 1;
for (int i=0; i<6; i++)
if (contrast(colors[i], r,g,b)<7.0) {
good = 0;
break;
}
if (good) {
double l = rellum(r,g,b);
if (l > lum) {
lum = l;
r0 = r; g0 = g; b0 = b;
}
}
}
printf("#%02x%02x%02x (%0.5f)\n", r0, g0, b0, lum);
return 0;
}
(declaim (optimize (speed 3)))
(defun f (c)
(declare (type (integer 0 255) c))
(let ((x (/ c 255.0d0)))
(if (<= x 0.03928d0)
(/ x 12.92d0)
(expt (/ (+ x 0.055d0) 1.055d0) 2.4d0))))
(defun rel-lum (r g b)
(declare (type (integer 0 255) r g b))
(+ (* 0.2126d0 (f r)) (* 0.7152d0 (f g)) (* 0.0722d0 (f b))))
(defun contrast (r1 g1 b1 r2 g2 b2)
(let* ((l1 (rel-lum r1 g1 b1))
(l2 (rel-lum r2 g2 b2))
(ct (/ (+ l1 0.05d0) (+ l2 0.05d0))))
(max ct (/ ct))))
(defparameter colors '((106 228 185)
( 0 186 244)
(114 164 255)
(247 143 231)
( 88 221 19)
(229 240 64)))
(defun best-contrast (colors)
(let ((r0 0) (g0 0) (b0 0) (lum 0.0d0))
(dotimes (r 256)
(dotimes (g 256)
(dotimes (b 256)
(when (loop for (r1 g1 b1) in colors
always (>= (contrast r g b r1 g1 b1) 7.0d0))
(let ((l (rel-lum r g b)))
(when (>= l lum)
(setf lum l r0 r g0 g b0 b)))))))
(values (format nil "#~2,'0x~2,'0x~2,'0x" r0 b0 g0) lum)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment