Được rồi, đây vẫn không phải là giải pháp tốt nhất có thể, nhưng là một điểm tốt để bắt đầu. Tôi đã viết một ứng dụng Java nhỏ để tính toán tỷ lệ tương phản của hai màu và chỉ xử lý các màu có tỷ lệ 5: 1 trở lên - tỷ lệ này và công thức tôi sử dụng đã được W3C phát hành và có thể sẽ thay thế đề xuất hiện tại ( Tôi xem xét rất hạn chế). Nó tạo một tệp trong dir đang hoạt động hiện tại có tên là "selected-font-Colors.html", với màu nền bạn chọn và một dòng văn bản bằng mọi màu đã vượt qua bài kiểm tra W3C này. Nó mong đợi một đối số duy nhất, là màu nền.
Ví dụ bạn có thể gọi nó như thế này
java FontColorChooser 33FFB4
sau đó chỉ cần mở tệp HTML đã tạo trong trình duyệt bạn chọn và chọn một màu từ danh sách. Tất cả các màu được đưa ra đều vượt qua bài kiểm tra W3C cho màu nền này. Bạn có thể thay đổi phần cắt bỏ bằng cách thay thế số 5 bằng một số bạn chọn (các số thấp hơn cho phép độ tương phản yếu hơn, ví dụ: 3 sẽ chỉ đảm bảo độ tương phản là 3: 1, 10 sẽ đảm bảo ít nhất là 10: 1) và bạn cũng có thể cắt bỏ để tránh độ tương phản quá cao (bằng cách đảm bảo rằng nó nhỏ hơn một số nhất định), ví dụ như thêm
|| cDiff > 18.0
đối với mệnh đề if sẽ đảm bảo rằng độ tương phản sẽ không quá cực đoan, vì sự tương phản quá lớn có thể khiến mắt bạn căng thẳng. Đây là mã và vui chơi với nó một chút :-)
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);
}
}