Android/Java:确定文本颜色是否会与背景融合?

发布于 2024-12-10 05:00:14 字数 1291 浏览 0 评论 0原文

我在我的应用程序中引入“标记”功能,允许显示标记的方法之一是将文本设置为用户为每个标记选择的颜色。我的应用程序有三个主题,背景分别是白色、黑色和类似记事本的棕色(这些主题将来可能会改变/增长)。如果标签可以轻松地与背景形成对比,我希望能够以其本机颜色显示标签,否则只需为每个主题使用默认文本颜色。

我编写了一个辅助函数来帮助我确定文本是否将被屏蔽,但它不是 100% 正确(我希望它根据所有三个 HSV 组件来确定颜色是否将被屏蔽,现在的饱和度比较无效)。代码如下。

    public static boolean colorWillBeMasked(int color, Application app){

      float[] hsv = new float[3];
      Color.colorToHSV(color, hsv);
      //note 0, black 1, white 2
      int theme = app.api.getThemeView();
      System.out.println("h=" +hsv[0]+ ", s=" +hsv[1]+ ", v=" +hsv[2]+", theme="+theme);

      if(android.R.color.transparent == color) return true;
      // color is dark
      if(hsv[2] <= .2){
          if(theme == 1) return true;
      }
      // color is light
      else if(hsv[2] >= .8) {
          if(theme == 2) return true;
      }
      return false;
   }

当使用蓝色、红色、透明、黑色、黄色和绿色调用此函数时,输出分别如下:

  • h=0.0, s=1.0, v=1.0, theme=1
  • h=229.41177, s=1.0, v= 1.0,主题=1
  • h=267.6923,s=1.0,v=0.050980393,主题=1
  • h=0.0, s=0.0, v=0.0, theme=1
  • h=59.52941, s=1.0, v=1.0, theme=1
  • h=111.29411, s=1.0, v=1.0, theme=1

我的问题是:基于关于色调、饱和度和值,如何确定以某种方式着色的文本是否会显示在白色背景与黑色背景上,或者是否会显示在白色背景上?蒙面?请采用我的算法并改进它或帮助我创建一个新的算法。

提前致谢。

I'm introducing "tagging" functionality in my application, and one of the ways I allow tags to be displayed is to set the text to the color the user has selected for each. My application has three themes with backgrounds that are white, black and a notepad-like brown (these could change/grow in the future). I want to be able to display the tag in its native color if it easily contrasts the background, and just use the default text color for each theme otherwise.

I've written a helper function to help me determine if the text will be masked, but its not 100% correct (I want it to determine if colors will be masked based on all three of the hsv components, and right now the saturation comparison isn't valid). The code is below.

    public static boolean colorWillBeMasked(int color, Application app){

      float[] hsv = new float[3];
      Color.colorToHSV(color, hsv);
      //note 0, black 1, white 2
      int theme = app.api.getThemeView();
      System.out.println("h=" +hsv[0]+ ", s=" +hsv[1]+ ", v=" +hsv[2]+", theme="+theme);

      if(android.R.color.transparent == color) return true;
      // color is dark
      if(hsv[2] <= .2){
          if(theme == 1) return true;
      }
      // color is light
      else if(hsv[2] >= .8) {
          if(theme == 2) return true;
      }
      return false;
   }

When calling this function with blue, red, transparent, black, yellow and green the output is as follows (respectively):

  • h=0.0, s=1.0, v=1.0, theme=1
  • h=229.41177, s=1.0, v=1.0, theme=1
  • h=267.6923, s=1.0, v=0.050980393, theme=1
  • h=0.0, s=0.0, v=0.0, theme=1
  • h=59.52941, s=1.0, v=1.0, theme=1
  • h=111.29411, s=1.0, v=1.0, theme=1

My question is: based on hue, saturation and value, how can you determine if text that is colored a certain way will show up on a white background vs a black background or if it will be masked? Please take my algorithm and improve it or help me create a new one.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

轻拂→两袖风尘 2024-12-17 05:00:14

我想出的解决方案:

我最终使用了在此博客上重新定义我的函数,如下所示;然后我调整了两端的亮度截止值。希望这对某人有帮助。

public static boolean colorWillBeMasked(int color, Application app){
    if(android.R.color.transparent == color) return true;

    int[] rgb = {Color.red(color), Color.green(color), Color.blue(color)};

    int brightness =
        (int)Math.sqrt(
              rgb[0] * rgb[0] * .241 + 
              rgb[1] * rgb[1] * .691 + 
              rgb[2] * rgb[2] * .068);

    System.out.println("COLOR: " + color + ", BRIGHT: " + brightness);
    //note 0,black 1,classic 2
    int theme = app.api.getThemeView();

    // color is dark
    if(brightness <= 40){
        if(theme == 1) return true;
    }
    // color is light
    else if (brightness >= 215){
        if(theme == 2) return true;
    }
    return false;
}

Solution that I came up with:

I ended up using an algorithm found on this blog to redefine my function as follows; I then adjusted the brightness cut-off on each end. Hope this helps someone.

public static boolean colorWillBeMasked(int color, Application app){
    if(android.R.color.transparent == color) return true;

    int[] rgb = {Color.red(color), Color.green(color), Color.blue(color)};

    int brightness =
        (int)Math.sqrt(
              rgb[0] * rgb[0] * .241 + 
              rgb[1] * rgb[1] * .691 + 
              rgb[2] * rgb[2] * .068);

    System.out.println("COLOR: " + color + ", BRIGHT: " + brightness);
    //note 0,black 1,classic 2
    int theme = app.api.getThemeView();

    // color is dark
    if(brightness <= 40){
        if(theme == 1) return true;
    }
    // color is light
    else if (brightness >= 215){
        if(theme == 2) return true;
    }
    return false;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文