Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android/Java: Determining if text color will blend in with the background?

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.

like image 261
Blaskovicz Avatar asked Oct 16 '11 16:10

Blaskovicz


People also ask

How do we figure out if white color font or black color font is more readable?

Contrast with a Black or Dark Background While white text on a black background provides very high value contrast, it is less readable and causes greater eye fatigue than black text on a white background. All light-colored text on dark backgrounds causes eye fatigue.

How can I change the color of part of a string in Android?

It is easy to change the color of the whole string but to change the color of a substring we have to use a special class SpannableString. But SpannableString class is not really helpful when it comes to change the background color of the text. So for that, we have to use SpannableStringBuilder class.

How do I change text color in XML?

In XML, we can set a text color by the textColor attribute, like android:textColor="#FF0000" .


1 Answers

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;
}
like image 118
Blaskovicz Avatar answered Sep 27 '22 20:09

Blaskovicz