Programmatically choose high-contrast colors

2019-01-22 19:10发布

This should be a simple question, but I haven't been able to find a way to make it work.

Essentially, I have a silly localhost page that I use in my webdevelopment. When I am surfing between our development server and my local version of the C# code (redirected from the dev url via host file) I have been known to sometimes forget what 'dev.foo.com' points at - local or server.

So I created a page which will run locally as my default web page's default page, so I can easily identify my localhost from the server.

This page does a lot of things randomly (including generating a character's starting stats for D&D), including setting a random background color. I do this by generating 3 random numbers between 0 and 255, and setting them as the RGB value for the body background color in CSS.

Given the 3 ints R, G, and B, how do I determine R2, G2, and B2 such that the second color will have high contrast with the first? I like having the page have random background colors (it keeps me from getting used to the look of the landing page) but I also like to be able to read the text.

11条回答
Summer. ? 凉城
2楼-- · 2019-01-22 19:28

You can use method GetBrightness() on Color class. It returns a float value from 0.0 (brightness of black) to 1.0 (white). A simple solution would be:

var color1 = new Color.FromArgb(r1, g1, b1);
var brightness = color1.GetBrightness();

var color2 = brightness > 0.5 ? Color.Black : Color.White;
查看更多
你好瞎i
3楼-- · 2019-01-22 19:31

Check out this PHP solution: Calculating Color Contrast with PHP by Andreas Gohr. It can be ported to any language of course.

He also has a very nice demonstration of his contrast analyzer where you can find some minimal contrast levels to work with.

查看更多
Evening l夕情丶
4楼-- · 2019-01-22 19:33

For best contrast use this code

function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){

    $L1 = 0.2126 * pow($R1/255, 2.2) +
          0.7152 * pow($G1/255, 2.2) +
          0.0722 * pow($B1/255, 2.2);

    $L2 = 0.2126 * pow($R2/255, 2.2) +
          0.7152 * pow($G2/255, 2.2) +
          0.0722 * pow($B2/255, 2.2);

    if($L1 > $L2){
        return ($L1+0.05) / ($L2+0.05);
    }else{
        return ($L2+0.05) / ($L1+0.05);
    }
}

function get_the_contrast($c1, $c2) {
    return (lumdiff(hexdec(substr($c1,0,2)),
        hexdec(substr($c1,2,2)),hexdec(substr($c1,4,2)),
        hexdec(substr($c2,0,2)),hexdec(substr($c2,2,2)),
        hexdec(substr($c2,4,2))));
}

The method above ( AVG(red,green,blue) > 128 ) is not realy good.

查看更多
forever°为你锁心
5楼-- · 2019-01-22 19:37

There are some good resources (and algorithms) to address this at http://juicystudio.com/article/luminositycontrastratioalgorithm.php

查看更多
戒情不戒烟
6楼-- · 2019-01-22 19:39

If you flip all the bits, you will get the "opposite" color which would be pretty good contrast.

I believe it's the ~ operator in C#:

R2 = ~R1;
G2 = ~G1;
B2 = ~B1;
查看更多
虎瘦雄心在
7楼-- · 2019-01-22 19:41
private Color GetContrastingColor(Color color)
{
    int r = color.R > 0 ? 256 - color.R : 255;
    int g = color.G > 0 ? 256 - color.G : 255;
    int b = color.B > 0 ? 256 - color.B : 255;
    return System.Drawing.Color.FromArgb(r, g, b);
}
查看更多
登录 后发表回答