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):
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.
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.
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.
In XML, we can set a text color by the textColor attribute, like android:textColor="#FF0000" .
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With