反转相反的颜色

时间:2011-01-12 18:06:25

标签: java android colors

我有一个用户设置,他们可以选择警报的颜色。警报是文本或按钮上的背景颜色。但问题在于,如果他们选择深蓝色并且我们有黑色字母,那么对比度就足够了,你无法阅读它。

我试图制作一个功能来获得反向相反的颜色,但还没有走得太远。

有这样的功能吗?

12 个答案:

答案 0 :(得分:23)

使用complementary color

Algo很简单,从255中减去每个颜色分量以获得新的颜色分量

Color textColor = Color.rgb(255-Color.red(bgColor),
                         255-Color.green(bgColor),
                         255-Color.blue(bgColor));

-----编辑(因为基于RGB的补充可能无法正常工作--------

这两个链接非常有用,主题如下:

http://www.splitbrain.org/blog/2008-09/18-calculating_color_contrast_with_php

http://24ways.org/2010/calculating-color-contrast

答案 1 :(得分:23)

我发现对我来说最好的解决方案是将RGB值转换为YIQ值。由于我们只对亮度值(由Y表示)感兴趣,因此只需进行一次计算:Y = (299*R + 587*G + 114*B)/1000。它的Java代码如下所示:

public static Color getContrastColor(Color color) {
  double y = (299 * color.getRed() + 587 * color.getGreen() + 114 * color.getBlue()) / 1000;
  return y >= 128 ? Color.black : Color.white;
}

根据原始颜色的亮度,您可以看到它只是决定使用黑色或白色。在我看来,结果非常好。权重(299,587,114)与眼睛的敏感度(或视网膜的敏感度)成正比。

答案 2 :(得分:8)

根据Marks解决方案,我建议:

public static int getComplementaryColor(int colorToInvert) {
    float[] hsv = new float[3];
    Color.RGBToHSV(Color.red(colorToInvert), Color.green(colorToInvert),
            Color.blue(colorToInvert), hsv);
    hsv[0] = (hsv[0] + 180) % 360;
    return Color.HSVToColor(hsv);
}

此外,我现在创建了一个类似的方法,用于计算给定颜色的默认背景:

public static int getContrastVersionForColor(int color) {
    float[] hsv = new float[3];
    Color.RGBToHSV(Color.red(color), Color.green(color), Color.blue(color),
            hsv);
    if (hsv[2] < 0.5) {
        hsv[2] = 0.7f;
    } else {
        hsv[2] = 0.3f;
    }
    hsv[1] = hsv[1] * 0.2f;
    return Color.HSVToColor(hsv);
}

答案 3 :(得分:3)

整数解决方案:

public static int getContrastColor(int color) {
        double y = (299 * Color.red(color) + 587 * Color.green(color) + 114 * Color.blue(color)) / 1000;
        return y >= 128 ? Color.BLACK : Color.WHITE;
    }

答案 4 :(得分:2)

我认为它工作了,我认为:)

这是功能:

public static int OpposeColor(int ColorToInvert)
{
     int RGBMAX = 255;

     float[] hsv = new float[3];
     float H;

     Log.i("HSV_H", "Start Color=" +  ColorToInvert);

     Color.RGBToHSV( Color.red( ColorToInvert),  RGBMAX - Color.green( ColorToInvert), Color.blue(ColorToInvert), hsv);

     Log.i("HSV_H", "Hue=" + hsv[0]);
     Log.i("HSV_H", "Saturation=" + hsv[1]);
     Log.i("HSV_H", "Value=" + hsv[2]);

    H = (float) (hsv[0] + 0.5);

    if (H > 1) H -= 1;

    Log.i("HSV_H", "Hue2=" + H);         

    Log.i("HSV_H", "Color=" +  Color.HSVToColor(hsv ));

    return Color.HSVToColor(hsv );


}

答案 5 :(得分:1)

文本是否必须是从背景颜色派生的颜色?如果它只根据r g b强度在白色和黑色之间交替怎么办?这个想法是,白色将始终在低于特定强度的r g b值上可见,而其余部分始终可见黑色。

