Ich möchte einige Bilder wie dieses Beispiel zeigen
Die Füllfarbe wird durch ein Feld in der Datenbank mit der Farbe in Hex festgelegt (z. B. ClassX -> Color: # 66FFFF) . Nun möchte ich Daten über einer Füllung mit der ausgewählten Farbe anzeigen (wie in Bild oben), aber ich muss wissen, ob die Farbe dunkel oder hell ist, also weiß ich, ob die Wörter weiß oder schwarz sein sollten. Gibt es einen Weg? tks
Aufbauend auf meiner Antwort auf eine ähnliche Frage .
Sie müssen den Hex-Code in 3 Teile aufteilen, um die einzelnen Rot-, Grün- und Blau-Intensitäten zu erhalten. Jeweils zwei Ziffern des Codes repräsentieren einen Wert in hexadezimaler Schreibweise (Basis-16). Ich werde hier nicht auf die Details der Konvertierung eingehen, sie sind leicht zu finden.
Wenn Sie die Intensitäten für die einzelnen Farben festgelegt haben, können Sie die Gesamtintensität der Farbe bestimmen und den entsprechenden Text auswählen.
if (red*0.299 + green*0.587 + blue*0.114) > 186 use #000000 else use #ffffff
Die Schwelle von 186 basiert auf der Theorie, kann aber nach Geschmack eingestellt werden. Basierend auf den Kommentaren unterhalb kann ein Schwellenwert von 150 für Sie besser funktionieren .
Die Formel für den Kontrast in W3C Recommendations ist (L1 + 0.05) / (L2 + 0.05)
, wobei L1
die Luminanz der hellsten Farbe und L2
die Luminanz des dunkelsten auf einer Skala von 0,0-1,0 ist. Die Luminanz von Schwarz ist 0,0 und Weiß ist 1,0. Durch Ersetzen dieser Werte können Sie den Wert mit dem höchsten Kontrast bestimmen. Wenn der Kontrast für Schwarz größer als der Kontrast für Weiß ist, verwenden Sie Schwarz, andernfalls Weiß. Angesichts der Leuchtdichte der Farbe, die Sie als L
testen, wird der Test zu:
if (L + 0.05) / (0.0 + 0.05) > (1.0 + 0.05) / (L + 0.05) use #000000 else use #ffffff
Dies vereinfacht algebraisch:
if L > sqrt(1.05 * 0.05) - 0.05
Oder ungefähr:
if L > 0.179 use #000000 else use #ffffff
Das einzige, was bleibt, ist L
zu berechnen. Diese Formel ist auch in den Richtlinien angegeben und sieht aus wie die Umwandlung von sRGB in lineares RGB, gefolgt von der ITU-R-Empfehlung BT.709 für die Luminanz.
for each c in r,g,b:
c = c / 255.0
if c <= 0.03928 then c = c/12.92 else c = ((c+0.055)/1.055) ^ 2.4
L = 0.2126 * r + 0.7152 * g + 0.0722 * b
Der Schwellenwert von 0,179 sollte nicht geändert werden, da er an die W3C-Richtlinien gebunden ist. Wenn Sie die Ergebnisse nicht für Sie finden, probieren Sie die einfachere Formel aus.
Ich akzeptiere diesen Code nicht, da er nicht mein ist, aber ich lasse ihn hier, damit andere ihn in der Zukunft schnell finden können:
Basierend auf der Antwort von Mark Ransoms, hier ein Code-Snippet für die einfache Version:
function pickTextColorBasedOnBgColorSimple(bgColor, lightColor, darkColor) {
var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB
return (((r * 0.299) + (g * 0.587) + (b * 0.114)) > 186) ?
darkColor : lightColor;
}
und hier ist der Code-Ausschnitt für die erweiterte Version:
function pickTextColorBasedOnBgColorAdvanced(bgColor, lightColor, darkColor) {
var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB
var uicolors = [r / 255, g / 255, b / 255];
var c = uicolors.map((col) => {
if (col <= 0.03928) {
return col / 12.92;
}
return Math.pow((col + 0.055) / 1.055, 2.4);
});
var L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
return (L > 0.179) ? darkColor : lightColor;
}
Um sie zu benutzen, rufen Sie einfach an:
var color = '#EEACAE' // this can be any color
pickTextColorBasedOnBgColorSimple(color, '#FFFFFF', '#000000');
Danke auch Alx
und chetstone
.
Wie wäre es damit (JavaScript-Code)?
/**
* Get color (black/white) depending on bgColor so it would be clearly seen.
* @param bgColor
* @returns {string}
*/
getColorByBgColor(bgColor) {
if (!bgColor) { return ''; }
return (parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2) ? '#000' : '#fff';
}
Hier ist meine Lösung in Java für Android:
// Put this method in whichever class you deem appropriate
// static or non-static, up to you.
public static int getContrastColor(int colorIntValue) {
int red = Color.red(colorIntValue);
int green = Color.green(colorIntValue);
int blue = Color.blue(colorIntValue);
double lum = (((0.299 * red) + ((0.587 * green) + (0.114 * blue))));
return lum > 186 ? 0xFF000000 : 0xFFFFFFFF;
}
// Usage
// If Color is represented as HEX code:
String colorHex = "#484588";
int color = Color.parseColor(colorHex);
// Or if color is Integer:
int color = 0xFF484588;
// Get White (0xFFFFFFFF) or Black (0xFF000000)
int contrastColor = WhateverClass.getContrastColor(color);
Zusätzlich zu den Rechenlösungen kann auch ein neuronales KI-Netzwerk verwendet werden. Der Vorteil ist, dass Sie es an Ihren eigenen Geschmack und Ihre Bedürfnisse anpassen können (dh weißlicher Text auf hellen gesättigten Rottönen sieht gut aus und ist genauso lesbar wie Schwarz).
Hier ist eine nette Javascript-Demo, die das Konzept veranschaulicht. Sie können Ihre eigene JS-Formel auch direkt in der Demo erstellen.
https://harthur.github.io/brain/
Nachfolgend finden Sie einige Diagramme, die mir dabei geholfen haben, meine Gedanken zu fassen um das Problem . Im ersten Diagramm ist die Helligkeit konstant 128, während Farbton und Sättigung variieren. In der zweiten Tabelle ist die Sättigung konstant 255, während Farbton und Helligkeit variieren.
Dies ist nur ein Beispiel, bei dem die Farbe eines SVG-Häkchens geändert wird, wenn Sie auf ein Element klicken. Die Farbe des Häkchens wird auf der Hintergrundfarbe des angeklickten Elements auf Schwarz oder Weiß gesetzt.
checkmarkColor: function(el) {
var self = el;
var contrast = function checkContrast(rgb) {
// @TODO check for HEX value
// Get RGB value between parenthesis, and remove any whitespace
rgb = rgb.split(/\(([^)]+)\)/)[1].replace(/ /g, '');
// map RGB values to variables
var r = parseInt(rgb.split(',')[0], 10),
g = parseInt(rgb.split(',')[1], 10),
b = parseInt(rgb.split(',')[2], 10),
a;
// if RGBA, map alpha to variable (not currently in use)
if (rgb.split(',')[3] !== null) {
a = parseInt(rgb.split(',')[3], 10);
}
// calculate contrast of color (standard grayscale algorithmic formula)
var contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000;
return (contrast >= 128) ? 'black' : 'white';
};
$('#steps .step.color .color-item .icon-ui-checkmark-shadow svg').css({
'fill': contrast($(self).css('background-color'))
});
}
onClickExtColor: function(evt) {
var self = this;
self.checkmarkColor(evt.currentTarget);
}
Basierend auf der Antwort von @MarkRansom habe ich ein PHP Skript erstellt, das Sie hier finden können:
function calcC($c) {
if ($c <= 0.03928) {
return $c / 12.92;
}
else {
return pow(($c + 0.055) / 1.055, 2.4);
}
}
function cutHex($h) {
return ($h[0] == "#") ? substr($h, 1, 7) : $h;
}
function hexToR($h) {
return hexdec(substr(cutHex($h), 0, 2));
}
function hexToG($h) {
return hexdec(substr(cutHex($h), 2, 2)); // Edited
}
function hexToB($h) {
return hexdec(substr(cutHex($h), 4, 2)); // Edited
}
function computeTextColor($color) {
$r = hexToR($color);
$g = hexToG($color);
$b = hexToB($color);
$uicolors = [$r / 255, $g / 255, $b / 255];
$c = array_map("calcC", $uicolors);
$l = 0.2126 * $c[0] + 0.7152 * $c[1] + 0.0722 * $c[2];
return ($l > 0.179) ? '#000000' : '#ffffff';
}
Mit dieser JavaScript-Funktion konvertiere ich rgb
/rgba
in 'white'
Oder 'black'
.
function getTextColor(rgba) {
rgba = rgba.match(/\d+/g);
if ((rgba[0] * 0.299) + (rgba[1] * 0.587) + (rgba[2] * 0.114) > 186) {
return 'black';
} else {
return 'white';
}
}
Sie können eines dieser Formate eingeben und es wird 'black'
Oder 'white'
Ausgegeben.
rgb(255,255,255)
rgba(255,255,255,0.1)
color:rgba(255,255,255,0.1)
255,255,255,0.1
Ich habe so etwas noch nie gemacht, aber was ist mit dem Schreiben einer Funktion, um die Werte jeder Farbe mit der mittleren Farbe von Hex 7F (FF/2) zu vergleichen. Wenn zwei der drei Farben größer als 7F sind, arbeiten Sie mit einer dunkleren Farbe.
Mark detaillierte Antwort funktioniert super. Hier ist eine Implementierung in Javascript:
function lum(rgb) {
var lrgb = [];
rgb.forEach(function(c) {
c = c / 255.0;
if (c <= 0.03928) {
c = c / 12.92;
} else {
c = Math.pow((c + 0.055) / 1.055, 2.4);
}
lrgb.Push(c);
});
var lum = 0.2126 * lrgb[0] + 0.7152 * lrgb[1] + 0.0722 * lrgb[2];
return (lum > 0.179) ? '#000000' : '#ffffff';
}
Dann kann diese Funktion lum([111, 22, 255])
aufgerufen werden, um weiß oder schwarz zu werden.
LESS hat eine Nice contrast()
-Funktion, die gut für mich funktioniert hat, siehe http://lesscss.org/functions/#color-operations-contrast
"Wählen Sie aus, welche der beiden Farben den stärksten Kontrast zu einer anderen bietet .. _. Dies ist nützlich, um sicherzustellen, dass eine Farbe vor einem Hintergrund lesbar ist, was auch für die Einhaltung der Barrierefreiheit hilfreich ist. Diese Funktion funktioniert genauso wie die Kontrastfunktion in Compass for SASS. Gemäß WCAG 2.0 werden Farben anhand ihres gamma-korrigierten Luma-Werts und nicht anhand ihrer Helligkeit verglichen. "
Beispiel:
p {
a: contrast(#bbbbbb);
b: contrast(#222222, #101010);
c: contrast(#222222, #101010, #dddddd);
d: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 30%);
e: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 80%);
}
Ausgabe:
p {
a: #000000 // black
b: #ffffff // white
c: #dddddd
d: #000000 // black
e: #ffffff // white
}
@SoBiT, ich habe mir deine Antwort angesehen, die gut aussieht, aber es gibt einen kleinen Fehler. Ihre Funktion hexToG und hextoB müssen geringfügig bearbeitet werden. Die letzte Zahl in substr ist die Länge der Zeichenfolge. In diesem Fall sollte sie "2" und nicht 4 oder 6 sein.
function hexToR($h) {
return hexdec(substr(cutHex($h), 0, 2));
}
function hexToG($h) {
return hexdec(substr(cutHex($h), 2, 2));
}
function hexToB($h) {
return hexdec(substr(cutHex($h), 4, 2));
}
Dies ist eine schnelle Version von Mark Ransoms Antwort als Erweiterung von UIColor
extension UIColor {
// Get the rgba components in CGFloat
var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return (red, green, blue, alpha)
}
/// Return the better contrasting color, white or black
func contrastColor() -> UIColor {
let rgbArray = [rgba.red, rgba.green, rgba.blue]
let luminanceArray = rgbArray.map({ value -> (CGFloat) in
if value < 0.03928 {
return (value / 12.92)
} else {
return (pow( (value + 0.55) / 1.055, 2.4) )
}
})
let luminance = 0.2126 * luminanceArray[0] +
0.7152 * luminanceArray[1] +
0.0722 * luminanceArray[2]
return luminance > 0.179 ? UIColor.black : UIColor.white
} }
Versionscode für Objective-c für iOS basierend auf Marks Antwort:
- (UIColor *)contrastForegroundColor {
CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[self getRed:&red green:&green blue:&blue alpha:&alpha];
NSArray<NSNumber *> *rgbArray = @[@(red), @(green), @(blue)];
NSMutableArray<NSNumber *> *parsedRGBArray = [NSMutableArray arrayWithCapacity:rgbArray.count];
for (NSNumber *item in rgbArray) {
if (item.doubleValue <= 0.03928) {
[parsedRGBArray addObject:@(item.doubleValue / 12.92)];
} else {
double newValue = pow((item.doubleValue + 0.055) / 1.055, 2.4);
[parsedRGBArray addObject:@(newValue)];
}
}
double luminance = 0.2126 * parsedRGBArray[0].doubleValue + 0.7152 * parsedRGBArray[1].doubleValue + 0.0722 * parsedRGBArray[2].doubleValue;
return luminance > 0.179 ? UIColor.blackColor : UIColor.whiteColor;
}
Basierend auf verschiedenen Eingaben aus dem Link Vordergrundfarbe schwarz oder weiß abhängig vom Hintergrund festlegen und diesem Thread habe ich eine Erweiterungsklasse für Color erstellt, die die erforderlichen Kontrastfarben ergibt.
Der Code lautet wie folgt:
public static class ColorExtension
{
public static int PerceivedBrightness(this Color c)
{
return (int)Math.Sqrt(
c.R * c.R * .299 +
c.G * c.G * .587 +
c.B * c.B * .114);
}
public static Color ContrastColor(this Color iColor, Color darkColor,Color lightColor)
{
// Counting the perceptive luminance (aka luma) - human eye favors green color...
double luma = (iColor.PerceivedBrightness() / 255);
// Return black for bright colors, white for dark colors
return luma > 0.5 ? darkColor : lightColor;
}
public static Color ContrastColor(this Color iColor) => iColor.ContrastColor(Color.Black);
public static Color ContrastColor(this Color iColor, Color darkColor) => iColor.ContrastColor(darkColor, Color.White);
// Converts a given Color to gray
public static Color ToGray(this Color input)
{
int g = (int)(input.R * .299) + (int)(input.G * .587) + (int)(input.B * .114);
return Color.FromArgb(input.A, g, g, g);
}
}
Wie wäre es mit allen 24-Bit-Farben zu testen?
Beachten Sie, dass die YIQ-Methode ein minimales Kontrastverhältnis von 1,9: 1 liefert, das die AA- und AAA-WCAG2.0-Tests nicht bestanden hat, wenn ein Schwellenwert von 128 angenommen wird.
Bei der W3C-Methode wird ein minimales Kontrastverhältnis von 4,58: 1 zurückgegeben, das die AA- und AAA-Tests für großen Text und den AA-Test für kleinen Text bestanden hat. Es wird den AAA-Test für kleinen Text für jede Farbe nicht bestehen.
Hier ist meine eigene Methode, mit der ich bisher keine Probleme hatte ????
const hexCode = value.charAt(0) === '#'
? value.substr(1, 6)
: value;
const hexR = parseInt(hexCode.substr(0, 2), 16);
const hexG = parseInt(hexCode.substr(2, 2), 16);
const hexB = parseInt(hexCode.substr(4, 2), 16);
// Gets the average value of the colors
const contrastRatio = (hexR + hexG + hexB) / (255 * 3);
contrastRatio >= 0.5
? 'black'
: 'white';
Von Hex zu Schwarz oder Weiß:
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? [
parseInt(result[1], 16),
parseInt(result[2], 16),
parseInt(result[3], 16)
]
: [0, 0, 0];
}
function lum(hex) {
var rgb = hexToRgb(hex)
var lrgb = [];
rgb.forEach(function(c) {
c = c / 255.0;
if (c <= 0.03928) {
c = c / 12.92;
} else {
c = Math.pow((c + 0.055) / 1.055, 2.4);
}
lrgb.Push(c);
});
var lum = 0.2126 * lrgb[0] + 0.7152 * lrgb[1] + 0.0722 * lrgb[2];
return lum > 0.179 ? "#000000" : "#ffffff";
}