检查字符串是不是是有效的颜色表示

Posted

技术标签:

【中文标题】检查字符串是不是是有效的颜色表示【英文标题】:Check if character string is a valid color representation检查字符串是否是有效的颜色表示 【发布时间】:2022-01-17 03:58:05 【问题描述】:

简短的问题,如果我有一个字符串,我如何测试该字符串是否是R 中的有效颜色表示?

我尝试了两件事,首先使用函数col2rgb()来测试它是否是一种颜色:

isColor <- function(x)

  res <- try(col2rgb(x),silent=TRUE)
  return(!"try-error"%in%class(res))


> isColor("white")
[1] TRUE
> isColor("#000000")
[1] TRUE
> isColor("foo")
[1] FALSE

有效,但看起来不是很漂亮并且没有矢量化。第二件事是检查字符串是否在 colors() 向量或 # 后跟长度为 4 到 6 的十六进制数:

isColor2 <- function(x)

  return(x%in%colors() | grepl("^#(\\d|[a-f])6,8$",x,ignore.case=TRUE))


> isColor2("white")
[1] TRUE
> isColor2("#000000")
[1] TRUE
> isColor2("foo")
[1] FALSE

虽然我不确定它的稳定性如何,但它确实有效。但似乎应该有一个内置函数来做这个检查?

【问题讨论】:

我想在Rgames&gt; plot(1,2,col='phlogiston') Error in plot.xy(xy, type, ...) : invalid color name 'phlogiston' 上做trycatch 没有帮助:-) 抱歉 - SO 超时让我在编辑过程中遇到了问题。函数的选择取决于你想用它做什么。抛出一个错误是否足够(plot 已经这样做了),还是你想“修复”一个错误的颜色规范?如果是后者,你将不得不滚动你自己的函数,基于你认为正确的校正算法 您可能有字母数字。 isColor( "#00000000" ) 应该返回 TRUE @Romain yes 应该是 6 到 8 位,改了。 @Carl我喜欢非常灵活的函数参数。例如。 color 参数,可以分配颜色以直接使用该颜色,或 TRUE 使用某种算法来定义颜色,或 FALSE 省略它。 正如加文的回答和评论所表明的那样,您正在走#FFFFFFCC 路径。为了比较,您认为将参数解析为任意函数以确保所述参数名称存在于当前环境中是否明智? (我希望答案是“否”。)此外,如果你有一个变量 my_colors&lt;-c('red','blue','boogersnot') 怎么办?调用plot(x,y,col=my_colors) 是否出错? 【参考方案1】:

您的第一个想法(使用col2rgb() 为您测试颜色名称的有效性)对我来说似乎很好,只需要矢量化。至于它看起来是否漂亮……很多/大多数 R 函数在“幕后”并不是特别漂亮,这是首先创建函数的主要原因!对用户隐藏所有那些丑陋的内部结构。

一旦你在下面定义了areColors(),使用它就很简单了:

areColors <- function(x) 
     sapply(x, function(X) 
         tryCatch(is.matrix(col2rgb(X)), 
                  error = function(e) FALSE)
         )
     

areColors(c(NA, "black", "blackk", "1", "#00", "#000000"))
#   <NA>   black  blackk       1     #00 #000000 
#   TRUE    TRUE   FALSE    TRUE   FALSE    TRUE 

【讨论】:

vapply 会更好,因为当输入长度为 0 时它会返回更好的响应。【参考方案2】:

更新,鉴于编辑

?par 详细描述了在 R 中可以指定颜色的方式。任何解决有效颜色的方法都必须考虑:

    colors() 中列出的 命名 颜色 "#RRGGBBAA 形式的十六进制表示形式,用于指定红色、绿色、蓝色和 Alpha 通道。 Alpha 通道用于透明度,并非所有设备都支持,因此虽然使用 8 个十六进制值以这种方式指定颜色是有效的,但它在特定设备上可能无效。 NA 是有效的“颜色”。它表示透明,但就 R 而言,它是一种有效的颜色表示。 同样"transparent"也有效,但在colors()中无效,所以也需要处理

    1 是一种有效的颜色表示,因为它是palette() 返回的小调色板中颜色的索引

    > palette()
    [1] "black"   "red"     "green3"  "blue"    "cyan"    "magenta" "yellow" 
    [8] "gray"
    

    因此您需要处理1:8。为什么这很重要,?par 告诉我们将这些颜色的索引表示为字符也是有效的,因此您需要捕获 "1" 作为有效的颜色表示。但是(正如 @hadley 在 cmets 中所指出的那样)这 只是 用于默认调色板。用户可能会使用另一个调色板,在这种情况下,您将不得不考虑对您的 R 版本允许的最大长度的向量元素的字符索引。

一旦你处理了所有这些你应该好好去;-)

据我所知,没有用户可见的功能可以做到这一点。所有这些都隐藏在执行绘图的 C 代码中;很快你就会到达.Internal(....) 土地,那里有龙!


原创

[迂腐#000000不是 R.中的颜色名称]

names R 知道的唯一颜色是 colors() 返回的颜色。是的,#000000 是 R 理解的颜色表示之一,但您特别询问了名称,最终列表或解决方案是 x %in% colors(),就像您在第二个示例中一样。

这几乎是稳定的。当您使用col = "goldenrod" 之类的颜色时,R 在内部将其与您正在绘制的任何设备的颜色的“正确”表示相匹配。 color() 返回 R 可以查找的颜色名称列表。如果它不在colors() 中,则它不是颜色名称。

【讨论】:

你是对的。我更改了标题/问题以表明我正在寻找有效的表示,因此包括#000000 等。 在这种情况下,技术上"3" 也是一种颜色,浅绿色。 @GavinSimpson 仅使用默认调色板。 @GavinSimpson 你不会比 OP 使用col2rgb 并检查错误的第一个想法做得更好。那就是说col2rgb 的C source code 并不算太可怕,并揭示了另一种情况:col2rgb(0) 为您提供了情节的背景颜色。 是的,我同意,这也是我要使用的。

以上是关于检查字符串是不是是有效的颜色表示的主要内容,如果未能解决你的问题,请参考以下文章

找到最相似值的有效方法

vscode中的颜色代码怎样记忆最有效

使用位深度来确定 BMP 图像中颜色表的大小是不是有效?

检查颜色是不是接近

Java JTable改变单元格颜色

VueJS/Vuetify v-for 中的不同颜色芯片,检查带有参数的对象:使用点表示法的颜色