在Ruby中基于背景色反转前色(文本颜色)

时间:2019-03-24 09:52:24

标签: ruby

我想根据Ruby中的背景颜色hex选择一种文本颜色。例如:

用户输入了这种背景色:

color1

然后预期的文本颜色应为白色#FFFFFF(白色)。

如果用户选择与此类似的内容:

color2

然后预期的文本颜色应为#000000(黑色)

我知道这是可能的,并且我发现其他语言(例如JavaScript或c#)的相似代码示例,但它们均基于RGB。我无法移植到红宝石中的HEX

2 个答案:

答案 0 :(得分:1)

我已经设法与自己做一个。如果这有误,请纠正我,否则可能导致特定颜色的结果出乎意料。

def colorize(hex)
    r = hex[0..1].to_i(16)
    g = hex[2..3].to_i(16)
    b = hex[4..5].to_i(16)
    c = ((r*299)+(g*587)+(b*114))/1000
    (c >= 128) ? :black : :white
end


puts colorize '668899'
# => :white 
puts colorize 'ffefe8'
# => :black

答案 1 :(得分:1)

Pratha,我采取了与您相同的方法;我对计算的组织方式略有不同。

W3C已经制定了perceived brightness of any colour(299*r + 114*b + 587*g)/1000的度量标准,其中rbg分别在00xFF。发现最大值为255

我们可以定义一种将颜色亮度表示为白色亮度的一部分的方法:

WHITE_BRIGHT = 299*0xFF + 114*0xFF + 587*0xFF
  #=> 255000

def brightness(rbg)
  rb,g = rbg.divmod(0x100)
  r,b  = rb.divmod(0x100)
  (299*r + 114*b + 587*g).fdiv(WHITE_BRIGHT)
end

brightness 0         #=> 0.0 
brightness 0xFFFFFF  #=> 1.0 
brightness 0x668899  #=> 0.5326 
brightness 0xFFEFF8  #=> 0.9767... 
brightness 0x1F223F  #=> 0.1965... 

请参见Integer#divmod(一种非常有用的方法)和Integer#fdiv

我们只需选择背景颜色以最大化前景和背景亮度之间的差异。显然是黑色还是白色,具体取决于brightness(rgb)是否大于0.5

def background(rbg)
  brightness(rbg) > 0.5 ? 0 : 0xFFFFFF
end

background(0).to_s(16)         #=> "ffffff" 
background(0xFFFFFF).to_s(16)  #=> "0" 
background(0x668899).to_s(16)  #=> "0" 
background(0xFFEFF8).to_s(16)  #=> "0" 
background(0x1F223F).to_s(16)  #=> "ffffff"