首页 > 解决方案 > 如何生成远离值列表的随机值?

问题描述

我有以下透明图像。

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

我想要做的是将它们粘贴到具有特定颜色背景的图像上。背景的颜色是随机的,如下所示:

rand1, rand2, rand3 = (random.randint(0, 255),
                       random.randint(0, 255),
                       random.randint(0, 255))

background = Image.new('RGBA', png.size, (rand1, rand2, rand3))

alpha_composite = Image.alpha_composite(background, png)

不幸的是,有些标志的背景颜色并不好。背景颜色有时会接近徽标内部的颜色,这会使徽标部分或完全不可见。这是一个背景颜色与 Ubuntu 徽标中的橙色几乎相同的示例:

在此处输入图像描述

我所做的是从每个徽标中获取所有颜色并将它们保存在这样的元组列表中。这实际上是一个元组列表的列表。我现在刚刚对其进行了编辑,以突出显示哪个嵌套的元组列表属于哪个徽标:

Intel = [(0, 113, 197)]
Corsair = [(4, 7, 7)]
Google = [(66, 133, 244), (234, 67, 53), (251, 188, 5), (52, 168, 83), (0, 255, 255), (255, 128, 0), (255, 255, 0)]
Riot = [(209, 54, 57), (255, 255, 255), (226, 130, 132), (0, 0, 0)]

我想要做的是使用上面的 ^ 信息随机选择背景颜色,这样徽标的任何部分都不会不可见。我正在寻求有关解决此问题的策略的建议..

这是为徽标添加背景颜色的函数:

def logo_background(path):

    rand1, rand2, rand3 = (random.randint(0, 255),
                           random.randint(0, 255),
                           random.randint(0, 255))

    png = Image.open(path).convert('RGBA')
    colors = extcolors.extract_from_path(path)

    background = Image.new('RGBA', png.size, (rand1, rand2, rand3))

    alpha_composite = Image.alpha_composite(background, png)


    return alpha_composite
>>> extcolors.extract_from_path(path)
[((0, 113, 197), 25727), 56235]

# for the intel logo, which is just blue with transparent background

有些标志是全黑的。海盗船标志是一个透明背景的全黑标志,但代码没有选择正确的背景。

在此处输入图像描述

标签: pythonrandompython-imaging-libraryextcolors

解决方案


我认为使用像 rgb 这样的 thre component vektor 很难随机选择。我会先将其转换为 hsv 颜色系统(色调、饱和度、亮度)。然后我们只需要担心色调并且可以使用random.choice从可能值的一维列表中选择一个值。

Google = [(66, 133, 244), (234, 67, 53), (251, 188, 5), (52, 168, 83), (0, 255, 255), (255, 128, 0), (255, 255, 0)]
threshold = 0.1 #No hue value closer than threshold to a logo-color 

# convert to hsv
GoogleHsv = [colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0) for r,g,b in Google] 
print("GoogleHsv:", GoogleHsv)

# list of possible hue-values that are at least threshold away from all logo-hue-values
choices = [x for x in np.linspace(0,1,201) if min([abs(x-h) for h,l,s in GoogleHsv]) > threshold] 
print("choices:", choices)

h = random.choice(choices)
l = random.random() # random lightness 
s = random.random() # random saturation
# you could also use constants for l,s to alway get a vibrant/dark color.

color = [int(x*255) for x in colorsys.hsv_to_rgb(h, l, s)] # converting back to rbg
print("color:", color)

希望这可以帮助。祝你今天过得愉快。


编辑

对于您的功能,它看起来像这样:

def logo_background(path):
    
    threshold = 0.1        
    png = Image.open(path).convert('RGBA')
    used_colors_rgb = extcolors.extract_from_path(path)[0]

    used_hsv = [colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0) for (r,g,b), _ in used_colors_rgb] 
    choices = [x for x in np.linspace(0,1,201) if min([abs(x-h) for h,l,s in used_hsv]) > threshold] 
    h, l, s = random.choice(choices), (random.random()+1) / 2, (random.random()+1) / 2    
    color = [int(x*255) for x in colorsys.hsv_to_rgb(h, l, s)]
  
    background = Image.new('RGBA', png.size,tuple(color))
    alpha_composite = Image.alpha_composite(background, png)
    return alpha_composite
    
logo_background("google.png")

推荐阅读