【问题标题】:How to generate random 'greenish' colors如何生成随机的“绿色”颜色
【发布时间】:2010-12-07 20:29:18
【问题描述】:

有人对如何使随机颜色全为绿色有任何建议吗?现在我正在通过这个生成颜色:

color = (randint(100, 200), randint(120, 255), randint(100, 200))

这主要是有效的,但我得到了很多棕色的颜色。

【问题讨论】:

  • 被推荐为我在这里见过的最随机的问题!)

标签: python language-agnostic random colors


【解决方案1】:

简单的解决方案:使用HSL or HSV 色彩空间 而不是 rgb(如果需要,之后将其转换为 RGB)。区别在于元组的含义:其中 RGB 表示红色、绿色和蓝色的值,在 HSL 中,H 是颜色(例如 120 度或 0.33 表示绿色),S 表示饱和度,V 表示亮度。因此,将 H 保持在固定值(或者对于更多随机颜色,您可以通过添加/减去一个小的随机数来随机化它)并随机化 S 和 V。请参阅wikipedia 文章。

【讨论】:

    【解决方案2】:

    正如其他人所建议的,在 HSV 颜色空间(或 HSL,差异与此无关)中生成随机颜色要容易得多

    因此,生成随机“绿色”颜色的代码,并(出于演示目的)将它们显示为一系列简单的彩色 HTML 跨度标签:

    #!/usr/bin/env python2.5
    """Random green colour generator, written by dbr, for
    http://stackoverflow.com/questions/1586147/how-to-generate-random-greenish-colors
    """
    
    def hsv_to_rgb(h, s, v):
        """Converts HSV value to RGB values
        Hue is in range 0-359 (degrees), value/saturation are in range 0-1 (float)
    
        Direct implementation of:
        http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_HSV_to_RGB
        """
        h, s, v = [float(x) for x in (h, s, v)]
    
        hi = (h / 60) % 6
        hi = int(round(hi))
    
        f = (h / 60) - (h / 60)
        p = v * (1 - s)
        q = v * (1 - f * s)
        t = v * (1 - (1 - f) * s)
    
        if hi == 0:
            return v, t, p
        elif hi == 1:
            return q, v, p
        elif hi == 2:
            return p, v, t
        elif hi == 3:
            return p, q, v
        elif hi == 4:
            return t, p, v
        elif hi == 5:
            return v, p, q
    
    def test():
        """Check examples on..
        http://en.wikipedia.org/wiki/HSL_and_HSV#Examples
        ..work correctly
        """
        def verify(got, expected):
            if got != expected:
                raise AssertionError("Got %s, expected %s" % (got, expected))
    
        verify(hsv_to_rgb(0, 1, 1), (1, 0, 0))
        verify(hsv_to_rgb(120, 0.5, 1.0), (0.5, 1, 0.5))
        verify(hsv_to_rgb(240, 1, 0.5), (0, 0, 0.5))
    
    def main():
        """Generate 50 random RGB colours, and create some simple coloured HTML
        span tags to verify them.
        """
        test() # Run simple test suite
    
        from random import randint, uniform
    
        for i in range(50):
            # Tweak these values to change colours/variance
            h = randint(90, 140) # Select random green'ish hue from hue wheel
            s = uniform(0.2, 1)
            v = uniform(0.3, 1)
    
            r, g, b = hsv_to_rgb(h, s, v)
    
            # Convert to 0-1 range for HTML output
            r, g, b = [x*255 for x in (r, g, b)]
    
            print "<span style='background:rgb(%i, %i, %i)'>&nbsp;&nbsp;</span>" % (r, g, b)
    
    if __name__ == '__main__':
        main()
    

    输出(在网络浏览器中查看时)应类似于以下内容:

    编辑:我不知道 colorsys 模块。代替上面的hsv_to_rgb 函数,您可以使用colorsys.hsv_to_rgb,这使得代码更短(它不是一个直接替代,因为我的hsv_to_rgb 函数期望色调以度数而不是0-1 ):

    #!/usr/bin/env python2.5
    from colorsys import hsv_to_rgb
    from random import randint, uniform
    
    for x in range(50):
        h = uniform(0.25, 0.38) # Select random green'ish hue from hue wheel
        s = uniform(0.2, 1)
        v = uniform(0.3, 1)
    
        r, g, b = hsv_to_rgb(h, s, v)
    
        # Convert to 0-1 range for HTML output
        r, g, b = [x*255 for x in (r, g, b)]
    
        print "<span style='background:rgb(%i, %i, %i)'>&nbsp;&nbsp;</span>" % (r, g, b)
    

    【讨论】:

      【解决方案3】:

      查看colorsys 模块:

      http://docs.python.org/library/colorsys.html

      使用 HSL 或 HSV 颜色空间。将色调随机化为接近绿色,然后为饱和度和 V(亮度)选择完全随机的东西。

      【讨论】:

      • 完全随机选择饱和度和亮度将包括纯黑色和白色作为可能的结果。
      • 如果我能接受 2 个答案,我也会接受这个。谢谢。
      • 您可以选择 0.2 到 1 之间的随机值来获得饱和度和值,而不会看起来太糟糕(至少在 HTML 中)
      • @wcoenen:这完全取决于 Echo 对“绿色”的定义。也许色调需要非常窄,或者更宽一点的定义是好的。但主要是在其中获取色彩空间转换代码,以便可以使用数字。 @Echo:顺便说一句,您可能还想尝试使用直线随机函数以外的东西。像 random.normalvariate 这样的东西。但这并不能真正提供一个好的截止点来确保每种输出颜色都是绿色(尽管大多数都是绿色)......嗯。
      【解决方案4】:

      如果你坚持使用 RGB,你基本上只需要确保 G 值大于 R 和 B,并尽量保持蓝色和红色值相似,这样色调就不会太疯狂。从 Slaks 扩展,可能类似于(我对 Python 几乎一无所知):

      greenval = randint(100, 255)
      redval = randint(20,(greenval - 60))
      blueval = randint((redval - 20), (redval + 20))
      color = (redval, greenval, blueval)
      

      【讨论】:

      【解决方案5】:

      因此,在这种情况下,您很幸运希望原色发生变化,但对于这样的艺术用途,最好指定色轮坐标而不是原色幅度。

      你可能想要来自colorsys 模块的东西,比如:

      colorsys.hsv_to_rgb(h, s, v)
          Convert the color from HSV coordinates to RGB coordinates.
      

      【讨论】:

        【解决方案6】:

        具有 HSx 色彩空间的解决方案是一个非常好的解决方案。但是,如果您需要一些非常简单的东西并且对颜色的分布没有特定要求(如均匀性),那么基于 RGB 的简单解决方案就是确保 G 值大于 R 和 B

        rr = randint(100, 200)
        rb = randint(100, 200)
        rg = randint(max(rr, rb) + 1, 255)
        

        这会给你“绿色”的颜色。其中一些会变得如此微绿。您可以通过增加(绝对或相对)最后一次randint 调用中的下限来增加保证的绿色程度。

        【讨论】:

        • 您的代码中有一个拼写错误,rg = randint(max(rg ...,Python 不需要显式的行终止分号!
        【解决方案7】:

        您想要的是使用HSL 而不是RGB。您可以找到一系列满足“绿色”的色调并从中选择一种随机色调。您也可以选择随机饱和度和亮度,但您可能希望将饱和度保持在 1 附近,将亮度保持在 0.5 左右,但您可以使用它们。

        下面是一些将 HSL 转换为 RGB 的动作脚本代码。好久没碰python了,不然会贴出python版本的。

        我发现绿色大概是 0.47*PI 到 0.8*PI。

            /**
        @param h hue [0, 2PI]
        @param s saturation [0,1]
        @param l lightness [0,1]
        @return object {r,g,b} {[0,1],[0,1][0,1]}
        */
        public function hslToRGB(h:Number, s:Number, l:Number):Color
        {
            var q:Number = (l<0.5)?l*(1+s):l+s-l*s;
            var p:Number = 2*l-q;
            var h_k:Number = h/(Math.PI*2);
            var t_r:Number = h_k+1/3;
            var t_g:Number = h_k;
            var t_b:Number = h_k-1/3;
            if (t_r < 0) ++t_r; else if (t_r > 1) --t_r;
            if (t_g < 0) ++t_g; else if (t_g > 1) --t_g;
            if (t_b < 0) ++t_b; else if (t_b > 1) --t_b;
            var c:Color = new Color();
            if (t_r < 1/6) c.r = p+((q-p)*6*t_r);
            else if (t_r < 1/2) c.r = q;
            else if (t_r < 2/3) c.r = p+((q-p)*6*(2/3-t_r));
            else c.r = p;
            if (t_g < 1/6) c.g = p+((q-p)*6*t_g);
            else if (t_g < 1/2) c.g = q;
            else if (t_g < 2/3) c.g = p+((q-p)*6*(2/3-t_g));
            else c.g = p;
            if (t_b < 1/6) c.b = p+((q-p)*6*t_b);
            else if (t_b < 1/2) c.b = q;
            else if (t_b < 2/3) c.b = p+((q-p)*6*(2/3-t_b));
            else c.b = p;
            return c;
        }
        

        【讨论】:

          【解决方案8】:

          执行此操作的最简单方法是确保红色和蓝色分量相同,如下所示:(原谅我的 Python)

          rb = randint(100, 200)
          color = (rb, randint(120, 255), rb)
          

          【讨论】:

          • 应该允许红色和蓝色之间的细微差别。 - 查看 Moose 对 theomega 答案的评论。
          • Hmm... 这种方法可以生成G分量小于R和B分量的颜色,最极端的情况是(200, 120, 200)。这是一种略带紫色的颜色,甚至不是偏绿色。
          • @Danny:这对我来说听起来不合逻辑。在 RGB 术语中,我将“geenish”定义为 G 分量大于 R 和 B 分量的任何颜色。 R和B之间的差异有多大并不重要,只要G大于它们两者,颜色就会显示为绿色。 “绿色”的程度可以通过 G 比 R 和 B 大多少来参数化,但 R 和 B 之间的差异仍然没有起到任何重要作用。
          • 我试过了;他可能是对的。将以下代码粘贴到 LINQPad 中:var form = new Form(); var rand = new Random(); form.Click += delegate{ var green = rand.Next(128,255); var rb = rand.Next(100); form.BackColor=Color.FromArgb(rb,green,rb+rand.Next(-5,5)); }; form.ShowDialog();
          【解决方案9】:

          我会采用其他人提到的 HSV 方法。另一种方法是获取一张漂亮的高分辨率照片,其中包含一些绿色植物,裁剪掉非绿色部分,然后使用PIL从中挑选随机像素。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-01-05
            • 1970-01-01
            • 2012-06-13
            • 1970-01-01
            • 2017-05-28
            • 2017-09-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多