甚至从一个十六进制颜色增加到另一个十六进制颜色

时间:2018-04-15 12:48:01

标签: python colors

我的程序收到用户的两个号码,如下所示......

first_color = int(input("Input first color: "), 16)
second_color = int(input("Input second color: "), 16)
generate = int(input("Enter the number of colors I will make between the two input numbers"))

例如,如果用户输入0x030303,0x454545和3;应该有五个输出(全部以十六进制表示);两个输入数字和三个数字均匀分布在两个输入数字之间。

要明确我的计划在两个输入数字之间的数字;我将使用带有十进制数字的类似示例...

用户输入10,2和3。 程序输出2,4,6,8,10(原始的两个输入数字和三个数字均匀分布在两个输入数字之间)。

我在尝试生成均匀分布在两个输入数字之间的十六进制数字时遇到了很多麻烦。我不想导入任何东西来实现这一点。我想将较小的十六进制数(从用户)拆分为RGB组件,然后递增为连续的十六进制数。

2 个答案:

答案 0 :(得分:1)

如果你关心的是颜色,你不希望数字在输入之间均匀分布。您想要将颜色转换为坐标,找到它们之间均匀分布的,然后将它们转回字符串。

代码

# Do not convert input to integers yet
first_color = input("Input first color: ")
second_color = input("Input second color: ")
generate = int(input("Enter the number of colors: "))

def get_colors_from_input(color1, color2, n):
    # Extract color coordinates
    r1, g1, b1 = [int(x, 16)
                  for x in [color1[i:i+2] for i in range(2, 8, 2)]]
    r2, g2, b2 = [int(x, 16)
                  for x in [color2[i:i+2] for i in range(2, 8, 2)]]

    # Build the coordinate-wise distribution
    # We could have used `range`, but using floats prevents some rounding errors
    dec_cols = zip(
        [int(r1 + x * (r2 - r1) / (n + 1)) for x in range(n + 2)],
        [int(g1 + x * (g2 - g1) / (n + 1)) for x in range(n + 2)],
        [int(b1 + x * (b2 - b1) / (n + 1)) for x in range(n + 2)])

    # Format back the coordinates to strings.
    # We used a small hack with `str.replace` to make sure coordinates have two digits
    return ['0x' + ''.join(hex(x).replace('x', '')[-2:]
                             for x in color) for color in dec_cols]

print(*get_colors_from_input(first_color, second_color, generate))

实施例

Input first color: 0x000000
Input second color: 0xffffff
Enter the number of colors: 3
0x000000 0x3f3f3f 0x7e7e7e 0xbdbdbd 0xffffff

使用re

验证输入格式

您可能希望添加so guard子句以确保输入格式正确。尽管您希望在代码中不使用导入,但我建议您使用re模块。

import re

...

# Extract color coordinates
color_coords1 = re.fullmatch(r'0x([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})', color1)
color_coords2 = re.fullmatch(r'0x([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})', color2)

# If there is no match, some color was malformatted
if not color_coords1 or not color_coords2:
    raise ValueError('Wrong color format')

r1, g1, b1 = [int(x, 16) for x in color_coords1.groups()]
r2, g2, b2 = [int(x, 16) for x in color_coords2.groups()]

答案 1 :(得分:0)

this code应用于您的: https://pyfiddle.io/fiddle/2bda2f7c-7bf1-4fe2-86e0-9492546e5add/

def get_rgb(int_value):
    blue  = int_value & 255
    green = (int_value >> 8) & 255
    red   = (int_value >> 16) & 255
    return red, green, blue

def get_int(rgb):
    red = rgb[0]
    green = rgb[1]
    blue = rgb[2]
    int_value = (red<<16) + (green<<8) + blue
    return int_value

def get_step(first_rgb, rgb_steps, step):
    current_rgb = [
        int(first_rgb[c] + ((step+1) * rgb_steps[c]))
        for c in range(3)
    ]
    return get_int(current_rgb)

first_color = int(input("Input first color: "), 16)
second_color = int(input("Input second color: "), 16)
generate = int(input("Enter the number of colors I will make between the two input numbers"))

first_rgb = get_rgb(first_color)
second_rgb = get_rgb(second_color)

rgb_steps = [(second_rgb[i] - first_rgb[i]) / (generate + 1)
    for i in range(3)]

gradient_color_list = [first_color] \
    + list(map(
        lambda step: get_step(first_rgb, rgb_steps, step),
        range(generate)
    )) + [second_color]


print("\n".join([ hex(v) for v in gradient_color_list ]))

值为0x450031,0x9000ff,5,输出为:

0x450031
0x510053
0x5d0075
0x690097
0x7500b9
0x8100db
0x9000ff