我有一个用户设置,他们可以选择警报的颜色。警报是文本或按钮上的背景颜色。但问题在于,如果他们选择深蓝色并且我们有黑色字母,那么对比度就足够了,你无法阅读它。
我试图制作一个功能来获得反向相反的颜色,但还没有走得太远。
有这样的功能吗?
答案 0 :(得分:23)
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
答案 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
,以获得最佳视觉效果。
答案 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);
}