Jak wybrać kolor czcionki w kolorze białym lub czarnym w zależności od koloru tła?
Chcę pokazać kilka zdjęć, takich jak ten przykład
O kolorze wypełnienia decyduje pole w bazie danych z kolorem szesnastkowym(np.: ClassX - > Color: #66FFFF). Teraz chcę pokazać dane nad wypełnieniem z wybranym kolorem (JAK na obrazku powyżej), ale muszę wiedzieć, czy kolor jest ciemny czy jasny, więc wiem, czy słowa powinny być białe lub czarne. Jest jakiś sposób? tks
15 answers
Bazując na mojej odpowiedzi na podobne pytanie .
Musisz rozbić Kod hex na 3 części, aby uzyskać poszczególne intensywności czerwone, zielone i niebieskie. Każda 2 cyfra kodu reprezentuje wartość w zapisie szesnastkowym (baza-16). Nie będę tu wdawać się w szczegóły konwersji, łatwo je sprawdzić.
Po uzyskaniu intensywności dla poszczególnych kolorów można określić ogólną intensywność koloru i wybrać odpowiedni tekst.
if (red*0.299 + green*0.587 + blue*0.114) > 186 use #000000 else use #ffffff
Edit: powyższe jest proste i działa dość dobrze, i wydaje się mieć dobrą akceptację tutaj w StackOverflow. Jednak jedna z poniższych uwag pokazuje, że w pewnych okolicznościach może to prowadzić do nieprzestrzegania wytycznych W3C. Poniżej przedstawiam zmodyfikowaną formę, która zawsze wybiera najwyższy kontrast w oparciu o wytyczne.
Wzór podany dla kontrastu w zaleceniach W3C jest (L1 + 0.05) / (L2 + 0.05)
, Gdzie L1
jest luminancją najjaśniejszy kolor i L2
to luminancja najciemniejszego w skali 0,0-1,0. Luminancja czerni wynosi 0,0, a bieli 1,0, więc podstawianie tych wartości pozwala określić tę o najwyższym kontraście. Jeśli kontrast dla czerni jest większy niż kontrast dla bieli, użyj czerni, w przeciwnym razie użyj bieli. Z uwagi na luminancję koloru, który testujesz jako L
, test staje się:
if (L + 0.05) / (0.0 + 0.05) > (1.0 + 0.05) / (L + 0.05) use #000000 else use #ffffff
To upraszcza algebraicznie do:
if L > sqrt(1.05 * 0.05) - 0.05
Lub w przybliżeniu:
if L > 0.179 use #000000 else use #ffffff
Pozostało tylko obliczyć L
. Wzór ten jest również podany w wytycznych i wygląda jak konwersja z sRGB na liniową RGB, po której następuje ITU-R rekomendacja BT.709 dla luminancji.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:44
Co powiesz na to (kod JavaScript)?
/**
* 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';
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 11:55:48
Nie przypisuję sobie tego kodu, ponieważ nie jest mój, ale zostawiam go tutaj, aby inni mogli go szybko znaleźć w przyszłości: {]}
Na podstawie odpowiedzi Marka Ransomsa, oto fragment kodu do prostej wersji:
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;
}
A oto fragment kodu dla wersji advanced:
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;
}
Aby ich użyć wystarczy zadzwonić:
var color = '#EEACAE' // this can be any color
pickTextColorBasedOnBgColorSimple(color, '#FFFFFF', '#000000');
Również, dzięki Alx
i chetstone
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 17:31:58
Oto moje rozwiązanie w Javie dla Androida:
// 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-19 16:19:50
Oprócz rozwiązań arytmetycznych możliwe jest również wykorzystanie sieci neuronowej AI. Zaletą jest to, że można dostosować go do własnego gustu i potrzeb (np. prawie biały tekst na jasnych nasyconych czerwieniach wygląda dobrze i jest tak samo czytelny jak czarny).
Oto zgrabne demo Javascript, które ilustruje tę koncepcję. Możesz również wygenerować własną formułę JS bezpośrednio w demo.
Https://harthur.github.io/brain/
Poniżej kilka wykresów, które pomogły mi uzyskać mój umysł wokół problemu . Na pierwszym wykresie jasność jest stała 128, podczas gdy barwa i nasycenie różnią się. Na drugim wykresie nasycenie wynosi stałą 255, podczas gdy barwa i jasność są różne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-28 13:17:29
To tylko przykład, który zmieni kolor znacznika SVG po kliknięciu elementu. Spowoduje to ustawienie koloru znacznika na czarny lub biały w zależności od koloru tła klikniętego elementu.
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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 20:44:21
Używam tej funkcji JavaScript do Konwersji rgb
/rgba
do 'white'
lub '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';
}
}
Możesz wprowadzić dowolny z tych formatów i wyświetli 'black'
lub 'white'
rgb(255,255,255)
rgba(255,255,255,0.1)
color:rgba(255,255,255,0.1)
255,255,255,0.1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 16:09:55
Na podstawie odpowiedzi @MarkRansom stworzyłem skrypt PHP, który można znaleźć tutaj:
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';
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-11 14:50:33
Nigdy czegoś takiego nie robiłem, ale co powiesz na napisanie funkcji sprawdzającej wartości każdego z kolorów względem mediany koloru Hex 7F (FF / 2). Jeśli dwa z trzech kolorów są większe niż 7F, to pracujesz z ciemniejszym kolorem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-15 14:03:46
Szczegółowa odpowiedź Marka działa świetnie. Oto implementacja w 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';
}
Następnie można wywołać tę funkcję lum([111, 22, 255])
, Aby uzyskać biały lub czarny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 03:02:19
@SoBiT, patrzyłem na Twoją odpowiedź, która wygląda dobrze, ale jest w niej mały błąd. Twoja funkcja hexToG i hextoB wymagają drobnej edycji. Ostatnia liczba w substr jest długością ciągu, a więc w tym przypadku powinna być "2", a nie 4 lub 6.
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));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-25 15:54:39
LESS ma ładną contrast()
funkcję, która mi dobrze działała, Zobacz http://lesscss.org/functions/#color-operations-contrast
"Wybierz, który z dwóch kolorów zapewnia największy kontrast z innym. Jest to przydatne do zapewnienia, że kolor jest czytelny na tle, co jest również przydatne do zapewnienia zgodności z dostępnością. Funkcja ta działa tak samo jak funkcja kontrastu w kompasie dla SASS. Zgodnie z WCAG 2.0 kolory porównywane są za pomocą ich wartość luma z korekcją gamma, a nie ich lekkość."
Przykład:
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%);
}
Wyjście:
p {
a: #000000 // black
b: #ffffff // white
c: #dddddd
d: #000000 // black
e: #ffffff // white
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-19 16:02:37
Od hex do black or white:
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";
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-28 13:44:56
Objective-Kod wersji c dla iOS na podstawie odpowiedzi Marka:
- (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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-29 01:02:05
Jest to szybka wersja odpowiedzi Marka Ransoma jako rozszerzenie 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
} }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-28 15:28:08