如何用代码检测调色板是否符合色轮配色方案,求Python实现思路
配色方案校验系统Python实现思路
1. 先统一颜色的数值表达
所有和色轮相关的计算都优先用HSV色彩空间处理,色轮的角度完全对应HSV里的Hue(色相)值,0-360度刚好覆盖完整色轮,比RGB计算逻辑简单很多:
- 用Python标准库
colorsys即可实现RGB和HSV的互相转换,不需要额外安装第三方依赖 - 新增一个hex格式转RGB的工具函数,支持直接输入常用的十六进制颜色值
- 提前过滤无效色相:饱和度低于阈值的黑白灰类无彩色单独处理,这类颜色不参与色相匹配计算,仅作为亮度/饱和度变体存在
2. 明确各类配色的判定规则
先给所有配色方案设置可调整的公差阈值(一般默认±15度即可,实际使用的配色很少完全卡准理论值),再逐个拆解匹配逻辑:
- 单色(monochromatic):所有有效颜色的色相值都在公差范围内,仅存在饱和度、亮度的差异
- 邻近色(analogous):所有有效颜色的色相都落在色轮上连续的30-90度区间内,常规默认取60度范围
- 互补色(complementary):有效色相去重后仅存2个,两个色相的环形差值在180度±公差范围内
- 分裂互补(split complementary):有效色相去重后共3个,其中一个色相的180度互补位±30度范围内存在另外两个色相,三个色相的环形差值约为150/150/60度
- 三角色(triadic):有效色相去重后共3个,两两之间的环形差值在120度±公差范围内,均匀分布在色轮上
- 四方色(square):有效色相去重后共4个,两两之间的环形差值在90度±公差范围内,均匀分布在色轮上
- 矩形/四元色(tetradic):有效色相去重后共4个,刚好由两组互补色组成,两组互补色的色相差值在60-120度之间
3. 核心逻辑实现要点
- 先实现环形差值计算:处理360度色轮的溢出问题,比如350度和10度的实际差值是20度不是340度
- 对输入调色板的色相值先去重、排序,再和对应配色的规则做匹配,还可以额外计算匹配度得分,误差越小得分越高
- 把公差阈值做成可配置参数,支持不同场景的严格度调整
4. 基础示例代码片段
import colorsys def hex_to_rgb(hex_color: str) -> tuple[float, float, float]: """十六进制颜色转0-1范围的RGB值""" hex_color = hex_color.lstrip("#") return tuple(int(hex_color[i:i+2], 16)/255.0 for i in (0, 2, 4)) def get_valid_hue(hex_color: str, sat_threshold: float = 0.05) -> float | None: """获取颜色的有效色相,饱和度低于阈值的无彩色返回None""" r, g, b = hex_to_rgb(hex_color) h, s, v = colorsys.rgb_to_hsv(r, g, b) return h * 360 if s > sat_threshold else None def hue_circle_diff(h1: float, h2: float) -> float: """计算两个色相的环形最小差值""" diff = abs(h1 - h2) return min(diff, 360 - diff) def is_complementary(palette: list[str], tolerance: int = 15) -> bool: """校验调色板是否符合互补色方案""" hues = [h for h in [get_valid_hue(c) for c in palette] if h is not None] unique_hues = list(set(round(h) for h in hues)) if len(unique_hues) != 2: return False return 180 - tolerance <= hue_circle_diff(unique_hues[0], unique_hues[1]) <= 180 + tolerance
内容的提问来源于stack exchange,提问作者Baggins
相关产品推荐
相关产品推荐

