根据背景颜色确定字体颜色

Posted

技术标签:

【中文标题】根据背景颜色确定字体颜色【英文标题】:Determine font color based on background color 【发布时间】:2010-12-23 18:36:56 【问题描述】:

给定一个允许用户自定义某些部分的背景颜色而不是字体颜色的系统(例如网站)(以将选项数量保持在最低限度),有没有一种方法可以以编程方式确定“轻”或“深色”字体颜色是必要的?

我确定有一些算法,但我对颜色、亮度等了解不足,无法自行解决。

【问题讨论】:

【参考方案1】:

我遇到了类似的问题。我必须找到一种选择对比字体颜色的好方法,以在色标/热图上显示文本标签。它必须是通用方法,并且生成的颜色必须“好看”,这意味着简单地生成补色并不是好的解决方案——有时它会生成奇怪的、非常强烈的颜色,难以观看和阅读。

经过长时间的测试和尝试解决这个问题,我发现最好的解决方案是为“暗”颜色选择白色字体,为“亮”颜色选择黑色字体。

这是我在 C# 中使用的函数示例:

Color ContrastColor(Color color)

    int d = 0;

    // Counting the perceptive luminance - human eye favors green color... 
    double luminance = ( 0.299 * color.R + 0.587 * color.G + 0.114 * color.B)/255;

    if (luminance > 0.5)
       d = 0; // bright colors - black font
    else
       d = 255; // dark colors - white font

    return  Color.FromArgb(d, d, d);

这已针对许多不同的色阶(彩虹色、灰度色、热色、冰色和许多其他色阶)进行了测试,是我发现的唯一“通用”方法。

编辑 将计算a 的公式更改为“感知亮度”——看起来确实更好!已经在我的软件中实现了,看起来很棒。

编辑 2 @WebSeed 提供了该算法的一个很好的工作示例:http://codepen.io/WebSeed/full/pvgqEq/

【讨论】:

这可能并不重要,但您可能想要一个更好的函数来计算亮度***.com/questions/596216/… 您的感知亮度权重从何而来? 来自这个答案:***.com/questions/596216/… 这是旧的,我知道,但我不认为切换到黑色是这个算法的好地方。采用像 [135,135,135] 之类的东西,它位于灰色的较暗一侧,但显示为需要黑色字体。这不是一个糟糕的选择,但这里的白色字体显然更好。 这真是太棒了。我遇到了同样的问题,这解决了我的问题【参考方案2】:

如果您要处理视觉效果的色彩空间,则使用 HSL(色相、饱和度和亮度)通常比使用 RGB 更容易。在 RGB 中移动颜色以提供自然令人愉悦的效果在概念上往往非常困难,而转换为 HSL,在那里进行操作,然后再次转换回来在概念上更直观,并且总是能提供更好看的结果。

***有一个good introduction 到 HSL 和密切相关的 HSV。并且网上有免费代码可以进行转换(例如here is a javascript implementation)

您使用什么精确的转换是一个品味问题,但我个人认为反转色相和亮度组件肯定会生成良好的高对比度颜色作为第一近似值,但您可以轻松地进行更微妙的转换效果。

【讨论】:

是的,但也要考虑到人眼可以看到绿色比其他颜色更占主导地位,而蓝色则更少(这就是为什么蓝色在图像格式中获得的颜色位更少)。 确实如此。如果我们要迁移到 HSL,我们不妨完全跳到 YUV 并考虑人类感知。【参考方案3】:

感谢这篇文章。

对于可能感兴趣的人,以下是 Delphi 中该函数的示例:

function GetContrastColor(ABGColor: TColor): TColor;
var
  ADouble: Double;
  R, G, B: Byte;
