代码之家  ›  专栏  ›  技术社区  ›  Echo says Reinstate Monica

如何生成随机的“绿色”颜色

  •  33
  • Echo says Reinstate Monica  · 技术社区  · 15 年前

    有人对如何使所有的随机颜色都是绿色有什么建议吗?现在,我通过以下方式生成颜色:

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

    这基本上是可行的,但我有很多褐色的颜色。

    9 回复  |  直到 11 年前
        1
  •  54
  •   theomega    15 年前

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

        2
  •  21
  •   dbr    11 年前

    正如其他人所说,在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()
    

    输出(在Web浏览器中查看时)应沿以下行显示:

    Example output, showing random green colours

    编辑 :我不知道colorsys模块。而不是上面的 hsv_to_rgb 函数,可以使用 colorsys.hsv_to_rgb ,这使得代码更短(这不是一个很小的替换,因为我的 HVSI 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
  •  16
  •   Anthony Mills    15 年前

    退房 colorsys 模块:

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

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

        4
  •  9
  •   Matt Bayliss    15 年前

    如果你坚持使用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
  •  5
  •   DigitalRoss    15 年前

    所以,在这种情况下,你很幸运地想要原色的变化,但是对于这样的艺术用途,最好是指定色轮坐标,而不是原色的大小。

    你可能想从 colorsys 模块类型:

    colorsys.hsv_to_rgb(h, s, v)
        Convert the color from HSV coordinates to RGB coordinates.
    
        6
  •  3
  •   AnT stands with Russia    15 年前

    HSX颜色空间的解决方案非常好。但是,如果您需要一些非常简单的东西,并且对颜色的分布没有特定的要求(例如一致性),那么基于RGB的简单解决方案将只是确保g值大于r和b值。

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

    这会给你“绿色”的颜色。他们中的一些人将永远是如此的微绿。你可以通过增加(绝对或相对)最后一个下限来提高绿色的保证程度。 randint 打电话。

        7
  •  1
  •   putgeminmouth    15 年前

    你想做的是 HSL 而不是RGB。你可以找到一个满足“绿色”的色调范围,然后从中选择一个随机的色调。你也可以选择随机的饱和度和亮度,但你可能想让饱和度保持在1附近,亮度保持在0.5左右,但是你可以使用它们。

    下面是一些将hsl转换为rgb的actionscript代码。我有一段时间没有接触过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
  •  0
  •   SLaks    15 年前

    最简单的方法是确保红色和蓝色组件是相同的,就像这样:(请原谅我的python)

    rb = randint(100, 200)
    color = (rb, randint(120, 255), rb)
    
        9
  •  0
  •   Dickon Reed    15 年前

    我会采用其他人提到的HSV方法。另一种方法是得到一张高分辨率的照片,照片中有一些绿色植物,裁剪出非绿色部分,然后使用 PIL .