【问题标题】:How to find good looking font color if background color is known? [closed]如果已知背景颜色,如何找到好看的字体颜色? [关闭]
【发布时间】:2010-09-23 01:05:40
【问题描述】:

那里似乎有很多色轮、颜色选择器和颜色匹配器 Web 应用程序,您可以在其中提供一种颜色,然后它们会找到其他几种颜色,这些颜色在组合使用时会产生和谐的布局.然而,它们中的大多数只关注背景颜色,并且在每种背景颜色上打印的任何文本(如果在预览中完全打印文本)都是黑色或白色。

我的问题不同。我知道要用于文本区域的背景颜色。我需要帮助的是选择几种颜色(越多越好)我可以在这个背景上用作字体颜色。最重要的是颜色会确保字体可读(对比度不要太低,也可以不要太高以避免眼睛受到压力),当然前景和背景的组合看起来很好。

有人知道这样的应用程序吗?我更喜欢 Web 应用程序,而不是我必须下载的任何东西。谢谢。

【问题讨论】:

    标签: colors accessibility readability


    【解决方案1】:

    如果您需要算法,请尝试以下操作:将颜色从 RGB 空间转换为 HSV 空间(色相、饱和度、值)。如果你的 UI 框架做不到,请查看这篇文章:http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV

    色相在 [0,360) 范围内。要找到“相反”的颜色(想想色轮),只需添加 180 度:

    h = (h + 180) % 360;
    

    对于饱和度和值,反转它们:

    l = 1.0 - l;
    v = 1.0 - v;
    

    转换回 RGB。即使大多数组合看起来很难看,这也应该始终为您提供高对比度。

    如果你想避免“丑”的部分,用几个“好”的组合建一个表,找到差异最小的一个

    def q(x):
        return x*x
    def diff(col1, col2):
        return math.sqrt(q(col1.r-col2.r) + q(col1.g-col2.g) + q(col1.b-col2.b))
    

    并使用它。

    【讨论】:

      【解决方案2】:

      好的,这仍然不是最好的解决方案,但是一个很好的起点。我写了一个小的 Java 应用程序,它计算两种颜色的对比度,只处理比例为 5:1 或更好的颜色 - 这个比例和我使用的公式已经由 W3C 发布,可能会取代当前的推荐(我认为非常有限)。它在当前工作目录中创建一个名为“chosen-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);
          }
      }
      

      【讨论】:

      • 加一,对比度计算,正是我想要的。
      【解决方案3】:

      这是一个有趣的问题,但我认为这实际上是不可能的。两种颜色是否“适合”作为背景和前景颜色取决于显示技术和人类视觉的生理特征,但最重要的是取决于经验塑造的个人品味。快速浏览一下 MySpace 非常清楚地表明,并非所有人都以相同的方式感知颜色。我不认为这是一个可以通过算法解决的问题,尽管在某个地方可能有一个巨大的数据库可以提供可接受的匹配颜色。

      【讨论】:

        【解决方案4】:

        出于不同的原因,我已经实现了类似的东西 - 那是告诉最终用户他们选择的前景色和背景色是否会导致无法阅读的文本的代码。为此,我没有检查 RGB 值,而是将颜色值转换为 HSL/HSV,然后通过实验确定在比较 fg 和 bg 值时我的可读性截止点是什么。这是您可能想要/需要考虑的事情。

        【讨论】:

          【解决方案5】:

          在我最近制作的一个应用程序中,我使用了反转颜色。有了 r,g 和 b 值,只需计算(在本例中,颜色范围从 0 到 255):

          r = 127-(r-127) and so on.
          

          【讨论】:

            【解决方案6】:

            回答我自己的问题可能很奇怪,但这是我以前从未见过的另一个非常酷的颜色选择器。它也不能解决我的问题:-((((但是我认为这对我已经知道的这些来说要酷得多。

            http://www.colorjack.com/

            在右侧,在“工具”下选择“Color Sphere”,一个非常强大且可自定义的球体(看看你可以用顶部的弹出窗口做什么),“Color Galaxy”,我仍然不确定它是如何工作的,但看起来很酷,“Color Studio”也不错。此外,它可以导出为各种格式(例如 Illustrator 或 Photoshop 等)

            怎么样,我在那里选择我的背景颜色,让它创建一个互补色(从第一个弹出窗口开始) - 这应该具有最高的对比度,因此可读性最好,现在选择互补色作为主色并选择中性?嗯……也不是很好,但我们正在变得更好;-)

            【讨论】:

            • 不,回答你自己的问题一点也不奇怪,我自己也做过几次,而且把答案放在那里只会让社区变得更好。
            【解决方案7】:

            您是否考虑过让您的应用程序的用户选择他们自己的配色方案?毫无疑问,您无法通过您的选择取悦所有用户,但您可以让他们找到让他们满意的内容。

            【讨论】:

            • 让用户决定没有错,但我至少应该包含一个有用的默认颜色主题,不是吗?在每个用户修复它之前,默认情况下它不可能是不可读和丑陋的;-)
            【解决方案8】:

            类似于@Aaron Digulla 的建议,除了我建议使用图形设计工具,选择基础颜色,在您的情况下选择背景颜色,然后调整色调、饱和度和值。使用它,您可以非常轻松地创建颜色样本。 Paint.Net 是免费的,我一直为此使用它,付费工具也可以做到这一点。

            【讨论】:

              【解决方案9】:

              我个人认为我们无法找到一种算法来通过指定背景颜色来计算最匹配的文本颜色。

              我认为目前艺术家应该有一个具有良好阅读质量的颜色对列表,我们可以将它们添加到一个表格中,并将其中一个随机设置为我们的阅读主题...

              这很合理,我们不会得到丑陋的颜色对......

              【讨论】:

                猜你喜欢
                • 2020-08-07
                • 1970-01-01
                • 2020-12-13
                • 2016-04-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-06-03
                相关资源
                最近更新 更多