begin
  if ABGColor <= 0 then
  begin
    Result := clWhite;
    Exit; // *** EXIT RIGHT HERE ***
  end;

  if ABGColor = clWhite then
  begin
    Result := clBlack;
    Exit; // *** EXIT RIGHT HERE ***
  end;

  // Get RGB from Color
  R := GetRValue(ABGColor);
  G := GetGValue(ABGColor);
  B := GetBValue(ABGColor);

  // Counting the perceptive luminance - human eye favors green color...
  ADouble := 1 - (0.299 * R + 0.587 * G + 0.114 * B) / 255;

  if (ADouble < 0.5) then
    Result := clBlack  // bright colors - black font
  else
    Result := clWhite;  // dark colors - white font
end;

【讨论】:

倒数第四行有一个小错误。结果:= clBlack 后面不应该有分号;【参考方案4】:

您可以在任何色调背景上使用任何色调文本并确保其清晰易读。我一直都这样做。在Readable Text in Colour – STW* 的 Javascript 中有一个公式 正如该链接上所说,该公式是逆伽马调整计算的一种变体,尽管恕我直言,更易于管理。 该链接右侧的菜单及其相关页面使用随机生成的文本和背景颜色,始终清晰易读。所以是的,显然可以做到,没问题。

【讨论】:

【参考方案5】:

以防万一有人想要更短、更容易理解的 GaceK's answer 版本:

public Color ContrastColor(Color iColor)

   // Calculate the perceptive luminance (aka luma) - human eye favors green color... 
   double luma = ((0.299 * iColor.R) + (0.587 * iColor.G) + (0.114 * iColor.B)) / 255;

   // Return black for bright colors, white for dark colors
   return luma > 0.5 ? Color.Black : Color.White;

注意:我去掉了luma值的反转(为了让鲜艳的颜色有更高的值,我觉得更自然,也是'默认'的计算方法。

我使用了与来自 here 的 GaceK 相同的常量,因为它们对我很有效。

(您也可以使用以下签名将其实现为Extension Method:

public static Color ContrastColor(this Color iColor)

然后您可以通过foregroundColor = background.ContrastColor() 调用它。)

【讨论】:

【参考方案6】:

我对 Gacek 答案的 Swift 实现:

func contrastColor(color: UIColor) -> UIColor 
    var d = CGFloat(0)

    var r = CGFloat(0)
    var g = CGFloat(0)
    var b = CGFloat(0)
    var a = CGFloat(0)

    color.getRed(&r, green: &g, blue: &b, alpha: &a)

    // Counting the perceptive luminance - human eye favors green color...
    let luminance = 1 - ((0.299 * r) + (0.587 * g) + (0.114 * b))

    if luminance < 0.5 
        d = CGFloat(0) // bright colors - black font
     else 
        d = CGFloat(1) // dark colors - white font
    

    return UIColor( red: d, green: d, blue: d, alpha: a)

【讨论】:

在 swift 中,由于 r/g/b 是 CGFloats,你不需要 "/255" 来计算亮度:让亮度 = 1 - ((0.299 * r) + (0.587 * g ) + (0.114 * b))【参考方案7】:

如果你不想写,那就是丑陋的 Python :)

'''
Input a string without hash sign of RGB hex digits to compute
complementary contrasting color such as for fonts
'''
def contrasting_text_color(hex_str):
    (r, g, b) = (hex_str[:2], hex_str[2:4], hex_str[4:])
    return '000' if 1 - (int(r, 16) * 0.299 + int(g, 16) * 0.587 + int(b, 16) * 0.114) / 255 < 0.5 else 'fff'

【讨论】:

【参考方案8】:

这是一个很有帮助的答案。谢谢!

我想分享一个 SCSS 版本:

@function is-color-light( $color ) 

  // Get the components of the specified color
  $red: red( $color );
  $green: green( $color );
  $blue: blue( $color );

  // Compute the perceptive luminance, keeping
  // in mind that the human eye favors green.
  $l: 1 - ( 0.299 * $red + 0.587 * $green + 0.114 * $blue ) / 255;
  @return ( $l < 0.5 );


