簡體   English   中英

R 中的顏色對比度檢查器,用於 2 種以上顏色

[英]Colour contrast checker in R for more than 2 colours

我正在嘗試一種可重現的方法來計算網頁上圖形的各種顏色的顏色對比度。 我發現了以下 function: https://rdrr.io/github/m-clark/visibly/src/R/color_contrast_checker.ZE1E1D3D40573127E3DZE0480CAF128之間的比較,這正是我想要的。

我希望能夠給這個 function 一個前景色和背景色,它們是可以循環通過的有效十六進制代碼列表,因此 function 計算兩個列表中所有顏色的所有組合的顏色對比度。 我試圖給 function 一個 dataframe 中的顏色列表,並使用 for 循環重復 function 幾次但沒有運氣。 我認為 function 的設計不能采用超過 1 個元素,即 1x 前景色和 1x 背景色,但我對 R 中的函數和循環有點陌生。 有誰知道我怎么能做到這一點謝謝?

以下是沒有成功的示例代碼:

library(gplots)  
library(jsonlite)
library(dplyr)

background_col_list<-as.character(c("#6A86B8","#DFE3EB","#E57D3A","#BBB332"))
foreground_col_list<-as.character(c("#6A86B8","#DFE3EB","#E57D3A","#BBB332")) 

result.df <- expand.grid(as.character(foreground_col_list),as.character(background_col_list))

result.df<-result.df %>%
  mutate_all(as.character)

color_contrast_checker <- function(foreground, background) {
  
  #initial checks

  if ((is.null(foreground) | rlang::is_empty(foreground)) |
      (is.null(background) | rlang::is_empty(background)))
    stop('Need both foreground and background colors')
  
  if (!is.character(foreground) | !is.character(background))
    stop(strwrap('Elements must be character string as a named R color or
         hex (e.g. "#ffffff")'))
  
  #note: alpha returned by col2hex will be ignored         
     
  if (foreground %in% colors()){
    foreground <- col2hex(foreground)
  } else {
    if (!nchar(foreground) %in% c(7, 9) | !grepl('^#', foreground))
      stop(strwrap('foreground must be an R color, e.g. see colors(),
                   or a hex of the form #ff5500'))
  }
  
  if (background %in% colors()) {
    background <- col2hex(background)
  } else {
    if (!nchar(background) %in% c(7, 9) | !grepl('^#', background))
      stop(strwrap('background must be an R color, e.g. see colors(),
                   or a hex of the form #ff5500'))
  }
  
  #remove pound sign

  foreground <- substr(foreground, start = 2, stop = nchar(foreground))
  background <- substr(background, start = 2, stop = nchar(background))
  
  url <- paste0('https://webaim.org/resources/contrastchecker/?fcolor=',
                foreground,
                '&bcolor=',
                background,
                '&api')
  
  result <- suppressWarnings({readLines(url)})
  
  if (!requireNamespace('jsonlite', quietly = TRUE)) {
    result <- strsplit(
      gsub(result, pattern = '\\{|\\}|\"', replacement = ''),
      ',')
    return(result[[1]])
  }
  
data.frame(jsonlite::fromJSON(result))
  
}


for (value in result.df) {
  
  color_contrast_checker(foreground=result.df$Var1, background=result.df$Var2) #Var1 & Var2 column names of result.df df that contains list of hex codes 

}


#Have also tried:

for (i in 1:length(unique(background_col_list))) {
  
  color_contrast_checker(background_col_list, foreground_col_list) 
  
}

基礎 R 中最簡單的選項是results = apply(result.df, 1, function(x) color_contrast_checker(x[1], x[2])) ,然后您可以將其轉換為更具可讀性的 output (例如do.call(rbind, results) )。

然而,這個 function 有點慢 - 你可以在 R 中很容易地自己實現檢查。

首先,我們檢查 W3C 使用什么作為對比度

對比度 (L1 + 0.05) / (L2 + 0.05),其中

  • L1是colors的打火機的相對亮度,和
  • L2 是 colors 較暗的相對亮度。

然后我們檢查 W3C 定義的相對亮度

對於 sRGB 顏色空間,顏色的相對亮度定義為 L = 0.2126 * R + 0.7152 * G + 0.0722 * B

因此,此時您需要做的就是計算每種顏色的相對亮度,然后計算它們的比率,並檢查它們是否通過任何所需的閾值:

WCAG 2.0 AA 級要求普通文本的對比度至少為 4.5:1,大文本的對比度至少為 3:1。 WCAG 2.1 要求圖形和用戶界面組件(例如表單輸入邊框)的對比度至少為 3:1。 WCAG AAA 級要求普通文本的對比度至少為 7:1,大文本的對比度至少為 4.5:1。

在代碼中:

# Transform colors to RGB values, and RGB values to relative luminance

result.df$L_background = apply(col2rgb(result.df[,1]), 2, function(x) 
0.2126 * x[1] + 0.7152 * x[2] + 0.0722 * x[3])

result.df$L_foreground = apply(col2rgb(result.df[,2]), 2, function(x) 
0.2126 * x[1] + 0.7152 * x[2] + 0.0722 * x[3])

# Apply the contrast ratio formula (max luminance is brighter, min is darker)

result.df$L_ratio =  apply(result.df[,3:4], 1, function(x) 
(max(x) + 0.05)/(min(x) + 0.05))

# Check against standard thresholds
result.df$WCAG2_0_AA_pass = result.df$L_ratio > 4.5
result.df$WCAG2_1_pass = result.df$L_ratio > 3
result.df$WCAG_AAA_pass = result.df$L_ratio > 7

對於不大的支票,這相對較快。 某處可能存在矢量化解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM