可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
You need a difference in brightness for text to be readable, as color vision itself has too low resolution.
So as an algorithm I'd suggest the following:
Pick a random background color.
Then decide whether it is a light or a dark color. For example you could check whether the average of the three primary colors is greater or equal 128.
For a light color use black text, for a dark one white text.
回答2:
"Contrast" is a loaded word. If you just care about being able to read the text, then one easy way is to work in a luminance-based color space like HSL, and pick foreground and background colors with big differences in luminance.
The conversion between HSL and RGB is well-known--see Wikipedia for the details.
If you're talking about actual color contrast, it's not nearly as cut-and-dried (there are a lot of perceptual factors that, as far as I know, haven't been reduced to a single colors space), but I suspect you don't need that level of sophistication.
回答3:
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.
回答4:
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;
回答5:
I did something like this in a Palm OS application. This is what I came up with. It doesn't give you "high contrast" colors but it gives you a background color that's different enough from the text color to be quite readable:
// Black background is a special case. It's fairly likely to occur and
// the default color shift we do isn't very noticeable with very dark colors.
if (backColor.r < 0x20 && backColor.g < 0x20 && backColor.b < 0x20)
{
textColor.r = backColor.r + 0x20;
textColor.g = backColor.g + 0x20;
textColor.b = backColor.b + 0x20;
}
else
{
textColor.r = backColor.r + ((backColor.r < 128) ? 0x10 : -0x10);
textColor.g = backColor.g + ((backColor.g < 128) ? 0x10 : -0x10);
textColor.b = backColor.b + ((backColor.b < 128) ? 0x10 : -0x10);
}
You might not need to do black as a special case for your purposes - Palm's color handling is a bit funky (16-bit color).
回答6:
There are some good resources (and algorithms) to address this at http://juicystudio.com/article/luminositycontrastratioalgorithm.php
回答7:
These answers are more or less suggesting to use one of the two or three color choices based on whether the color is bright or dark.
I use a bit different approach and it worked elegantly in my case. Here is the implementation.
int color = your_color;
contrastColor = Color.rgb(255-(color >> 16)&0xFF, 255-(color >> 8)&0xFF, 255- color&0xFF);
It's simple and wonderful.
回答8:
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;
回答9:
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.
回答10:
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);
}
回答11:
Thanks to @starblue !
Here is C#
code that I use
public static string GetContrastBlackOrWhiteColorAsHtmlColorCode(Color c)
{
System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml("transparent");
try
{
if (c.R >= 128 && c.G >= 128 && c.B >= 128)
{
return System.Drawing.ColorTranslator.ToHtml(Color.Black);
}
else
{
return System.Drawing.ColorTranslator.ToHtml(Color.White);
}
}
catch (Exception)
{
}
return System.Drawing.ColorTranslator.ToHtml(color);
}