Last active
October 19, 2024 12:09
-
-
Save oantolin/3c49f488b8b943a801791180b33f65c0 to your computer and use it in GitHub Desktop.
Find most luminous contrasting color
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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