现在正在研究如何使用算法为菜单链接自动创建悬停颜色。浅色标题悬停更暗,反之亦然。

【讨论】:

【参考方案9】:

谢谢@Gacek。这是适用于 android 的版本:

@ColorInt
public static int getContrastColor(@ColorInt int color) 
    // Counting the perceptive luminance - human eye favors green color...
    double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;

    int d;
    if (a < 0.5) 
        d = 0; // bright colors - black font
     else 
        d = 255; // dark colors - white font
    

    return Color.rgb(d, d, d);

还有一个改进的(更短的)版本:

@ColorInt
public static int getContrastColor(@ColorInt int color) 
    // Counting the perceptive luminance - human eye favors green color...
    double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
    return a < 0.5 ? Color.BLACK : Color.WHITE;

【讨论】:

如果您应用@Marcus Mangelsdorf 的更改(去掉1 - ... 部分并将a 重命名为luminance,它会更短且更易于阅读 使用第一个,您也可以捕获 alpha。【参考方案10】:

ios Swift 3.0(UIColor 扩展):

func isLight() -> Bool

    if let components = self.cgColor.components, let firstComponentValue = components[0], let secondComponentValue = components[1], let thirdComponentValue = components[2] 
        let firstComponent = (firstComponentValue * 299)
        let secondComponent = (secondComponentValue * 587)
        let thirdComponent = (thirdComponentValue * 114)
        let brightness = (firstComponent + secondComponent + thirdComponent) / 1000

        if brightness < 0.5
        
            return false
        else
            return true
        
      

    print("Unable to grab components and determine brightness")
    return nil

【讨论】:

函数按预期运行,但要小心 linting 和 force casts【参考方案11】:

Javascript [ES2015]

const hexToLuma = (colour) => 
    const hex   = colour.replace(/#/, '');
    const r     = parseInt(hex.substr(0, 2), 16);
    const g     = parseInt(hex.substr(2, 2), 16);
    const b     = parseInt(hex.substr(4, 2), 16);

    return [
        0.299 * r,
        0.587 * g,
        0.114 * b
    ].reduce((a, b) => a + b) / 255;
;

【讨论】:

【参考方案12】:

作为 Kotlin / Android 扩展:

fun Int.getContrastColor(): Int 
    // Counting the perceptive luminance - human eye favors green color...
    val a = 1 - (0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255
    return if (a < 0.5) Color.BLACK else Color.WHITE

【讨论】:

【参考方案13】:

也可以捕获 alpha 的 Android 版本。

(感谢@thomas-vos)

/**
 * Returns a colour best suited to contrast with the input colour.
 *
 * @param colour
 * @return
 */
@ColorInt
public static int contrastingColour(@ColorInt int colour) 
    // XXX https://***.com/questions/1855884/determine-font-color-based-on-background-color

    // Counting the perceptive luminance - human eye favors green color...
    double a = 1 - (0.299 * Color.red(colour) + 0.587 * Color.green(colour) + 0.114 * Color.blue(colour)) / 255;
    int alpha = Color.alpha(colour);

    int d = 0; // bright colours - black font;
    if (a >= 0.5) 
        d = 255; // dark colours - white font
    

    return Color.argb(alpha, d, d, d);

【讨论】:

【参考方案14】:

objective-c 的实现

+ (UIColor*) getContrastColor:(UIColor*) color 
    CGFloat red, green, blue, alpha;
    [color getRed:&red green:&green blue:&blue alpha:&alpha];
    double a = ( 0.299 * red + 0.587 * green + 0.114 * blue);
    return (a > 0.5) ? [[UIColor alloc]initWithRed:0 green:0 blue:0 alpha:1] : [[UIColor alloc]initWithRed:255 green:255 blue:255 alpha:1];

【讨论】:

你应该在这里添加一些描述,让其他用户知道你的代码发生了什么【参考方案15】:

我遇到了同样的问题,但我必须在 PHP 中开发它。我使用了@Garek 的solution,我也使用了这个答案: Convert hex color to RGB values in php 将 HEX 颜色代码转换为 RGB。

所以我要分享它。

我想在给定背景 HEX 颜色的情况下使用此函数,但并不总是从“#”开始。

//So it can be used like this way:
$color = calculateColor('#804040');
echo $color;

//or even this way:
$color = calculateColor('D79C44');
echo '<br/>'.$color;

function calculateColor($bgColor)
    //ensure that the color code will not have # in the beginning
    $bgColor = str_replace('#','',$bgColor);
    //now just add it
    $hex = '#'.$bgColor;
    list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
    $color = 1 - ( 0.299 * $r + 0.587 * $g + 0.114 * $b)/255;

    if ($color < 0.5)
        $color = '#000000'; // bright colors - black font
    else
        $color = '#ffffff'; // dark colors - white font

    return $color;

【讨论】:

【参考方案16】:

Swift 4 示例:

extension UIColor 

    var isLight: Bool 
        let components = cgColor.components

        let firstComponent = ((components?[0]) ?? 0) * 299
        let secondComponent = ((components?[1]) ?? 0) * 587
        let thirdComponent = ((components?[2]) ?? 0) * 114
        let brightness = (firstComponent + secondComponent + thirdComponent) / 1000

        return !(brightness < 0.6)
    


更新 - 发现0.6 是一个更好的查询测试平台

【讨论】:

这实际上在几种情况下很可能会失败,因为它假定一个 RGB 颜色空间。 CGColor.components 中的元素数量取决于颜色空间:例如,UIColor.white 在转换为 CGColor 时只有两个:[1.0, 1.0] 表示具有完整 alpha 的灰度(全白)颜色。提取 UIColor 的 RGB 元素的更好方法是 UIColor.getRed(_ red:, green:, blue:, alpha:)【参考方案17】:

Flutter 实现

Color contrastColor(Color color) 
  if (color == Colors.transparent || color.alpha < 50) 
    return Colors.black;
  
  double luminance = (0.299 * color.red + 0.587 * color.green + 0.114 * color.blue) / 255;
  return luminance > 0.5 ? Colors.black : Colors.white;

【讨论】:

我所做的只是加上'static'前缀。谢谢!【参考方案18】:

请注意,google closure library 中有一个用于此的算法,它引用了 w3c 建议:http://www.w3.org/TR/AERT#color-contrast。但是,在此 API 中,您提供了一个建议颜色列表作为起点。

/**
 * Find the "best" (highest-contrast) of the suggested colors for the prime
 * color. Uses W3C formula for judging readability and visual accessibility:
 * http://www.w3.org/TR/AERT#color-contrast
 * @param goog.color.Rgb prime Color represented as a rgb array.
 * @param Array<goog.color.Rgb> suggestions Array of colors,
 *     each representing a rgb array.
 * @return !goog.color.Rgb Highest-contrast color represented by an array.
 */
goog.color.highContrast = function(prime, suggestions) 
  var suggestionsWithDiff = [];
  for (var i = 0; i < suggestions.length; i++) 
    suggestionsWithDiff.push(
      color: suggestions[i],
      diff: goog.color.yiqBrightnessDiff_(suggestions[i], prime) +
          goog.color.colorDiff_(suggestions[i], prime)
    );
  
  suggestionsWithDiff.sort(function(a, b)  return b.diff - a.diff; );
  return suggestionsWithDiff[0].color;
;


/**
 * Calculate brightness of a color according to YIQ formula (brightness is Y).
 * More info on YIQ here: http://en.wikipedia.org/wiki/YIQ. Helper method for
 * goog.color.highContrast()
 * @param goog.color.Rgb rgb Color represented by a rgb array.
 * @return number brightness (Y).
 * @private
 */
goog.color.yiqBrightness_ = function(rgb) 
  return Math.round((rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000);
;


/**
 * Calculate difference in brightness of two colors. Helper method for
 * goog.color.highContrast()
 * @param goog.color.Rgb rgb1 Color represented by a rgb array.
 * @param goog.color.Rgb rgb2 Color represented by a rgb array.
 * @return number Brightness difference.
 * @private
 */
goog.color.yiqBrightnessDiff_ = function(rgb1, rgb2) 
  return Math.abs(
      goog.color.yiqBrightness_(rgb1) - goog.color.yiqBrightness_(rgb2));
;


/**
 * Calculate color difference between two colors. Helper method for
 * goog.color.highContrast()
 * @param goog.color.Rgb rgb1 Color represented by a rgb array.
 * @param goog.color.Rgb rgb2 Color represented by a rgb array.
 * @return number Color difference.
 * @private
 */
goog.color.colorDiff_ = function(rgb1, rgb2) 
  return Math.abs(rgb1[0] - rgb2[0]) + Math.abs(rgb1[1] - rgb2[1]) +
      Math.abs(rgb1[2] - rgb2[2]);
;

【讨论】:

【参考方案19】:

base@Gacek 得到luminance 的答案的R 版本(您可以轻松应用自己的阈值)

# vectorized
luminance = function(col) c(c(.299, .587, .114) %*% col2rgb(col)/255)

用法:

luminance(c('black', 'white', '#236FAB', 'darkred', '#01F11F'))
# [1] 0.0000000 1.0000000 0.3730039 0.1629843 0.5698039

【讨论】:

【参考方案20】:

基于Gacek's answer,并在使用WAVE 浏览器扩展分析@WebSeed's example 之后,我想出了以下版本,它根据对比度选择黑色或白色文本(如W3C 的Web Content Accessibility Guidelines (WCAG) 2.1 中定义的那样) ),而不是亮度。

这是代码(在 javascript 中):

// As defined in WCAG 2.1
var relativeLuminance = function (R8bit, G8bit, B8bit) 
  var RsRGB = R8bit / 255.0;
  var GsRGB = G8bit / 255.0;
  var BsRGB = B8bit / 255.0;

  var R = (RsRGB <= 0.03928) ? RsRGB / 12.92 : Math.pow((RsRGB + 0.055) / 1.055, 2.4);
  var G = (GsRGB <= 0.03928) ? GsRGB / 12.92 : Math.pow((GsRGB + 0.055) / 1.055, 2.4);
  var B = (BsRGB <= 0.03928) ? BsRGB / 12.92 : Math.pow((BsRGB + 0.055) / 1.055, 2.4);

  return 0.2126 * R + 0.7152 * G + 0.0722 * B;
;

var blackContrast = function(r, g, b) 
  var L = relativeLuminance(r, g, b);
  return (L + 0.05) / 0.05;
;

var whiteContrast = function(r, g, b) 
  var L = relativeLuminance(r, g, b);
  return 1.05 / (L + 0.05);
;

// If both options satisfy AAA criterion (at least 7:1 contrast), use preference
// else, use higher contrast (white breaks tie)
var chooseFGcolor = function(r, g, b, prefer = 'white') 
  var Cb = blackContrast(r, g, b);
  var Cw = whiteContrast(r, g, b);
  if(Cb >= 7.0 && Cw >= 7.0) return prefer;
  else return (Cb > Cw) ? 'black' : 'white';
;

在@WebSeed 的codepen 的my fork 中可以找到一个工作示例,它在WAVE 中产生零低对比度错误。

【讨论】:

【参考方案21】:

我会评论@MichaelChirico 的answer,但我没有足够的声誉。因此,这是 R 中返回颜色的示例:

get_text_colour <- function(
    background_colour,
    light_text_colour = 'white',
    dark_text_colour = 'black',
    threshold = 0.5
) 

    background_luminance <- c( 
        c( .299, .587, .114 ) %*% col2rgb( background_colour ) / 255
    )

    return(
        ifelse(
            background_luminance < threshold,
            light_text_colour,
            dark_text_colour
        )
    )

> get_text_colour( background_colour = 'blue' )
[1] "white"

> get_text_colour( background_colour = c( 'blue', 'yellow', 'pink' ) )
[1] "white" "black" "black"

> get_text_colour( background_colour = c('black', 'white', '#236FAB', 'darkred', '#01F11F') )
[1] "white" "black" "white" "white" "black"

【讨论】:

【参考方案22】:

简答:

计算给定颜色的亮度 (Y),并根据预先确定的中间对比度图形将文本翻转为黑色或白色。对于典型的 sRGB 显示器,当 Y

更长的答案

毫不奇怪,这里的几乎每个答案都存在一些误解,和/或引用了不正确的系数。唯一真正接近的答案是 Seirios,尽管它依赖于 WCAG 2 的对比度,而这本身就是不正确的。

如果我说“不足为奇”,部分原因是互联网上有大量关于这个特定主题的错误信息。事实上,这个领域仍然是一个积极研究的主题,而悬而未决的科学则增加了乐趣。我得出这个结论是最近几年对一种新的对比度预测方法的可读性研究的结果。

视觉感知领域是密集而抽象的,也是发展中的,因此存在误解是很常见的。例如,HSV 和 HSL 甚至都不是接近感知准确的。为此,您需要一个感知统一的模型,例如 CIELAB 或 CIELUV 或 CIECAM02 等。

一些误解甚至进入了标准,例如 WCAG 2 (1.4.3) 的对比部分,该部分已被证明在其大部分范围内都是不正确的。

第一次修复:

这里的许多答案中显示的系数是 (.299, .587, .114) 并且是错误的,因为它们与几十年前北美的模拟广播系统 NTSC YIQ 有关。虽然它们可能仍用于某些 YCC 编码规范以实现向后兼容性,但不应在 sRGB 上下文中使用它们

sRGB 和 Rec.709 (HDTV) 的系数为:

红色:0.2126 绿色:0.7152 蓝色:0.0722

Rec2020 或 Adob​​eRGB 等其他色彩空间使用不同的系数,对于给定的色彩空间使用正确的系数非常重要。

系数不能直接应用于 8 位 sRGB 编码图像或颜色数据。编码数据必须首先被线性化,然后应用系数来找到给定像素或颜色的亮度(光值)。

对于 sRGB 有一个分段变换,但由于我们只对感知的明度对比度感兴趣以找到将文本从黑色“翻转”为白色的点,因此我们可以通过简单的 gamma 方法走捷径。

安迪的亮度和亮度捷径

将每种 sRGB 颜色除以 255.0,然后提高到 2.2 的幂,然后乘以系数并将它们相加,得到估计的亮度。

 let Ys = Math.pow(sR/255.0,2.2) * 0.2126 +
          Math.pow(sG/255.0,2.2) * 0.7152 +
          Math.pow(sB/255.0,2.2) * 0.0722; // Andy's Easy Luminance for sRGB. For Rec709 HDTV change the 2.2 to 2.4

这里,Y 是 sRGB 显示器的相对亮度,范围为 0.0 到 1.0。但这与感知无关,我们需要进一步变换以适应我们人类对相对亮度的视觉感知,以及感知到的对比度。

40% 翻转

但在我们到达那里之前,如果您只是在寻找一个基本点来将文本从黑色翻转为白色或反之亦然,那么作弊就是使用 Y 我们刚刚推导出来,并提出了关于Y = 0.40; 的转折点。因此,对于高于 0.4 Y 的颜色,将文本设为黑色 #000,对于低于 0.4 Y 的颜色,将文本设为白色 #fff

  let textColor = (Ys < 0.4) ? "#fff" : "#000"; // Low budget down and dirty text flipper.

为什么是 40% 而不是 50%?我们人类对明暗和对比度的感知不是线性的。对于自发光显示器,在大多数典型条件下,0.4 Y 恰好是中等对比度。

是的,它会有所不同,是的,这是一种过度简化。但是,如果您要将文本翻转为黑色或白色,那么简单的答案会很有用。

感知奖励回合

预测对给定颜色和亮度的感知仍然是一个积极研究的主题,而不是完全确定的科学。 CIELAB 或 LUV 的 L* (Lstar) 已被用于预测感知亮度,甚至预测感知对比度。但是,L* 适用于非常明确/受控环境中的表面颜色,但不适用于自发光显示器。

虽然这不仅取决于显示类型和校准,还取决于您的环境和整个页面内容,但如果您从上方取 Y,并将其提高 ^0.685 到 ^0.75 左右,您会发现0.5 通常是将文本从白色翻转为黑色的中间点。

  let textColor = (Math.pow(Ys,0.75) < 0.5) ? "#fff" : "#000"; // perceptually based text flipper.

使用指数 0.685 将使文本颜色交换为较深的颜色,使用 0.8 将使文本交换为较浅的颜色。

空间频率双倍奖励回合

请注意,对比度不仅仅是两种颜色之间的距离。空间频率,也就是字体粗细和大小,也是不容忽视的关键因素。

也就是说,您可能会发现,当颜色处于中间范围时,您会想要增加字体的大小和/或粗细。

  let textSize = "16px";
  let textWeight = "normal"; 
  let Ls = Math.pow(Ys,0.7);

  if (Ls > 0.33 && Ls < 0.66) 
      textSize = "18px";
      textWeight = "bold";
        // scale up fonts for the lower contrast mid luminances.

Hue R U

深入研究超出了本文的范围,但以上我们忽略了色调和色度。色相和色度确实会产生影响,例如 Helmholtz Kohlrausch,并且上述更简单的亮度计算并不总能预测饱和色调导致的强度。

为了预测感知的这些更微妙的方面,需要一个完整的外观模型。如果您想深入人类视觉感知的兔子洞,R. Hunt、M. Fairshild、E. Burns 是几位值得研究的作者...

为了这个狭隘的目的,我们可以稍微重新加权系数,因为绿色占亮度的大部分,纯蓝色和纯红色应该始终是两种颜色中最暗的。使用标准系数往往会发生的情况是,具有大量蓝色或红色的中间颜色可能会在低于理想亮度时变为黑色,而具有高绿色分量的颜色可能会发生相反的情况。

也就是说,我发现最好通过增加中间颜色的字体大小和粗细来解决这个问题。

把它们放在一起

因此我们假设您将向此函数发送一个十六进制字符串,它会返回一个可以发送到特定 html 元素的样式字符串。

Check out the CODEPEN,灵感来自 Seirios 所做的:

CodePen: Fancy Font Flipping

Codepen 代码所做的其中一件事是为较低对比度的中档增加文本大小。这是一个示例:

如果您想尝试其中的一些概念,请访问 SAPC 开发站点https://www.myndex.com/SAPC/,点击“研究模式”可提供交互式实验来演示这些概念。

启蒙条款

亮度: Y(相对)或 L(绝对 cd/m2)一种光谱加权但线性的光量度。不要与“亮度”混淆。

光度:随时间变化的光,在天文学中很有用。

亮度: L* (Lstar) 由 CIE 定义的感知亮度。某些型号具有相关的亮度 J*

【讨论】:

以上是关于根据背景颜色确定字体颜色的主要内容,如果未能解决你的问题,请参考以下文章

webstorm怎么设置背景颜色

如何根据字体颜色选择背景颜色以获得适当的对比度

根据背景颜色反转 CSS 字体颜色

如何根据背景颜色决定字体颜色为白色还是黑色?

s-s-rS 根据背景颜色设置字体颜色

xshell如何设置字体和背景色颜色?