我没有可用的算法来分享,但您可以尝试以下方式:

int threshold = 50;
if(r < threshold && g < threshold && b < threshold) {
  // set your font color to white
} else {
  // set your font color to black
}

你可能不得不稍微调整一下门槛以获得好看的东西。您还可以根据哪个r g b值占优势来对字体进行着色。

答案 6 :(得分:1)

对西蒙斯的答案稍作修改

float[] hsv = new float[3];
java.awt.Color.RGBtoHSB( bgColour.getRed(), bgColour.getGreen(), bgColour.getBlue(), hsv );
hsv[2] = (hsv[2] + 180) % 360;
java.awt.Color   invertedColour = java.awt.Color.getHSBColor( hsv[ 0 ], hsv[ 1 ], hsv[ 2 ] );

答案 7 :(得分:1)

正如Sarwar Erfan指出的那样,请使用互补色。为此,您可以使用整数掩码(比分别反转R,G,B颜色分量要快)。

int textColor = bgColor ^ 0x00ffffff;

答案 8 :(得分:0)

您可以计算每个颜色通道(红色,绿色和蓝色)之间的差异,并获得平均差异 - 然后根据它进行一些比较。

答案 9 :(得分:0)

import android.graphics.Color;
import android.graphics.Paint;

/**
 * Utilities for performing common color-related tasks.
 * @author Ryan Ware
 *
 */
public class ColorUtils {

  public static int getComplimentColor(Paint paint) {
    return getComplimentColor(paint.getColor());
  }

  /**
   * Returns the complimentary (opposite) color.
   * @param color int RGB color to return the compliment of
   * @return int RGB of compliment color
   */
  public static int getComplimentColor(int color) {
    // get existing colors
    int alpha = Color.alpha(color);
    int red = Color.red(color);
    int blue = Color.blue(color);
    int green = Color.green(color);

    // find compliments
    red = (~red) & 0xff;
    blue = (~blue) & 0xff;
    green = (~green) & 0xff;

    return Color.argb(alpha, red, green, blue);
  }

  /**
   * Converts an int RGB color representation into a hexadecimal {@link String}.
   * @param argbColor int RGB color
   * @return {@link String} hexadecimal color representation
   */
  public static String getHexStringForARGB(int argbColor) {
    String hexString = "#";
    hexString += ARGBToHex(Color.alpha(argbColor));
    hexString += ARGBToHex(Color.red(argbColor));
    hexString += ARGBToHex(Color.green(argbColor));
    hexString += ARGBToHex(Color.blue(argbColor));

    return hexString;
  }

  /**
   * Converts an int R, G, or B value into a hexadecimal {@link String}.
   * @param rgbVal int R, G, or B value
   * @return {@link String} hexadecimal value
   */
  private static String ARGBToHex(int rgbVal) {
    String hexReference = "0123456789ABCDEF";

    rgbVal = Math.max(0,rgbVal);
    rgbVal = Math.min(rgbVal,255);
    rgbVal = Math.round(rgbVal);

    return String.valueOf( hexReference.charAt((rgbVal-rgbVal%16)/16) + "" + hexReference.charAt(rgbVal%16) );
  }
}

感谢:http://www.java2s.com/Code/Android/2D-Graphics/Returnsthecomplimentaryoppositecolor.htm

答案 10 :(得分:0)

ColorUtils.calculateLuminance(int color)可用于确定给定背景色是使用深色还是明亮的文本颜色。

示例:

if (ColorUtils.calculateLuminance(backgroundColor) <= 0.5) textColor = <bright>
else textColor = <dark>

可以通过实验选择阈值(在此示例中为0.5,以获得最佳视觉效果。

Documentation

答案 11 :(得分:0)

用于转换整数格式颜色的另一种通用解决方案是:

private int getComplementaryColor( int color) {
    int R = color & 255;
    int G = (color >> 8) & 255;
    int B = (color >> 16) & 255;
    int A = (color >> 24) & 255;
    R = 255 - R;
    G = 255 - G;
    B = 255 - B;
    return R + (G << 8) + ( B << 16) + ( A << 24);
}