Android / Java: Déterminer si la couleur du texte se fondra avec l'arrière-plan?


J'introduit la fonctionnalité de "marquage" dans mon application, et l'une des façons dont j'autorise l'affichage des balises est de définir le texte à la couleur sélectionnée par l'utilisateur pour chacune. Mon application a trois thèmes avec des arrière-plans blancs, noirs et bruns ressemblant à un bloc-notes (ceux-ci pourraient changer/grandir à l'avenir). Je veux pouvoir afficher la balise dans sa couleur native si elle contraste facilement l'arrière-plan, et utilisez simplement la couleur de texte par défaut pour chaque thème sinon.

J'ai écrit une fonction d'aide pour m'aider à déterminer si le texte sera masqué, mais ce n'est pas 100% correct (je veux qu'il détermine si les couleurs seront masquées en fonction des trois composants hsv, et en ce moment la comparaison de saturation n'est pas valide). Le code est ci-dessous.

    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;
   }

Lorsque vous appelez cette fonction avec du bleu, du rouge, du transparent, du noir, du jaune et du vert, la sortie est la suivante (respectivement):

  • h=0.0, s=1.0, v=1.0, thème=1
  • h=229,41177, s=1,0, v=1,0, thème=1
  • h=267.6923, s=1.0, v=0.050980393, thème=1
  • h=0.0, s=0.0, v=0.0, thème=1
  • h=59.52941, s=1.0, v=1.0, thème=1
  • h=111.29411, s=1.0, v=1.0, thème=1

Ma question est la suivante: en fonction de la teinte, de la saturation et de la valeur, comment pouvez-vous déterminer si le texte coloré d'une certaine manière apparaîtra sur un fond blanc par rapport à un fond noir ou s'il sera masqué? Veuillez prendre mon algorithme et l'améliorer ou m'aider à en créer un nouveau.

Merci dans avance.

Author: Blaskovicz, 2011-10-16

1 answers

La Solution que j'ai trouvé:

J'ai fini par utiliser un algorithme trouvé sur ce blog pour redéfinir ma fonction comme suit; j'ai ensuite ajusté la coupure de luminosité à chaque extrémité. Espérons que cela aide quelqu'un.

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;
}
 4
Author: Blaskovicz, 2014-09-18 23:49:36