9

可能重复:
PHP 中颜色之间的“距离”

我想检测 RGB 值是否是某种粉红色。我不确定如何进行此操作,因为似乎没有一系列 RGB 或十六进制值遵循粉红色的线性顺序(一种粉红色是255, 182, 193; #FFB6C1,而另一种是238, 162, 173; #EEA2AD)。假设我知道我的范围的开始和结束 RGB/十六进制值,你知道该怎么做吗?

4

1 回答 1

15

它对我来说看起来相当线性。但是,您需要了解一些色彩理论。

在回答您的问题之前,我希望您不介意我在此处包含一个简单的色彩理论复习。但它有助于理解或制定任何解决方案。

首先,我相信大多数人都会记得他们在幼儿园学过的色轮:

                                          Red
       Red                        Orange   |   Purple
        |                                \_|_/
       _o_        ---------->             _o_
      /   \                              / | \
  Yellow   Blue                   Yellow   |   Blue
                                         Green

好吧,我们需要稍微修改一下。因为事实证明,红色和蓝色并不是真正的原色,因为您可以通过将洋红色和黄色混合来获得红色,并且可以通过将青色和一点红色混合来获得蓝色。所以修改后的色轮使用印刷颜色:CMY:

        Magenta
     Red   |   Blue
         \_|_/
          _o_
         / | \
  Yellow   |   Cyan
         Green

这基本上是 HSV 颜色空间(S 通常从轮子的中心绘制到边缘,而 V 根本不绘制,但通常可以通过滑块更改)。它源自印刷颜色 CMY。那么这如何帮助我们处理屏幕颜色 RGB 呢?

好吧,如果您仔细观察它,您会发现它实际上是印刷和屏幕色彩空间的组合。它实际上描绘了CMY和RGB之间的关系:

        Magenta                 Magenta
     Red   |   Blue                |           Red     Blue
         \_|_/                     |              \_ _/
          _o_            ==       _o_       +       o
         / | \                   /   \              |
  Yellow   |   Cyan         Yellow    Cyan          |
         Green                                    Green

所以,任何RGB颜色都可以通过理解这个色轮来理解。例如,RGB 中没有黄色。但请注意,黄色与蓝色相反。因此,要获得黄色,请从颜色中减去蓝色:

rgb(100,80,10)  is a "yellowish" version of rgb(100,80,120)
            ^                                           ^

一旦你理解了这个使用 RGB 值的色轮就更有意义了。通过足够的练习,您可以直接在#rrggbb语法中组合和编辑颜色,而无需参考颜色图表。

所以,回答你的问题。假设你的目标粉红色是:

rgb(255,182,193)

关于“粉红色”,我们知道两件事:

  1. 我们认为它是一种红色。因此,目标颜色具有较高的红色值(实际上是最大值)是有道理的。

  2. 我们认为它是一种非常浅的红色。因此,非红色分量也相当高(均高于 150)是有道理的。

因此,要获得接近目标颜色的色调,我们需要:

  1. R值明显高于G或B。
  2. 所有值都相当高(超过 150 左右)。

根据这个定义,我们可以将粉色识别为:

// Pseudo code:

is_pink (R,G,B) {
    return R > 200 &&  // make sure R is high
           G > 150 &&  // make sure G & B are relatively high
           B > 150 &&
           R > G &&    // make sure G & B are not higher than R
           R > B;
}

通过确保 G 和 B 非常相似,我们可以添加另一个条件来拒绝略带蓝色或绿色的“粉红色”:

// Pseudo code:

is_pink (R,G,B) {
    return R > 200 &&
           G > 150 &&
           B > 150 &&
           R > G &&
           R > B &&
           abs(G-B) < 20; // make sure it's neither bluish or greenish
}

您可以调整值 200、150 和 20 以适应您对粉红色的品味,但您会看到,如果我们将上述函数应用于您的测试颜色(255,182,193)(238,162,173)它们都会被识别为“粉红色”。

于 2012-11-23T02:58:21.563 回答