如何为rgb值生成接近的颜色?

时间:2017-08-05 15:12:05

标签: python colors

我希望能够生成接近一种RGB颜色的多种颜色,如下图所示。

enter image description here

以下是我使用Python制作的内容:

def similarColors(rgb, loop=6):
    difference = 30
    colors = []
    for i in range(loop):
        red = rgb[0]
        red_highest = red + difference
        red_lowest = red - difference
        red = randint(red_lowest, red_highest)

        green = rgb[1]
        green_highest = green + difference
        green_lowest = green - difference
        green = randint(green_lowest, green_highest)

        blue = rgb[2]
        blue_highest = blue + difference
        blue_lowest = blue - difference
        blue = randint(blue_lowest, blue_highest)

        colors.append([red, green, blue])
    return colors

palette = similarColors([244, 83, 28])

问题:我觉得我用这种方法过度复杂化是否有办法让上面的代码更清晰,更短?

我想避免分别对每种颜色(红色,蓝色,绿色)进行相同的处理,我也不确定这种方法对于我想要达到的目标是否非常精确。

3 个答案:

答案 0 :(得分:2)

我们可以通过循环遍历RGB组件来压缩该代码。但是,您当前的算法存在一个错误:它可以生成<&lt;颜色通道值。 0或&gt; 255,所以我们需要解决这个问题。

from random import randint

def similarColors(rgb, loop=6):
    colors = []
    delta = 30
    for i in range(loop):
        new_rgb = [randint(max(0, x - delta), min(x + delta, 255)) for x in rgb]  
        colors.append(new_rgb)                
    return colors

colors = similarColors([244, 83, 28])
print(colors)

典型输出

[[249, 75, 28], [226, 111, 34], [235, 85, 46], [228, 66, 28], [244, 62, 8], [233, 102, 21]]

你说:“我也不确定这种方法对于我想要达到的目标是否真的精确”。我不确切地知道你想要达到的目标,但我能看到的一个问题是人类视觉系统对R,G和&amp; B.因此,在一个频道中按给定金额的变化与另一个频道中的相同变化不会产生相同的效果。要正确处理这个问题,你需要在与人类视觉系统更紧密对齐的色彩空间中工作,例如Lab color space。但是,我们可以通过在通道增量上使用缩放因子来获得合理的近似值。

关于Grayscale的维基百科文章提供了一个可用于计算RGB颜色亮度的公式:

y = 0.299*R + 0.587*G + 0.114*B

该公式用于模拟NTSC&amp; PAL电视。

以上是使用这些缩放因子的上述代码的一个版本。我们将基数delta除以那些比例因子,因此蓝色增量是最大的&amp;绿色三角洲最小,因为眼睛对绿色最敏感,对蓝色最不敏感。

def similarColors(rgb, loop=6):
    colors = []
    delta = 10
    deltas = [round(delta / u) for u in (0.299, 0.587, 0.114)]
    for i in range(loop):
        new_rgb = [randint(max(0, x - delta), min(x + delta, 255)) 
            for x, delta in zip(rgb, deltas)]
        colors.append(new_rgb)
    return colors

colors = similarColors([244, 83, 28])
print(colors)

典型输出

[[236, 84, 65], [233, 74, 78], [226, 93, 73], [249, 88, 89], [240, 84, 40], [226, 75, 22]]

为了提高代码的效率,因为我们使用固定的基础delta,我们可以预先计算deltas数组,而不是每次调用{{1}时重新计算它}。

答案 1 :(得分:1)

无需复制粘贴每种颜色,您可以像这样使用for循环:

def similarColors(rgb, loop=6, difference=30):
    colors = []
    for _ in range(loop):
        color = []
        for curr_color in rgb:
            color.append(randint(curr_color - difference, curr_color + difference))
        colors.append(color)

    return colors

注意我还在参数中添加了difference

还有一个错误,其中rgb部分可以&lt; 0或&gt; 255,您可以使用max(0, min(255, randint(curr_color - difference, curr_color + difference)))来修复此问题。

答案 2 :(得分:1)

如果您可以使用numpy,那么更紧凑的解决方案就是:

import numpy as np

def similarColors(rgb, loop=6):
    delta = 30
    origClrs = np.tile(np.array(rgb), (loop, 1))
    randOffsets = np.random.randint(-delta, delta, size=(loop, 3))
    return origClrs + randomOffsets