跳转至

§5.2 颜色处理

字数 1079 个   代码 47 行   图片 2 张   阅读时间 4 分钟   访问量

一、处理函数

maliang 只支持两种颜色空间的处理,分别是 RGB 和 HSL,且对这两种颜色空间支持的相关处理函数都差不多。处理 RGB 的函数位于子包 color.rgb 中,处理 HSL 的函数为位于子包 color.hsl

1.1 获取相反色

以 RGB 颜色为例,这里说的相反色是指颜色某个指标的最大值减去当前值所得的结果,比如 (50, 100, 150) 的相反色就是 (255-50, 255-100, 255-150),即 (205, 155, 105),HSL 颜色同理。

要获取一个颜色的相反色,对于 RGB 颜色,可以使用函数 rgb.contrast,对于 HSL 颜色,可以使用函数 hsl.contrast。两者参数类似。

下面是一个简单的示例(运行结果为文档构建时计算得到):

1
2
3
4
5
import maliang.color.hsl
import maliang.color.rgb

print(maliang.color.rgb.contrast((50, 100, 150)))
print(maliang.color.hsl.contrast((1, 0.3, 0.6)))
(205, 155, 105)
(5.283185307179586, 0.7, 0.4)

1.2 过渡一个颜色

这里说的过渡一个颜色是指,将一个颜色以另外一个颜色为目标,以一定的比例向其靠拢得到的颜色。显然,当过渡比例为 100% 时,得到的返回值就是目标颜色,0% 时为原来的颜色。对于 RGB,过渡一个颜色要调用的函数为 rgb.transition,对于 HSL 是 hsl.transition

下面是一个简单的示例(运行结果为文档构建时计算得到):

1
2
3
4
5
import maliang.color.hsl
import maliang.color.rgb

print(maliang.color.rgb.transition((50, 100, 150), (0, 0, 0), 0.3))
print(maliang.color.hsl.transition((2, 0.3, 0.6), (0, 0, 0), 0.5))
(35, 70, 105)
(1.0, 0.15, 0.3)

1.3 混合多个颜色

混合颜色就是按权重(默认值表示等权重)分配三个颜色通道的值得到新的颜色。对于 RGB,混合颜色的函数为 rgb.blend,而 HSL 则是 hsl.blend

下面是一个简单的示例(运行结果为文档构建时计算得到):

import maliang.color.hsl
import maliang.color.rgb

# same weight
print(maliang.color.rgb.blend((50, 100, 150), (0, 0, 0), (100, 100, 100)))
print(maliang.color.hsl.blend((2, 0.3, 0.6), (0, 0, 0), (4, 0.4, 0.9)))

# diff weight
print(maliang.color.rgb.blend((50, 100, 150), (0, 0, 0), (100, 100, 100), weights=(1, 2, 3)))
print(maliang.color.hsl.blend((2, 0.3, 0.6), (0, 0, 0), (4, 0.4, 0.9), weights=(0.1, 0.3, 0.6)))
1
2
3
4
(50, 67, 83)
(2, 0.23333333333333334, 0.5)
(58, 67, 75)
(2.6, 0.27, 0.6000000000000001)

1.4 获取一组渐变色

其实可以通过设置一系列的值多次调用前面提到的函数 transition 就可以得到一组渐变色,但我并不推荐你使用这种方式获取渐变色,因为内部处理时由于循环可能会导致某些步骤被重复执行导致性能相对低下。对于 RGB 应该使用 rgb.gradient 来获取渐变色,而 HSL 则是 hsl.gradient

与上面的函数 transition 类似,函数 gradient 也有一个控制到目标颜色比例的参数 rate。这个参数的默认值是 1,表示渐变色的终点就是目标颜色,如果不是 1,那么就是以此参数的值用函数 transition 计算出的颜色作为渐变色的终点。不过,有趣的是,函数 gradient 有一个名为 contoller 的参数可以控制渐变色每次渐变的比例。它要传入的对象是前面第四章提到的控制函数,默认值是 controllers.linear,也就是线性的,等差的。但我们可以通过设置其它的控制函数得到其它的渐变效果。

该函数的返回值是一个列表,里面是一组 RGB 颜色或者 HSL 颜色,数量由参数 count 控制。返回的列表中一般不会包括目标颜色,除非目标颜色与初始颜色相近。

下面是一个简单的示例(运行结果为文档构建时计算得到):

1
2
3
4
5
6
7
import math

import maliang.color.hsl
import maliang.color.rgb

print(maliang.color.rgb.gradient((0, 0, 0), (100, 100, 100), 5))
print(maliang.color.hsl.gradient((0, 0, 0), (math.pi, 0.5, 0.5), 5))
[(0, 0, 0), (20, 20, 20), (40, 40, 40), (60, 60, 60), (80, 80, 80)]
[(0.0, 0.0, 0.0), (0.6283185307179586, 0.1, 0.1), (1.2566370614359172, 0.2, 0.2), (1.8849555921538759, 0.3, 0.3), (2.5132741228718345, 0.4, 0.4)]

特别注意:控制函数选取需谨慎

默认的控制函数用的是线性的,它的曲线最大值都不会超过 1,所以计算得到的颜色字符串永远都是有意义(除非你传入的初始参数就存在问题)。但有些控制函数,或者自定义的控制函数就可能产生一些问题,比如内置的控制函数 controllers.rebound 就可能会造成产生的颜色字符串无意义。因为这个控制函数的图像中有一部分是超出 1 的,见 第四章第二节图三

二、一些示例

下面给出一些示例以供参考。

2.1 渐变圆

这个示例简单使用了 RGB 和 HSL 的渐变色函数,代码如下:

import math

import maliang
import maliang.color
import maliang.color.hsl
import maliang.color.rgb

root = maliang.Tk()
canvas = maliang.Canvas()
canvas.place(width=1280, height=720)

for i, v in enumerate(maliang.color.rgb.gradient((0, 0, 0), (255, 255, 255), 360)):
    canvas.create_arc(100, 100, 500, 500, start=i, extent=1, fill=maliang.color.rgb_to_hex(v), outline="")

for i, v in enumerate(maliang.color.hsl.gradient((0, 0.5, 1), (math.tau, 0.5, 1), 360)):
    canvas.create_arc(100+600, 100, 500+600, 500, start=i, extent=1, fill=maliang.color.hsl_to_hex(v), outline="")

root.mainloop()

效果如下:

图1 渐变圆

2.2 呼吸灯效果

代码和效果就省略了,具体见 第四章第一节 2.6,现在想必你已经知道那个动画类是怎么实现的了吧?

猜你想问:为什么这里省略了代码和效果?

这个问题看起来十分复杂实际上非常复杂但简单来说就是因为我懒 :)
求求不要再催更我啦 :(