Гаразд, це все ще не найкраще можливе рішення, але хороший момент для початку. Я написав невелику програму Java, яка обчислює коефіцієнт контрастності двох кольорів і обробляє кольори лише у співвідношенні 5: 1 або краще - це співвідношення та формула, яку я використовую, було опубліковано W3C і, можливо, замінить поточну рекомендацію Я вважаю дуже обмеженим). Він створює файл у поточному робочому каталозі з назвою "selected-font-colors.html", із вибраним кольором тла та рядком тексту у кожному кольорі, що пройшов цей тест W3C. Він очікує одного аргументу, який є кольором тла.
Наприклад, ви можете назвати це так
java FontColorChooser 33FFB4
тоді просто відкрийте згенерований HTML-файл у вибраному вами браузері та виберіть колір зі списку. Усі вказані кольори пройшли тест W3C для цього кольору фону. Ви можете змінити відрізок, замінивши 5 на номер на ваш вибір (нижчі цифри дозволяють слабкі контрасти, наприклад, 3 лише переконайтеся, що контраст 3: 1, 10 переконається, що він становить принаймні 10: 1), відрізати, щоб уникнути занадто високих контрастів (переконавшись, що він менший за певну кількість), наприклад додавання
|| cDiff > 18.0
до речення if забезпечить, щоб контраст не був надто екстремальним, оскільки занадто екстремальні контрасти можуть напружувати ваші очі. Ось код і весело пограйте з ним :-)
import java.io.*;
/* For text being readable, it must have a good contrast difference. Why?
* Your eye has receptors for brightness and receptors for each of the colors
* red, green and blue. However, it has much more receptors for brightness
* than for color. If you only change the color, but both colors have the
* same contrast, your eye must distinguish fore- and background by the
* color only and this stresses the brain a lot over the time, because it
* can only use the very small amount of signals it gets from the color
* receptors, since the breightness receptors won't note a difference.
* Actually contrast is so much more important than color that you don't
* have to change the color at all. E.g. light red on dark red reads nicely
* even though both are the same color, red.
*/
public class FontColorChooser {
int bred;
int bgreen;
int bblue;
public FontColorChooser(String hexColor) throws NumberFormatException {
int i;
i = Integer.parseInt(hexColor, 16);
bred = (i >> 16);
bgreen = (i >> 8) & 0xFF;
bblue = i & 0xFF;
}
public static void main(String[] args) {
FontColorChooser fcc;
if (args.length == 0) {
System.out.println("Missing argument!");
System.out.println(
"The first argument must be the background" +
"color in hex notation."
);
System.out.println(
"E.g. \"FFFFFF\" for white or \"000000\" for black."
);
return;
}
try {
fcc = new FontColorChooser(args[0]);
} catch (Exception e) {
System.out.println(
args[0] + " is no valid hex color!"
);
return;
}
try {
fcc.start();
} catch (IOException e) {
System.out.println("Failed to write output file!");
}
}
public void start() throws IOException {
int r;
int b;
int g;
OutputStreamWriter out;
out = new OutputStreamWriter(
new FileOutputStream("chosen-font-colors.html"),
"UTF-8"
);
// simple, not W3C comform (most browsers won't care), HTML header
out.write("<html><head><title>\n");
out.write("</title><style type=\"text/css\">\n");
out.write("body { background-color:#");
out.write(rgb2hex(bred, bgreen, bblue));
out.write("; }\n</style></head>\n<body>\n");
// try 4096 colors
for (r = 0; r <= 15; r++) {
for (g = 0; g <= 15; g++) {
for (b = 0; b <= 15; b++) {
int red;
int blue;
int green;
double cDiff;
// brightness increasse like this: 00, 11,22, ..., ff
red = (r << 4) | r;
blue = (b << 4) | b;
green = (g << 4) | g;
cDiff = contrastDiff(
red, green, blue,
bred, bgreen, bblue
);
if (cDiff < 5.0) continue;
writeDiv(red, green, blue, out);
}
}
}
// finalize HTML document
out.write("</body></html>");
out.close();
}
private void writeDiv(int r, int g, int b, OutputStreamWriter out)
throws IOException
{
String hex;
hex = rgb2hex(r, g, b);
out.write("<div style=\"color:#" + hex + "\">");
out.write("This is a sample text for color " + hex + "</div>\n");
}
private double contrastDiff(
int r1, int g1, int b1, int r2, int g2, int b2
) {
double l1;
double l2;
l1 = (
0.2126 * Math.pow((double)r1/255.0, 2.2) +
0.7152 * Math.pow((double)g1/255.0, 2.2) +
0.0722 * Math.pow((double)b1/255.0, 2.2) +
0.05
);
l2 = (
0.2126 * Math.pow((double)r2/255.0, 2.2) +
0.7152 * Math.pow((double)g2/255.0, 2.2) +
0.0722 * Math.pow((double)b2/255.0, 2.2) +
0.05
);
return (l1 > l2) ? (l1 / l2) : (l2 / l1);
}
private String rgb2hex(int r, int g, int b) {
String rs = Integer.toHexString(r);
String gs = Integer.toHexString(g);
String bs = Integer.toHexString(b);
if (rs.length() == 1) rs = "0" + rs;
if (gs.length() == 1) gs = "0" + gs;
if (bs.length() == 1) bs = "0" + bs;
return (rs + gs + bs);
}
}